summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/system.c12
-rw-r--r--include/system.h12
-rw-r--r--zephyr/shim/chip/npcx/system.c68
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);