mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-02 20:08:31 +00:00
feat(core): introduce IWDG driver
[no changelog]
This commit is contained in:
parent
ff2d4edaef
commit
b83889457b
@ -24,6 +24,7 @@ FEATURES_WANTED = [
|
|||||||
"secure_domain",
|
"secure_domain",
|
||||||
"tropic",
|
"tropic",
|
||||||
"usb",
|
"usb",
|
||||||
|
"iwdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
if TREZOR_MODEL in ('T3W1', ):
|
if TREZOR_MODEL in ('T3W1', ):
|
||||||
|
37
core/embed/sec/iwdg/inc/sec/iwdg.h
Normal file
37
core/embed/sec/iwdg/inc/sec/iwdg.h
Normal 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);
|
49
core/embed/sec/iwdg/stm32/iwdg.c
Normal file
49
core/embed/sec/iwdg/stm32/iwdg.c
Normal 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
|
@ -60,7 +60,7 @@ extern "C" {
|
|||||||
#define HAL_HASH_MODULE_ENABLED
|
#define HAL_HASH_MODULE_ENABLED
|
||||||
/*#define HAL_HRTIM_MODULE_ENABLED */
|
/*#define HAL_HRTIM_MODULE_ENABLED */
|
||||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
#define HAL_IWDG_MODULE_ENABLED
|
||||||
#define HAL_I2C_MODULE_ENABLED
|
#define HAL_I2C_MODULE_ENABLED
|
||||||
/*#define HAL_I2S_MODULE_ENABLED */
|
/*#define HAL_I2S_MODULE_ENABLED */
|
||||||
#define HAL_LPTIM_MODULE_ENABLED
|
#define HAL_LPTIM_MODULE_ENABLED
|
||||||
|
@ -91,7 +91,15 @@ void lsi_init(void) {
|
|||||||
|
|
||||||
uint32_t bdcr_temp = RCC->BDCR;
|
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) &&
|
if (((bdcr_temp & RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) &&
|
||||||
((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION)) {
|
((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION)) {
|
||||||
// If LSIRDY is set while LSION is not enabled, LSIPREDIV can't be updated
|
// 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
|
// 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)
|
// Enable the Internal Low Speed oscillator (LSI)
|
||||||
@ -254,7 +262,9 @@ void SystemInit(void) {
|
|||||||
|
|
||||||
#ifdef USE_LSE
|
#ifdef USE_LSE
|
||||||
lse_init();
|
lse_init();
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_LSI) || !defined(USE_LSE)
|
||||||
lsi_init();
|
lsi_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -517,6 +517,10 @@ void tz_init(void) {
|
|||||||
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
HAL_GTZC_TZSC_ConfigPeriphAttributes(
|
||||||
GTZC_PERIPH_SAES, GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV);
|
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
|
// Set all interrupts as non-secure
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
NVIC_SetTargetState(i);
|
NVIC_SetTargetState(i);
|
||||||
|
Loading…
Reference in New Issue
Block a user