zephyr/soc/riscv/openisa_rv32m1/wdog.S

64 lines
1.4 KiB
ArmAsm

/*
* Copyright (c) 2018 Foundries.io Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <linker/sections.h>
#include <toolchain.h>
#include <arch/cpu.h>
/* Exports */
GTEXT(_WdogInit)
/* WDOG instance base address. */
#ifdef CONFIG_SOC_OPENISA_RV32M1_RI5CY
#define WDOG_BASE 0x4002A000 /* WDOG0 */
#else
#define WDOG_BASE 0x41026000 /* WDOG1 */
#endif
/* Register offsets. */
#define WDOG_CS_OFFSET 0x00
#define WDOG_CNT_OFFSET 0x04
#define WDOG_TOVAL_OFFSET 0x08
/* Watchdog unlock key. */
#define WDOG_CNT_UNLOCK 0xD928C520
/* TOVAL must be set when disabling watchdog after reset. */
#define WDOG_TOVAL_SET 0xFFFF
/* Disable the WDOG_CS[EN] bit. */
#define WDOG_CS_EN_DISABLED ~0x80
/* Set WDOG_CS[UPDATE] bit. */
#define WDOG_CS_UPDATE_ENABLED 0x20
/*
* Unlock and disable the watchdog, which is enabled by default.
*/
SECTION_FUNC(TEXT, _WdogInit)
/* Disable interrupts if they're on. This is timing-sensitive code. */
csrrc t0, mstatus, MSTATUS_IEN
/* Get base address. */
li t1, WDOG_BASE
/* Unlock the watchdog. */
li t2, WDOG_CNT_UNLOCK
sw t2, WDOG_CNT_OFFSET(t1)
/* Disable the watchdog. Allow updates later. */
lw t2, WDOG_CS_OFFSET(t1)
andi t2, t2, WDOG_CS_EN_DISABLED
ori t2, t2, WDOG_CS_UPDATE_ENABLED
sw t2, WDOG_CS_OFFSET(t1)
/* This must also be done per reference manual. */
li t2, WDOG_TOVAL_SET
sw t2, WDOG_TOVAL_OFFSET(t1)
/* Re-enable interrupts if they were disabled. */
csrrs x0, mstatus, t0
ret