Skip to content

Commit

Permalink
sparcv8leon-gr740: implement reboot through watchdog
Browse files Browse the repository at this point in the history
JIRA: RTOS-883
  • Loading branch information
lukileczo committed Jan 21, 2025
1 parent d3c627a commit f833876
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
3 changes: 3 additions & 0 deletions hal/sparcv8leon/gaisler/gaisler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ typedef struct {
int gaisler_iomuxCfg(iomux_cfg_t *ioCfg);


__attribute__((noreturn)) void timer_wdogReboot(void);


#endif
6 changes: 1 addition & 5 deletions hal/sparcv8leon/gaisler/gr740/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,5 @@ int hal_cpuJump(void)

void hal_cpuReboot(void)
{
/* TODO */
for (;;) {
}

__builtin_unreachable();
timer_wdogReboot();
}
34 changes: 29 additions & 5 deletions hal/sparcv8leon/gaisler/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

static struct {
vu32 *gptimer0_base;
u32 wdog;
vu32 *gptimer1_base;
volatile time_t time;
u32 ticksPerFreq;
Expand All @@ -57,6 +58,9 @@ __attribute__((section(".noxip"))) static int timer_isr(unsigned int irq, void *
/* Clear irq status - set & clear to handle different GPTIMER core versions */
*(timer_common.gptimer0_base + GPT_TCTRL(TIMER_DEFAULT)) |= TIMER_INT_PENDING;
*(timer_common.gptimer0_base + GPT_TCTRL(TIMER_DEFAULT)) &= ~TIMER_INT_PENDING;

/* Kick watchdog (on GR740 there's a fixed PLL watchdog, restarted on watchdog timer tctrl write) */
*(timer_common.gptimer0_base + GPT_TCTRL(timer_common.wdog)) |= TIMER_LOAD;
}

return 0;
Expand Down Expand Up @@ -87,15 +91,32 @@ __attribute__((section(".noxip"))) time_t hal_timerGet(void)
}


void timer_wdogReboot(void)
{
/* Reboot system using watchdog */
*(timer_common.gptimer0_base + GPT_SRELOAD) = 0;
*(timer_common.gptimer0_base + GPT_SCALER) = 0;
hal_cpuDataStoreBarrier();
*(timer_common.gptimer0_base + GPT_TRLDVAL(timer_common.wdog)) = 1;
hal_cpuDataStoreBarrier();

/* Interrupt must be enabled for the watchdog to work */
*(timer_common.gptimer0_base + GPT_TCTRL(timer_common.wdog)) = TIMER_LOAD | TIMER_INT_ENABLE | TIMER_ENABLE;

for (;;) { }
}


void timer_done(void)
{
int timer;
vu32 st;
u32 timer;
u32 tcnt = *(timer_common.gptimer0_base + GPT_CONFIG) & 0x7;

/* Disable timer interrupts - bits cleared when written 1 */
st = *(timer_common.gptimer0_base + GPT_TCTRL(TIMER_DEFAULT)) & (TIMER_INT_ENABLE | TIMER_INT_PENDING);
vu32 st = *(timer_common.gptimer0_base + GPT_TCTRL(TIMER_DEFAULT)) & (TIMER_INT_ENABLE | TIMER_INT_PENDING);
*(timer_common.gptimer0_base + GPT_TCTRL(TIMER_DEFAULT)) = st;

for (timer = 1; timer <= TIMER0_CNT; ++timer) {
for (timer = 1; timer <= tcnt; ++timer) {
/* Disable timers */
*(timer_common.gptimer0_base + GPT_TCTRL(timer)) = 0;
/* Reset counter and reload value */
Expand All @@ -105,10 +126,12 @@ void timer_done(void)

/* We might not have second timer core */
if (timer_common.gptimer1_base != NULL) {
tcnt = *(timer_common.gptimer1_base + GPT_CONFIG) & 0x7;

st = *(timer_common.gptimer1_base + GPT_TCTRL(TIMER_DEFAULT)) & (TIMER_INT_ENABLE | TIMER_INT_PENDING);
*(timer_common.gptimer1_base + GPT_TCTRL(TIMER_DEFAULT)) = st;

for (timer = 1; timer <= TIMER1_CNT; ++timer) {
for (timer = 1; timer <= tcnt; ++timer) {
*(timer_common.gptimer1_base + GPT_TCTRL(TIMER_DEFAULT)) = 0;
*(timer_common.gptimer1_base + GPT_TCNTVAL(timer)) = 0;
*(timer_common.gptimer1_base + GPT_TRLDVAL(timer)) = 0;
Expand All @@ -124,6 +147,7 @@ void timer_init(void)
timer_common.time = 0;
timer_common.gptimer0_base = (u32 *)GPTIMER0_BASE;
timer_common.gptimer1_base = (u32 *)GPTIMER1_BASE;
timer_common.wdog = *(timer_common.gptimer0_base + GPT_CONFIG) & 0x7;

/* Reset timer */
timer_done();
Expand Down

0 comments on commit f833876

Please sign in to comment.