diff --git a/core/arch/arm/kernel/tee_time_arm_cntpct.c b/core/arch/arm/kernel/tee_time_arm_cntpct.c index 112dfc3d3b5..94af18c128b 100644 --- a/core/arch/arm/kernel/tee_time_arm_cntpct.c +++ b/core/arch/arm/kernel/tee_time_arm_cntpct.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ static const struct time_source arm_cntpct_time_source = { }; REGISTER_TIME_SOURCE(arm_cntpct_time_source) +DECLARE_KEEP_PAGER(arm_cntpct_time_source); /* * We collect jitter using cntpct in 32- or 64-bit mode that is typically diff --git a/core/drivers/stm32_iwdg.c b/core/drivers/stm32_iwdg.c index 0489c3b2472..845f822b6ec 100644 --- a/core/drivers/stm32_iwdg.c +++ b/core/drivers/stm32_iwdg.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,7 @@ * @flags - Property flags for the IWDG instance * @timeout - Watchdog elaspure timeout * @hw_version - Watchdog HW version + * @last_refresh - Time of last watchdog refresh * @wdt_chip - Wathcdog chip instance * @link - Link in registered watchdog instance list */ @@ -102,6 +104,7 @@ struct stm32_iwdg_device { uint32_t flags; unsigned long timeout; unsigned int hw_version; + TEE_Time last_refresh; struct wdt_chip wdt_chip; SLIST_ENTRY(stm32_iwdg_device) link; }; @@ -234,6 +237,9 @@ static TEE_Result configure_timeout(struct stm32_iwdg_device *iwdg) static void iwdg_start(struct stm32_iwdg_device *iwdg) { + if (tee_time_get_sys_time(&iwdg->last_refresh)) + panic(); + io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_START_KEY); iwdg_wdt_set_enabled(iwdg); @@ -241,6 +247,9 @@ static void iwdg_start(struct stm32_iwdg_device *iwdg) static void iwdg_refresh(struct stm32_iwdg_device *iwdg) { + if (tee_time_get_sys_time(&iwdg->last_refresh)) + panic(); + io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); } @@ -305,11 +314,43 @@ static TEE_Result iwdg_wdt_set_timeout(struct wdt_chip *chip, return TEE_SUCCESS; } +static TEE_Result iwdg_wdt_get_timeleft(struct wdt_chip *chip, bool *is_enabled, + unsigned long *timeleft) +{ + struct stm32_iwdg_device *iwdg = wdt_chip_to_iwdg(chip); + TEE_Result res = TEE_ERROR_GENERIC; + TEE_Time time = { }; + TEE_Time now = { }; + + *is_enabled = iwdg_wdt_is_enabled(iwdg); + + if (!*is_enabled) { + *timeleft = 0; + return TEE_SUCCESS; + } + + res = tee_time_get_sys_time(&now); + if (res) + panic(); + + time.seconds = iwdg->timeout; + TEE_TIME_ADD(iwdg->last_refresh, time, time); + if (TEE_TIME_LE(time, now)) { + *timeleft = 0; + } else { + TEE_TIME_SUB(time, now, time); + *timeleft = time.seconds; + } + + return TEE_SUCCESS; +} + static const struct wdt_ops stm32_iwdg_ops = { .init = iwdg_wdt_init, .start = iwdg_wdt_start, .ping = iwdg_wdt_refresh, .set_timeout = iwdg_wdt_set_timeout, + .get_timeleft = iwdg_wdt_get_timeleft, }; DECLARE_KEEP_PAGER(stm32_iwdg_ops);