From 271c1c024d508944d8b0486567dd387ba3305ff4 Mon Sep 17 00:00:00 2001 From: James Ye Date: Fri, 24 May 2019 16:41:00 +1000 Subject: [PATCH] odroidc2: watchdog reset for AOS Reset when "reset" is typed into UART. Co-Authored-By: Anna Lyons Co-Authored-By: Curtis Millar --- include/arch/arm/arch/object/interrupt.h | 10 +++++ include/machine/io.h | 3 ++ src/arch/arm/kernel/boot.c | 4 ++ src/drivers/serial/meson-gx-uart.c | 47 ++++++++++++++++++++++++ src/plat/odroidc2/overlay-odroidc2.dts | 1 + tools/hardware.yml | 8 ++++ 6 files changed, 73 insertions(+) diff --git a/include/arch/arm/arch/object/interrupt.h b/include/arch/arm/arch/object/interrupt.h index 69ba77e73..9b0d506c1 100644 --- a/include/arch/arm/arch/object/interrupt.h +++ b/include/arch/arm/arch/object/interrupt.h @@ -21,6 +21,11 @@ exception_t decodeSGISignalInvocation(word_t invLabel, word_t length, /* Handle a platform-reserved IRQ. */ static inline void handleReservedIRQ(irq_t irq) { +#ifdef CONFIG_IRQ_REPORTING + if (IRQT_TO_IRQ(irq) != KERNEL_UART_IRQ) { + printf("Received reserved IRQ: %d\n", (int)IRQT_TO_IRQ(irq)); + } +#endif #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT if (IRQT_TO_IRQ(irq) == KERNEL_PMU_IRQ) { @@ -51,6 +56,11 @@ static inline void handleReservedIRQ(irq_t irq) #ifdef CONFIG_IRQ_REPORTING printf("Received unhandled reserved IRQ: 0x%lx\n", IRQT_TO_IRQ(irq)); #endif + + if (IRQT_TO_IRQ(irq) == KERNEL_UART_IRQ) { + handleUartIRQ(); + return; + } } diff --git a/include/machine/io.h b/include/machine/io.h index dd4738d7b..4e4997aa9 100644 --- a/include/machine/io.h +++ b/include/machine/io.h @@ -12,6 +12,9 @@ /* io for dumping capdl */ unsigned char kernel_getDebugChar(void); #endif +/* for reset */ +void handleUartIRQ(void); +void init_serial(void); #ifdef CONFIG_PRINTING diff --git a/src/arch/arm/kernel/boot.c b/src/arch/arm/kernel/boot.c index 93eb4d133..08e4e196a 100644 --- a/src/arch/arm/kernel/boot.c +++ b/src/arch/arm/kernel/boot.c @@ -131,6 +131,8 @@ BOOT_CODE static void init_irqs(cap_t root_cnode_cap) #ifdef CONFIG_TK1_SMMU setIRQState(IRQReserved, CORE_IRQ_TO_IRQT(0, INTERRUPT_SMMU)); #endif + setIRQTrigger(CORE_IRQ_TO_IRQT(0, KERNEL_UART_IRQ), 1); + setIRQState(IRQReserved, CORE_IRQ_TO_IRQT(0, KERNEL_UART_IRQ)); #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT #ifdef KERNEL_PMU_IRQ @@ -672,6 +674,8 @@ BOOT_CODE VISIBLE void init_kernel( NODE_STATE(ksCurTime) = getCurrentTime(); NODE_STATE(ksConsumed) = 0; #endif + + init_serial(); schedule(); activateThread(); } diff --git a/src/drivers/serial/meson-gx-uart.c b/src/drivers/serial/meson-gx-uart.c index a3f6c2d2a..e2b34ac37 100644 --- a/src/drivers/serial/meson-gx-uart.c +++ b/src/drivers/serial/meson-gx-uart.c @@ -6,19 +6,66 @@ #include #include +#include #include #include #include #define UART_WFIFO 0x0 #define UART_RFIFO 0x4 +#define UART_CTRL 0x8 #define UART_STATUS 0xC +#define UART_MISC 0x10 #define UART_TX_FULL BIT(21) #define UART_RX_EMPTY BIT(20) +#define UART_RX_IRQ BIT(27) +#define UART_RX_EN BIT(13) +#define UART_TX_EN BIT(12) + #define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x))) +#define WDOG_EN BIT(18) +#define WDOG_SYS_RESET_EN BIT(21) +#define WDOG_CLK_EN BIT(24) +#define WDOG_CLK_DIV_EN BIT(25) +#define WDOG_SYS_RESET_NOW BIT(26) + +static const char *reset = "reset"; +static int index = 0; + +void init_serial(void) +{ + /* enable tx, rx and rx irq */ + *(UART_REG(UART_CTRL)) |= UART_TX_EN | UART_RX_EN | UART_RX_IRQ; + /* send irq when 1 char is available */ + *(UART_REG(UART_MISC)) = 1; +} + +void handleUartIRQ(void) +{ + /* while there are chars to process */ + while (!(*UART_REG(UART_STATUS) & UART_RX_EMPTY)) { + char c = *UART_REG(UART_RFIFO); + putDebugChar(c); + if (c == 'r') { + index = 1; + } else if (c == reset[index]) { + index++; + } else { + index = 0; + } + if (index == strnlen(reset, 5)) { + /* do the reset */ + printf("\nResetting Odroid-C2\n"); + volatile uint32_t *wdog = (volatile uint32_t *) (WDOG_PPTR); + *wdog = (WDOG_EN | WDOG_SYS_RESET_EN | WDOG_CLK_EN | + WDOG_CLK_DIV_EN | WDOG_SYS_RESET_NOW); + } + } +} + #ifdef CONFIG_PRINTING void uart_drv_putchar(unsigned char c) { diff --git a/src/plat/odroidc2/overlay-odroidc2.dts b/src/plat/odroidc2/overlay-odroidc2.dts index cda5d434d..0ff365d29 100644 --- a/src/plat/odroidc2/overlay-odroidc2.dts +++ b/src/plat/odroidc2/overlay-odroidc2.dts @@ -14,6 +14,7 @@ seL4,kernel-devices = "serial0", &{/soc/interrupt-controller@c4301000}, + &{/soc/bus@c1100000/watchdog@98d0}, &{/timer}; }; }; diff --git a/tools/hardware.yml b/tools/hardware.yml index 523be51af..0babd79ba 100644 --- a/tools/hardware.yml +++ b/tools/hardware.yml @@ -200,6 +200,14 @@ devices: macro: CONFIG_PRINTING user: true kernel_size: 0x1000 + interrupts: + KERNEL_UART_IRQ: 0 + - compatible: + - amlogic,meson-gx-wdt + - amlogic,meson-gxbb-wdt + regions: + - index: 0 + kernel: WDOG_PPTR # SiFive U54/U74 PLIC (HiFive, Polarfire) - compatible: