Skip to content

Commit b838894

Browse files
committed
feat(core): introduce IWDG driver
[no changelog]
1 parent ff2d4ed commit b838894

File tree

6 files changed

+105
-4
lines changed

6 files changed

+105
-4
lines changed

core/SConscript.bootloader

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ FEATURES_WANTED = [
2424
"secure_domain",
2525
"tropic",
2626
"usb",
27+
"iwdg",
2728
]
2829

2930
if TREZOR_MODEL in ('T3W1', ):

core/embed/sec/iwdg/inc/sec/iwdg.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* This file is part of the Trezor project, https://trezor.io/
3+
*
4+
* Copyright (c) SatoshiLabs
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#pragma once
21+
22+
#include <trezor_types.h>
23+
24+
#define IWDG_MAX_TIME (60 * 60 * 4) // 4 hours
25+
26+
/**
27+
* @brief Start the Independent Watchdog, to enforce reset after specified time
28+
* elapsed.
29+
*
30+
* The IWDG is clocked from LSI, which is expected to be set to 250 Hz.
31+
* The IWDG prescaler is set to 1024, which means that the watchdog
32+
* will tick every 4.096 s. The time is floored to the nearest multiple of 4.096
33+
* s.
34+
*
35+
* @param time_s Watchdog timeout in seconds. Time is ceiled to IWDG_MAX_TIME.
36+
*/
37+
void iwdg_start(uint32_t time_s);

core/embed/sec/iwdg/stm32/iwdg.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* This file is part of the Trezor project, https://trezor.io/
3+
*
4+
* Copyright (c) SatoshiLabs
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
#ifdef SECURE_MODE
20+
21+
#include <trezor_bsp.h>
22+
#include <trezor_rtl.h>
23+
24+
#include <sec/iwdg.h>
25+
26+
_Static_assert(LSI_VALUE == 250, "LSI_VALUE must be defined to 250 Hz");
27+
28+
void iwdg_start(uint32_t time_s) {
29+
if (time_s > IWDG_MAX_TIME) {
30+
// Limit the maximum watchdog timeout to 4 hours
31+
time_s = IWDG_MAX_TIME;
32+
}
33+
34+
// Set the reload value based on the desired time in seconds
35+
uint32_t reload_value = ((time_s * LSI_VALUE) / 1024) - 1;
36+
37+
IWDG_HandleTypeDef hiwdg = {0};
38+
39+
hiwdg.Instance = IWDG;
40+
hiwdg.Init.Prescaler = IWDG_PRESCALER_1024;
41+
hiwdg.Init.Reload = reload_value;
42+
hiwdg.Init.Window = 0xFFF;
43+
hiwdg.Init.EWI = 0;
44+
45+
// Configure the IWDG
46+
HAL_IWDG_Init(&hiwdg);
47+
}
48+
49+
#endif

core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extern "C" {
6060
#define HAL_HASH_MODULE_ENABLED
6161
/*#define HAL_HRTIM_MODULE_ENABLED */
6262
/*#define HAL_IRDA_MODULE_ENABLED */
63-
/*#define HAL_IWDG_MODULE_ENABLED */
63+
#define HAL_IWDG_MODULE_ENABLED
6464
#define HAL_I2C_MODULE_ENABLED
6565
/*#define HAL_I2S_MODULE_ENABLED */
6666
#define HAL_LPTIM_MODULE_ENABLED

core/embed/sys/startup/stm32u5/startup_init.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,15 @@ void lsi_init(void) {
9191

9292
uint32_t bdcr_temp = RCC->BDCR;
9393

94-
if (RCC_LSI_DIV1 != (bdcr_temp & RCC_BDCR_LSIPREDIV)) {
94+
#if LSI_VALUE == 32000
95+
uint32_t lsi_div = RCC_LSI_DIV1;
96+
#elif LSI_VALUE == 250
97+
uint32_t lsi_div = RCC_LSI_DIV128;
98+
#else
99+
#error Unsupported LSI frequency
100+
#endif
101+
102+
if (lsi_div != (bdcr_temp & RCC_BDCR_LSIPREDIV)) {
95103
if (((bdcr_temp & RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) &&
96104
((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION)) {
97105
// If LSIRDY is set while LSION is not enabled, LSIPREDIV can't be updated
@@ -110,7 +118,7 @@ void lsi_init(void) {
110118
}
111119

112120
// Set LSI division factor
113-
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, 0);
121+
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, lsi_div);
114122
}
115123

116124
// Enable the Internal Low Speed oscillator (LSI)
@@ -254,7 +262,9 @@ void SystemInit(void) {
254262

255263
#ifdef USE_LSE
256264
lse_init();
257-
#else
265+
#endif
266+
267+
#if defined(USE_LSI) || !defined(USE_LSE)
258268
lsi_init();
259269
#endif
260270

core/embed/sys/trustzone/stm32u5/trustzone.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@ void tz_init(void) {
517517
HAL_GTZC_TZSC_ConfigPeriphAttributes(
518518
GTZC_PERIPH_SAES, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
519519

520+
// Set IWDG as secure & privileged
521+
HAL_GTZC_TZSC_ConfigPeriphAttributes(
522+
GTZC_PERIPH_IWDG, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
523+
520524
// Set all interrupts as non-secure
521525
for (int i = 0; i < 512; i++) {
522526
NVIC_SetTargetState(i);

0 commit comments

Comments
 (0)