Thang Q. Nguyen | 44cf8fd | 2020-12-22 04:27:36 +0000 | [diff] [blame] | 1 | From af4353ab19aaf29dc68ff89a0d581102ca5be43c Mon Sep 17 00:00:00 2001 |
| 2 | From: "Thang Q. Nguyen" <thang@os.amperecomputing.com> |
| 3 | Date: Wed, 6 Jan 2021 06:33:36 +0000 |
| 4 | Subject: [PATCH] aspeed: support passing system reset status to kernel via |
| 5 | bootargs |
| 6 | |
| 7 | This is a backport of the patch file from |
| 8 | openbmc/meta-yadro/meta-nicole/recipes-bsp/u-boot/ |
| 9 | to add the Aspeed reset reason to bootargs so kernel applications |
| 10 | can query it. |
| 11 | |
| 12 | Test case: /proc/cmdline must contain: |
| 13 | - resetreason=power after cold bmc boot |
| 14 | - resetreason=watchdog after warm bmc reboot |
| 15 | |
| 16 | Signed-off-by: Chanh Nguyen <chanh@os.amperecomputing.com> |
| 17 | Signed-off-by: Thang Q. Nguyen <thang@os.amperecomputing.com> |
| 18 | --- |
| 19 | arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 +- |
| 20 | arch/arm/mach-aspeed/ast-scu.c | 6 +- |
| 21 | board/aspeed/ast-g5/ast-g5.c | 81 ++++++++++++++++++++++ |
| 22 | 3 files changed, 87 insertions(+), 2 deletions(-) |
| 23 | |
| 24 | diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h |
| 25 | index d2c010a0dc..f5c9126ec0 100644 |
| 26 | --- a/arch/arm/include/asm/arch-aspeed/ast_scu.h |
| 27 | +++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h |
| 28 | @@ -29,7 +29,7 @@ |
| 29 | #define __AST_SCU_H |
| 30 | |
| 31 | extern void ast_scu_show_system_info (void); |
| 32 | -extern void ast_scu_sys_rest_info(void); |
| 33 | +extern u32 ast_scu_sys_rest_info(void); |
| 34 | extern void ast_scu_security_info(void); |
| 35 | extern u32 ast_scu_revision_id(void); |
| 36 | extern u32 ast_scu_get_vga_memsize(void); |
| 37 | diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c |
| 38 | index ef90ef3805..c7ab66415f 100644 |
| 39 | --- a/arch/arm/mach-aspeed/ast-scu.c |
| 40 | +++ b/arch/arm/mach-aspeed/ast-scu.c |
| 41 | @@ -494,22 +494,26 @@ void ast_scu_security_info(void) |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | -void ast_scu_sys_rest_info(void) |
| 46 | +u32 ast_scu_sys_rest_info(void) |
| 47 | { |
| 48 | u32 rest = ast_scu_read(AST_SCU_SYS_CTRL); |
| 49 | |
| 50 | if (rest & SCU_SYS_EXT_RESET_FLAG) { |
| 51 | printf("RST : External\n"); |
| 52 | ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL); |
| 53 | + rest = SCU_SYS_EXT_RESET_FLAG; |
| 54 | } else if (rest & SCU_SYS_WDT_RESET_FLAG) { |
| 55 | printf("RST : Watchdog\n"); |
| 56 | ast_scu_write(SCU_SYS_WDT_RESET_FLAG, AST_SCU_SYS_CTRL); |
| 57 | + rest = SCU_SYS_WDT_RESET_FLAG; |
| 58 | } else if (rest & SCU_SYS_PWR_RESET_FLAG) { |
| 59 | printf("RST : Power On\n"); |
| 60 | ast_scu_write(SCU_SYS_PWR_RESET_FLAG, AST_SCU_SYS_CTRL); |
| 61 | + rest = SCU_SYS_PWR_RESET_FLAG; |
| 62 | } else { |
| 63 | printf("RST : CLK en\n"); |
| 64 | } |
| 65 | + return rest; |
| 66 | } |
| 67 | |
| 68 | u32 ast_scu_get_vga_memsize(void) |
| 69 | diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c |
| 70 | index 9bf6c905fe..9e27bce0f5 100644 |
| 71 | --- a/board/aspeed/ast-g5/ast-g5.c |
| 72 | +++ b/board/aspeed/ast-g5/ast-g5.c |
| 73 | @@ -8,6 +8,8 @@ |
| 74 | */ |
| 75 | |
| 76 | #include <common.h> |
| 77 | +#include <stdlib.h> |
| 78 | +#include <asm/arch/regs-scu.h> |
| 79 | #include <netdev.h> |
| 80 | |
| 81 | #include <asm/arch/ast_scu.h> |
| 82 | @@ -25,9 +27,76 @@ int board_init(void) |
| 83 | } |
| 84 | |
| 85 | #ifdef CONFIG_BOARD_LATE_INIT |
| 86 | +static void update_bootargs_cmd(const char *key, const char *value) |
| 87 | +{ |
| 88 | + int buf_len; |
| 89 | + char *buf; |
| 90 | + char *cmdline; |
| 91 | + char *end = NULL; |
| 92 | + |
| 93 | + if (!key || (key[0] == '\0')) { |
| 94 | + printf("%s: Empty key not allowed\n", __func__); |
| 95 | + return; |
| 96 | + } |
| 97 | + |
| 98 | + cmdline = getenv("bootargs"); |
| 99 | + |
| 100 | + /* Allocate space for maximum possible new command line */ |
| 101 | + buf_len = (cmdline ? strlen(cmdline) : 0) |
| 102 | + + 1 /* spacebar as delimiter */ |
| 103 | + + strlen(key) |
| 104 | + + (value ? 1 /* equal sign */ + strlen(value) : 0) |
| 105 | + + 1 /* terminating null */; |
| 106 | + |
| 107 | + buf = calloc(buf_len, sizeof(char)); |
| 108 | + if (!buf) { |
| 109 | + printf("%s: out of memory\n", __func__); |
| 110 | + return; |
| 111 | + } |
| 112 | + |
| 113 | + if (cmdline) |
| 114 | + { |
| 115 | + char *start = strstr(cmdline, key); |
| 116 | + |
| 117 | + /* Check for full word match. Match should be start of cmdline |
| 118 | + * or there should be space before match |
| 119 | + **/ |
| 120 | + if (start && ((start == cmdline) || (*(start - 1) == ' '))) { |
| 121 | + strncat(buf, cmdline, (start - cmdline)); |
| 122 | + |
| 123 | + /* Find the end of the keyword[=value] pair, |
| 124 | + * including a single training space character, if any. |
| 125 | + * Skip the found substring, mark the tail of cmdline. |
| 126 | + **/ |
| 127 | + end = strchr(start, ' '); |
| 128 | + if (end) { |
| 129 | + end++; |
| 130 | + } |
| 131 | + } else { |
| 132 | + strcat(buf, cmdline); |
| 133 | + strcat(buf, " "); |
| 134 | + } |
| 135 | + } |
| 136 | + |
| 137 | + strcat(buf, key); |
| 138 | + if (value) { |
| 139 | + strcat(buf, "="); |
| 140 | + strcat(buf, value); |
| 141 | + } |
| 142 | + |
| 143 | + if (end) { |
| 144 | + strcat(buf, " "); |
| 145 | + strcat(buf, end); |
| 146 | + } |
| 147 | + |
| 148 | + setenv("bootargs", buf); |
| 149 | + free(buf); |
| 150 | +} |
| 151 | + |
| 152 | int board_late_init(void) |
| 153 | { |
| 154 | u32 val; |
| 155 | + u32 reset_reason = ast_scu_sys_rest_info(); |
| 156 | |
| 157 | /* Switch PWM to GPIO mode to make FAN run in max speed */ |
| 158 | ast_scu_switch_pwm_to_gpio_mode(); |
| 159 | @@ -44,6 +113,18 @@ int board_late_init(void) |
| 160 | writel(0xaa, AST_SCU_BASE); |
| 161 | #endif |
| 162 | |
| 163 | + if (reset_reason & SCU_SYS_EXT_RESET_FLAG) { |
| 164 | + update_bootargs_cmd("resetreason", "external"); |
| 165 | + } else if (reset_reason & SCU_SYS_WDT_RESET_FLAG) { |
| 166 | + update_bootargs_cmd("resetreason", "watchdog"); |
| 167 | + } else if (reset_reason & SCU_SYS_PWR_RESET_FLAG) { |
| 168 | + update_bootargs_cmd("resetreason", "power"); |
| 169 | + } else { |
| 170 | + char value[32]; |
| 171 | + snprintf(value, sizeof(value) - 1, "0x%x", reset_reason); |
| 172 | + update_bootargs_cmd("resetreason", value); |
| 173 | + } |
| 174 | + |
| 175 | return 0; |
| 176 | } |
| 177 | #endif |
| 178 | -- |
| 179 | 2.25.1 |
| 180 | |