1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-08-02 11:58:32 +00:00

feat(core): introduce IWDG driver

[no changelog]
This commit is contained in:
tychovrahe 2025-06-06 15:23:06 +02:00 committed by TychoVrahe
parent ff2d4edaef
commit b83889457b
6 changed files with 105 additions and 4 deletions

View File

@ -24,6 +24,7 @@ FEATURES_WANTED = [
"secure_domain",
"tropic",
"usb",
"iwdg",
]
if TREZOR_MODEL in ('T3W1', ):

View File

@ -0,0 +1,37 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <trezor_types.h>
#define IWDG_MAX_TIME (60 * 60 * 4) // 4 hours
/**
* @brief Start the Independent Watchdog, to enforce reset after specified time
* elapsed.
*
* The IWDG is clocked from LSI, which is expected to be set to 250 Hz.
* The IWDG prescaler is set to 1024, which means that the watchdog
* will tick every 4.096 s. The time is floored to the nearest multiple of 4.096
* s.
*
* @param time_s Watchdog timeout in seconds. Time is ceiled to IWDG_MAX_TIME.
*/
void iwdg_start(uint32_t time_s);

View File

@ -0,0 +1,49 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SECURE_MODE
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include <sec/iwdg.h>
_Static_assert(LSI_VALUE == 250, "LSI_VALUE must be defined to 250 Hz");
void iwdg_start(uint32_t time_s) {
if (time_s > IWDG_MAX_TIME) {
// Limit the maximum watchdog timeout to 4 hours
time_s = IWDG_MAX_TIME;
}
// Set the reload value based on the desired time in seconds
uint32_t reload_value = ((time_s * LSI_VALUE) / 1024) - 1;
IWDG_HandleTypeDef hiwdg = {0};
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_1024;
hiwdg.Init.Reload = reload_value;
hiwdg.Init.Window = 0xFFF;
hiwdg.Init.EWI = 0;
// Configure the IWDG
HAL_IWDG_Init(&hiwdg);
}
#endif

View File

@ -60,7 +60,7 @@ extern "C" {
#define HAL_HASH_MODULE_ENABLED
/*#define HAL_HRTIM_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
#define HAL_IWDG_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
/*#define HAL_I2S_MODULE_ENABLED */
#define HAL_LPTIM_MODULE_ENABLED

View File

@ -91,7 +91,15 @@ void lsi_init(void) {
uint32_t bdcr_temp = RCC->BDCR;
if (RCC_LSI_DIV1 != (bdcr_temp & RCC_BDCR_LSIPREDIV)) {
#if LSI_VALUE == 32000
uint32_t lsi_div = RCC_LSI_DIV1;
#elif LSI_VALUE == 250
uint32_t lsi_div = RCC_LSI_DIV128;
#else
#error Unsupported LSI frequency
#endif
if (lsi_div != (bdcr_temp & RCC_BDCR_LSIPREDIV)) {
if (((bdcr_temp & RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) &&
((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION)) {
// If LSIRDY is set while LSION is not enabled, LSIPREDIV can't be updated
@ -110,7 +118,7 @@ void lsi_init(void) {
}
// Set LSI division factor
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, 0);
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, lsi_div);
}
// Enable the Internal Low Speed oscillator (LSI)
@ -254,7 +262,9 @@ void SystemInit(void) {
#ifdef USE_LSE
lse_init();
#else
#endif
#if defined(USE_LSI) || !defined(USE_LSE)
lsi_init();
#endif

View File

@ -517,6 +517,10 @@ void tz_init(void) {
HAL_GTZC_TZSC_ConfigPeriphAttributes(
GTZC_PERIPH_SAES, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
// Set IWDG as secure & privileged
HAL_GTZC_TZSC_ConfigPeriphAttributes(
GTZC_PERIPH_IWDG, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
// Set all interrupts as non-secure
for (int i = 0; i < 512; i++) {
NVIC_SetTargetState(i);