diff --git a/core/embed/models/T3W1/memory.ld b/core/embed/models/T3W1/memory.ld index a5c9e5170c..98b0bff897 100644 --- a/core/embed/models/T3W1/memory.ld +++ b/core/embed/models/T3W1/memory.ld @@ -49,6 +49,8 @@ SAES_RAM_START = 0x300cfe00; SAES_RAM_SIZE = 0x200; FB2_RAM_START = 0x300d0000; FB2_RAM_SIZE = 0xc0000; +BACKUP_RAM_START = 0x50036400; +BACKUP_RAM_SIZE = 0x800; AUX1_RAM_START = 0x30190000; AUX1_RAM_SIZE = 0xe0000; CODE_ALIGNMENT = 0x400; diff --git a/core/embed/models/T3W1/model_T3W1.h b/core/embed/models/T3W1/model_T3W1.h index 83bf16f7a6..e0fdc1a852 100644 --- a/core/embed/models/T3W1/model_T3W1.h +++ b/core/embed/models/T3W1/model_T3W1.h @@ -101,6 +101,9 @@ #define AUX1_RAM_START 0x30190000 #define AUX1_RAM_SIZE (896 * 1024) +#define BACKUP_RAM_START 0x50036400 +#define BACKUP_RAM_SIZE 2048 + // misc #define CODE_ALIGNMENT 0x400 #define COREAPP_ALIGNMENT 0x2000 diff --git a/core/embed/sys/backup_ram/backup_ram.c b/core/embed/sys/backup_ram/backup_ram.c new file mode 100644 index 0000000000..9b976ec41c --- /dev/null +++ b/core/embed/sys/backup_ram/backup_ram.c @@ -0,0 +1,110 @@ +/* + * 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 . + */ + +// #include +#include +#include + +#include + +// Place backup RAM data structure in the linker backup SRAM section +__attribute__((section(".backup_ram"))) backup_ram_data_t backup_ram; + +typedef struct { + bool initialized; + RAMCFG_HandleTypeDef hramcfg; +} backup_ram_driver_t; + +static backup_ram_driver_t backup_ram_driver = { + .initialized = false, +}; + +backup_ram_status_t backup_ram_init(void) { + backup_ram_driver_t *drv = &backup_ram_driver; + + if (drv->initialized) { + return BACKUP_RAM_OK; + } + + // Enable backup SRAM clock + __HAL_RCC_RAMCFG_FORCE_RESET(); + __HAL_RCC_RAMCFG_RELEASE_RESET(); + __HAL_RCC_RAMCFG_CLK_ENABLE(); + __HAL_RCC_BKPSRAM_CLK_ENABLE(); + + memset((void *)drv, 0, sizeof(backup_ram_driver_t)); + drv->hramcfg.Instance = RAMCFG_BKPRAM; + HAL_StatusTypeDef status = HAL_RAMCFG_Init(&drv->hramcfg); + + if (status != HAL_OK) { + __HAL_RCC_BKPSRAM_CLK_DISABLE(); + return BACKUP_RAM_ERROR; + } + + drv->initialized = true; + + return BACKUP_RAM_OK; +} + +backup_ram_status_t backup_ram_deinit(void) { + backup_ram_driver_t *drv = &backup_ram_driver; + + HAL_RAMCFG_DeInit(&drv->hramcfg); + + // Disable backup SRAM clock + __HAL_RCC_BKPSRAM_CLK_DISABLE(); + __HAL_RCC_RAMCFG_CLK_DISABLE(); + backup_ram_driver.initialized = false; + + return BACKUP_RAM_OK; +} + +backup_ram_status_t backup_ram_erase(void) { + backup_ram_driver_t *drv = &backup_ram_driver; + + HAL_StatusTypeDef status = HAL_RAMCFG_Erase(&drv->hramcfg); + if (status != HAL_OK) { + return BACKUP_RAM_ERROR; + } + + return BACKUP_RAM_OK; +} + +backup_ram_status_t backup_ram_erase_unused(void) { + memset(backup_ram.bytes + sizeof(backup_ram.data), 0, + sizeof(backup_ram.bytes) - sizeof(backup_ram.data)); + + return BACKUP_RAM_OK; +} + +backup_ram_status_t backup_ram_store_fuel_gauge_state( + const fuel_gauge_backup_storage_t *fg_state) { + memcpy((void *)&backup_ram.data.fg, fg_state, + sizeof(fuel_gauge_backup_storage_t)); + + return BACKUP_RAM_OK; +} + +backup_ram_status_t backup_ram_read_fuel_gauge_state( + fuel_gauge_backup_storage_t *fg_state) { + memcpy(fg_state, (const void *)&backup_ram.data.fg, + sizeof(fuel_gauge_backup_storage_t)); + + return BACKUP_RAM_OK; +} diff --git a/core/embed/sys/backup_ram/inc/sys/backup_ram.h b/core/embed/sys/backup_ram/inc/sys/backup_ram.h new file mode 100644 index 0000000000..772fd76c5a --- /dev/null +++ b/core/embed/sys/backup_ram/inc/sys/backup_ram.h @@ -0,0 +1,65 @@ +/* + * 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 . + */ + +#pragma once + +#include +#include + +typedef enum { + BACKUP_RAM_OK = 0, + BACKUP_RAM_ERROR, +} backup_ram_status_t; + +// Fuel gauge backup storage definition +typedef struct { + float soc; // Captured state of charge <0, 1> + // Captures RTC time at which SOC was captured + uint32_t last_capture_timestamp; +} fuel_gauge_backup_storage_t; + +typedef union { + uint8_t bytes[BACKUP_RAM_SIZE]; + struct { + volatile fuel_gauge_backup_storage_t fg; + // < Room for other data structures > + } data; +} backup_ram_data_t; + +// Initialize backup RAM driver +backup_ram_status_t backup_ram_init(void); + +// Deinitialize backup RAM driver +backup_ram_status_t backup_ram_deinit(void); + +// Erase backup ram +backup_ram_status_t backup_ram_erase(void); + +// Erase unused space in backup ram +// This function clears the remaining part of the backup ram not alocated by +// data struct. +backup_ram_status_t backup_ram_erase_unused(void); + +// Store fuel gauge state in backup ram +backup_ram_status_t backup_ram_store_fuel_gauge_state( + const fuel_gauge_backup_storage_t* fg_state); + +// Read fuel gauge state from backup ram +backup_ram_status_t backup_ram_read_fuel_gauge_state( + fuel_gauge_backup_storage_t* fg_state); diff --git a/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h b/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h index 0b489baf77..f213c6446e 100644 --- a/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h +++ b/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h @@ -84,7 +84,7 @@ extern "C" { #define HAL_SRAM_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED /*#define HAL_TSC_MODULE_ENABLED */ -/*#define HAL_RAMCFG_MODULE_ENABLED */ +#define HAL_RAMCFG_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ diff --git a/core/embed/sys/linker/stm32u5g/prodtest.ld b/core/embed/sys/linker/stm32u5g/prodtest.ld index efc2f4ab56..4eba5c45be 100644 --- a/core/embed/sys/linker/stm32u5g/prodtest.ld +++ b/core/embed/sys/linker/stm32u5g/prodtest.ld @@ -11,6 +11,7 @@ MEMORY { SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE + BACKUP_RAM (wal) : ORIGIN = BACKUP_RAM_START, LENGTH = BACKUP_RAM_SIZE } _stack_section_start = ADDR(.stack); @@ -35,6 +36,9 @@ _accessible_ram_1_end = MCU_SRAM4 + MCU_SRAM4_SIZE; _bootargs_ram_start = BOOTARGS_START; _bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE; +_backup_ram_start = ORIGIN(BACKUP_RAM); +_backup_ram_end = ORIGIN(BACKUP_RAM) + LENGTH(BACKUP_RAM); + _codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential); _flash_start = ORIGIN(FLASH); @@ -113,6 +117,11 @@ SECTIONS { . = ALIGN(4); } >AUX1_RAM + .backup_ram (NOLOAD) : { + . = ALIGN(4); + *(.backup_ram) + . = ALIGN(4); + } > BACKUP_RAM .boot_args : ALIGN(8) { *(.boot_command*); diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py index 32f18f1c71..558e5b4170 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py @@ -77,6 +77,10 @@ def configure( paths += ["embed/io/i2c_bus/inc"] defines += [("USE_I2C", "1")] + sources += ["embed/sys/backup_ram/backup_ram.c"] + paths += ["embed/sys/backup_ram/inc"] + defines += [("USE_BACKUP_RAM", "1")] + if "haptic" in features_wanted: sources += [ "embed/io/haptic/drv2625/drv2625.c", diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py index 020576c3f4..8650ae8c82 100644 --- a/core/site_scons/models/stm32u5_common.py +++ b/core/site_scons/models/stm32u5_common.py @@ -68,6 +68,7 @@ def stm32u5_common_files(env, defines, sources, paths): "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pcd_ex.c", "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pwr.c", "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pwr_ex.c", + "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_ramcfg.c", "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rcc.c", "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rcc_ex.c", "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rtc.c",