diff options
-rw-r--r-- | common/system.c | 12 | ||||
-rw-r--r-- | include/system.h | 12 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/system.c | 68 |
3 files changed, 77 insertions, 15 deletions
diff --git a/common/system.c b/common/system.c index e626e250aa..9a18719148 100644 --- a/common/system.c +++ b/common/system.c @@ -46,18 +46,6 @@ /* Round up to a multiple of 4 */ #define ROUNDUP4(x) (((x) + 3) & ~3) -#ifdef CONFIG_ZEPHYR -#ifdef CONFIG_CPU_CORTEX_M -/* - * For cortex-m we cannot use irq_lock() for disabling all the interrupts - * because it leaves some (NMI and faults) still enabled. - */ -#define interrupt_disable_all() __asm__("cpsid i") -#endif -#else /* !CONFIG_ZEPHYR */ -#define interrupt_disable_all() interrupt_disable() -#endif /* CONFIG_ZEPHYR */ - /* Data for an individual jump tag */ struct jump_tag { uint16_t tag; /* Tag ID */ diff --git a/include/system.h b/include/system.h index c50c44797b..ef86d821aa 100644 --- a/include/system.h +++ b/include/system.h @@ -17,6 +17,18 @@ #include "ec_commands.h" #include "timer.h" +#ifdef CONFIG_ZEPHYR +#ifdef CONFIG_CPU_CORTEX_M +/* + * For cortex-m we cannot use irq_lock() for disabling all the interrupts + * because it leaves some (NMI and faults) still enabled. + */ +#define interrupt_disable_all() __asm__("cpsid i") +#endif +#else /* !CONFIG_ZEPHYR */ +#define interrupt_disable_all() interrupt_disable() +#endif /* CONFIG_ZEPHYR */ + /* Per chip implementation to save/read raw EC_RESET_FLAG_ flags. */ void chip_save_reset_flags(uint32_t flags); uint32_t chip_read_reset_flags(void); diff --git a/zephyr/shim/chip/npcx/system.c b/zephyr/shim/chip/npcx/system.c index 4e25363415..d776733827 100644 --- a/zephyr/shim/chip/npcx/system.c +++ b/zephyr/shim/chip/npcx/system.c @@ -3,30 +3,92 @@ * found in the LICENSE file. */ +#include <drivers/cros_bbram.h> #include <drivers/cros_system.h> #include <logging/log.h> +#include "watchdog.h" #include "system.h" +#define GET_BBRAM_OFFSET(node) \ + DT_PROP(DT_PATH(named_bbram_regions, node), offset) +#define GET_BBRAM_SIZE(node) DT_PROP(DT_PATH(named_bbram_regions, node), size) + LOG_MODULE_REGISTER(shim_npcx_system, LOG_LEVEL_ERR); +const struct device *bbram_dev; + +void chip_save_reset_flags(uint32_t flags) +{ + if (bbram_dev == NULL) { + LOG_ERR("bbram_dev doesn't binding"); + return; + } + + cros_bbram_write(bbram_dev, GET_BBRAM_OFFSET(saved_reset_flags), + GET_BBRAM_SIZE(saved_reset_flags), (uint8_t *)&flags); +} + +uint32_t chip_read_reset_flags(void) +{ + uint32_t flags; + + if (bbram_dev == NULL) { + LOG_ERR("bbram_dev doesn't binding"); + return 0; + } + + cros_bbram_read(bbram_dev, GET_BBRAM_OFFSET(saved_reset_flags), + GET_BBRAM_SIZE(saved_reset_flags), (uint8_t *)&flags); + + return flags; +} + void system_reset(int flags) { const struct device *sys_dev = device_get_binding("CROS_SYSTEM"); int err; + uint32_t save_flags; if (!sys_dev) LOG_ERR("sys_dev get binding failed"); - /* - * TODO(b/176523207): reset flag & SYSTEM_RESET_WAIT_EXT - */ + /* Disable interrupts to avoid task swaps during reboot */ + interrupt_disable_all(); + + /* Get flags to be saved in BBRAM */ + system_encode_save_flags(flags, &save_flags); + + /* Store flags to battery backed RAM. */ + chip_save_reset_flags(save_flags); + + /* If WAIT_EXT is set, then allow 10 seconds for external reset */ + if (flags & SYSTEM_RESET_WAIT_EXT) { + int i; + + /* Wait 10 seconds for external reset */ + for (i = 0; i < 1000; i++) { + watchdog_reload(); + udelay(10000); + } + } err = cros_system_soc_reset(sys_dev); if (err < 0) LOG_ERR("soc reset failed"); + /* should never return */ while (1) ; } + +static int chip_system_init(const struct device *unused) +{ + ARG_UNUSED(unused); + + bbram_dev = device_get_binding(DT_LABEL(DT_NODELABEL(bbram))); + return 0; +} + +SYS_INIT(chip_system_init, PRE_KERNEL_1, 50); |