summaryrefslogtreecommitdiff
path: root/zephyr/shim/chip/npcx/system_external_storage.c
diff options
context:
space:
mode:
authorYuval Peress <peress@chromium.org>2021-02-12 11:21:04 -0700
committerCommit Bot <commit-bot@chromium.org>2021-02-12 19:58:00 +0000
commitfafdc0f8c191c877dc56bc1e45b45e5144039cb7 (patch)
tree67ac088f82fb4f20270ca4f09418771555e1b25a /zephyr/shim/chip/npcx/system_external_storage.c
parentc2998b09577747f8b9c8b1abdc2a3f9bcc967641 (diff)
downloadchrome-ec-fafdc0f8c191c877dc56bc1e45b45e5144039cb7.tar.gz
zephyr: add npcx-specific system functions for external storage.
In order to sysjump we first need to copy the RW image from flash. rom_chip.h adds a macro to call ROM function download_from_flash (while system_external_storage.c contains all the npcx specific code needed to perform the sysjump). BRANCH=none BUG=b:167392037 TEST=zmake testall Signed-off-by: Yuval Peress <peress@chromium.org> Change-Id: I762954a71e87036b63513ae8b400605ed507fcf6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2693527 Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'zephyr/shim/chip/npcx/system_external_storage.c')
-rw-r--r--zephyr/shim/chip/npcx/system_external_storage.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/zephyr/shim/chip/npcx/system_external_storage.c b/zephyr/shim/chip/npcx/system_external_storage.c
new file mode 100644
index 0000000000..873686e44a
--- /dev/null
+++ b/zephyr/shim/chip/npcx/system_external_storage.c
@@ -0,0 +1,141 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "clock_chip.h"
+#include "common.h"
+#include "rom_chip.h"
+#include "system.h"
+
+/* TODO (b:179900857) Make this implementation not npcx specific. */
+
+#define NPCX_MDC_BASE_ADDR 0x4000C000
+#define NPCX_FWCTRL REG8(NPCX_MDC_BASE_ADDR + 0x007)
+#define NPCX_FWCTRL_RO_REGION 0
+#define NPCX_FWCTRL_FW_SLOT 1
+#define SET_BIT(reg, bit) ((reg) |= (0x1 << (bit)))
+#define CLEAR_BIT(reg, bit) ((reg) &= (~(0x1 << (bit))))
+#define IS_BIT_SET(reg, bit) (((reg) >> (bit)) & (0x1))
+
+void system_jump_to_booter(void)
+{
+ enum API_RETURN_STATUS_T status __attribute__((unused));
+ static uint32_t flash_offset;
+ static uint32_t flash_used;
+ static uint32_t addr_entry;
+
+ /*
+ * Get memory offset and size for RO/RW regions.
+ * Both of them need 16-bytes alignment since GDMA burst mode.
+ */
+ switch (system_get_shrspi_image_copy()) {
+ case EC_IMAGE_RW:
+ flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
+ CONFIG_RW_STORAGE_OFF;
+ flash_used = CONFIG_RW_SIZE;
+ break;
+#ifdef CONFIG_RW_B
+ case EC_IMAGE_RW_B:
+ flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
+ CONFIG_RW_B_STORAGE_OFF;
+ flash_used = CONFIG_RW_SIZE;
+ break;
+#endif
+ case EC_IMAGE_RO:
+ default: /* Jump to RO by default */
+ flash_offset = CONFIG_EC_PROTECTED_STORAGE_OFF +
+ CONFIG_RO_STORAGE_OFF;
+ flash_used = CONFIG_RO_SIZE;
+ break;
+ }
+
+ /* Make sure the reset vector is inside the destination image */
+ addr_entry = *(uintptr_t *)(flash_offset +
+ CONFIG_MAPPED_STORAGE_BASE + 4);
+
+ /*
+ * Speed up FW download time by increasing clock freq of EC. It will
+ * restore to default in clock_init() later.
+ */
+ clock_turbo();
+
+/*
+ * npcx9 Rev.1 has the problem for download_from_flash API.
+ * Workwaroud it by executing the system_download_from_flash function
+ * in the suspend RAM like npcx5.
+ * TODO: Removing npcx9 when Rev.2 is available.
+ */
+ /* Bypass for GMDA issue of ROM api utilities */
+#if defined(CHIP_FAMILY_NPCX5) || defined(CONFIG_WORKAROUND_FLASH_DOWNLOAD_API)
+ system_download_from_flash(
+ flash_offset, /* The offset of the data in spi flash */
+ CONFIG_PROGRAM_MEMORY_BASE, /* RAM Addr of downloaded data */
+ flash_used, /* Number of bytes to download */
+ addr_entry /* jump to this address after download */
+ );
+#else
+ download_from_flash(
+ flash_offset, /* The offset of the data in spi flash */
+ CONFIG_PROGRAM_MEMORY_BASE, /* RAM Addr of downloaded data */
+ flash_used, /* Number of bytes to download */
+ SIGN_NO_CHECK, /* Need CRC check or not */
+ addr_entry, /* jump to this address after download */
+ &status /* Status fo download */
+ );
+#endif
+}
+
+uint32_t system_get_lfw_address()
+{
+ /*
+ * In A3 version, we don't use little FW anymore
+ * We provide the alternative function in ROM
+ */
+ uint32_t jump_addr = (uint32_t)system_jump_to_booter;
+ return jump_addr;
+}
+
+enum ec_image system_get_shrspi_image_copy(void)
+{
+ /* TODO (b:179900857) Make this implementation not npcx specific. */
+ if (IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION)) {
+ /* RO image */
+#ifdef CHIP_HAS_RO_B
+ if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT))
+ return EC_IMAGE_RO_B;
+#endif
+ return EC_IMAGE_RO;
+ } else {
+#ifdef CONFIG_RW_B
+ /* RW image */
+ if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT))
+ /* Slot A */
+ return EC_IMAGE_RW_B;
+#endif
+ return EC_IMAGE_RW;
+ }
+}
+
+void system_set_image_copy(enum ec_image copy)
+{
+ /* TODO (b:179900857) Make this implementation not npcx specific. */
+ switch (copy) {
+ case EC_IMAGE_RW:
+ CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
+ SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+#ifdef CONFIG_RW_B
+ case EC_IMAGE_RW_B:
+ CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
+ CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+#endif
+ default:
+ /* Fall through to EC_IMAGE_RO */
+ case EC_IMAGE_RO:
+ SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
+ SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+ }
+}