1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-02 19:40:57 +00:00

fix(core): add delays to optiga i2c communications

[no changelog]
This commit is contained in:
tychovrahe 2023-09-21 16:11:53 +02:00 committed by TychoVrahe
parent 36e4a444bb
commit 510281590f
6 changed files with 44 additions and 1 deletions

View File

@ -300,6 +300,9 @@ void SVC_C_Handler(uint32_t *stack) {
// raising privileges. // raising privileges.
stack[6] = (uintptr_t)reboot_to_bootloader; stack[6] = (uintptr_t)reboot_to_bootloader;
return; return;
case SVC_GET_SYSTICK_VAL: {
systick_val_copy = SysTick->VAL;
} break;
default: default:
stack[0] = 0xffffffff; stack[0] = 0xffffffff;
break; break;

View File

@ -76,6 +76,7 @@ void show_pin_too_many_screen(void);
void hal_delay(uint32_t ms); void hal_delay(uint32_t ms);
uint32_t hal_ticks_ms(); uint32_t hal_ticks_ms();
void hal_delay_us(uint16_t delay_us);
void collect_hw_entropy(void); void collect_hw_entropy(void);
#define HW_ENTROPY_LEN (12 + 32) #define HW_ENTROPY_LEN (12 + 32)

View File

@ -175,8 +175,10 @@ static optiga_result optiga_i2c_write(const uint8_t *data, uint16_t data_size) {
} }
if (HAL_OK == i2c_transmit(OPTIGA_I2C_INSTANCE, OPTIGA_ADDRESS, if (HAL_OK == i2c_transmit(OPTIGA_I2C_INSTANCE, OPTIGA_ADDRESS,
(uint8_t *)data, data_size, I2C_TIMEOUT)) { (uint8_t *)data, data_size, I2C_TIMEOUT)) {
hal_delay_us(1000);
return OPTIGA_SUCCESS; return OPTIGA_SUCCESS;
} }
hal_delay_us(1000);
} }
return OPTIGA_ERR_I2C_WRITE; return OPTIGA_ERR_I2C_WRITE;
} }

View File

@ -46,6 +46,8 @@
#define COLOR_FATAL_ERROR COLOR_BLACK #define COLOR_FATAL_ERROR COLOR_BLACK
#endif #endif
uint32_t systick_val_copy = 0;
// from util.s // from util.s
extern void shutdown_privileged(void); extern void shutdown_privileged(void);
@ -154,6 +156,17 @@ void __assert_func(const char *file, int line, const char *func,
void hal_delay(uint32_t ms) { HAL_Delay(ms); } void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); } uint32_t hal_ticks_ms() { return HAL_GetTick(); }
void hal_delay_us(uint16_t delay_us) {
uint32_t val = svc_get_systick_val();
uint32_t t = hal_ticks_ms() * 1000 +
(((SystemCoreClock / 1000) - val) / (SystemCoreClock / 1000000));
uint32_t t2 = t;
do {
val = svc_get_systick_val();
t2 = hal_ticks_ms() * 1000 +
(((SystemCoreClock / 1000) - val) / (SystemCoreClock / 1000000));
} while ((t2 - t) < delay_us);
}
// reference RM0090 section 35.12.1 Figure 413 // reference RM0090 section 35.12.1 Figure 413
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U) #define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)

View File

@ -171,9 +171,19 @@ HAL_StatusTypeDef i2c_transmit(uint16_t idx, uint8_t addr, uint8_t *data,
uint16_t len, uint32_t timeout) { uint16_t len, uint32_t timeout) {
return HAL_I2C_Master_Transmit(&i2c_handle[idx], addr, data, len, timeout); return HAL_I2C_Master_Transmit(&i2c_handle[idx], addr, data, len, timeout);
} }
HAL_StatusTypeDef i2c_receive(uint16_t idx, uint8_t addr, uint8_t *data, HAL_StatusTypeDef i2c_receive(uint16_t idx, uint8_t addr, uint8_t *data,
uint16_t len, uint32_t timeout) { uint16_t len, uint32_t timeout) {
return HAL_I2C_Master_Receive(&i2c_handle[idx], addr, data, len, timeout); HAL_StatusTypeDef ret =
HAL_I2C_Master_Receive(&i2c_handle[idx], addr, data, len, timeout);
#ifdef USE_OPTIGA
if (idx == OPTIGA_I2C_INSTANCE) {
// apply GUARD_TIME as specified by the OPTIGA datasheet
// (only applies to the I2C bus to which the OPTIGA is connected)
hal_delay_us(50);
}
#endif
return ret;
} }
HAL_StatusTypeDef i2c_mem_write(uint16_t idx, uint8_t addr, uint16_t mem_addr, HAL_StatusTypeDef i2c_mem_write(uint16_t idx, uint8_t addr, uint16_t mem_addr,

View File

@ -6,11 +6,15 @@
#define SVC_SHUTDOWN 4 #define SVC_SHUTDOWN 4
#define SVC_REBOOT_TO_BOOTLOADER 5 #define SVC_REBOOT_TO_BOOTLOADER 5
#define SVC_REBOOT_COPY_IMAGE_HEADER 6 #define SVC_REBOOT_COPY_IMAGE_HEADER 6
#define SVC_GET_SYSTICK_VAL 7
#include <string.h> #include <string.h>
#include "common.h" #include "common.h"
#include "image.h" #include "image.h"
// from common.c
extern uint32_t systick_val_copy;
// from util.s // from util.s
extern void shutdown_privileged(void); extern void shutdown_privileged(void);
extern void reboot_to_bootloader(void); extern void reboot_to_bootloader(void);
@ -87,3 +91,13 @@ static inline void svc_reboot_copy_image_header(const uint8_t *image_address) {
reboot_to_bootloader(); reboot_to_bootloader();
} }
} }
static inline uint32_t svc_get_systick_val(void) {
if (is_mode_unprivileged() && !is_mode_handler()) {
__asm__ __volatile__("svc %0" ::"i"(SVC_GET_SYSTICK_VAL) : "memory");
return systick_val_copy;
} else {
systick_val_copy = SysTick->VAL;
return systick_val_copy;
}
}