Skip to content

Commit

Permalink
drivers: stm32_iwdg: add get_timeleft watchdog handler
Browse files Browse the repository at this point in the history
Implement .get_timeleft() watchdog operation handler for non-secure
world to query the watchdog device state. System time is logged a each
watchdog refresh to estimate time remaining before the watchdog elapses.

This change declare arm_cntpct_time_source and unpaged for
stm32mp15 platform compliance.

Change-Id: I15e283fa0fa8904b8a22da15283a9ca94639599e
Signed-off-by: Antonio Borneo <[email protected]>
Signed-off-by: Etienne Carriere <[email protected]>
  • Loading branch information
etienne-lms committed Dec 20, 2023
1 parent 661a146 commit db73e79
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/arch/arm/kernel/tee_time_arm_cntpct.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <arm.h>
#include <crypto/crypto.h>
#include <keep.h>
#include <kernel/misc.h>
#include <kernel/tee_time.h>
#include <kernel/time_source.h>
Expand Down Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions core/drivers/stm32_iwdg.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <kernel/panic.h>
#include <kernel/pm.h>
#include <kernel/spinlock.h>
#include <kernel/tee_time.h>
#include <libfdt.h>
#include <mm/core_memprot.h>
#include <sm/sm.h>
Expand Down Expand Up @@ -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
*/
Expand All @@ -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;
};
Expand Down Expand Up @@ -234,13 +237,19 @@ 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);
}

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);
}

Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit db73e79

Please sign in to comment.