summaryrefslogtreecommitdiff
path: root/zephyr/shim/chip
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
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')
-rw-r--r--zephyr/shim/chip/npcx/CMakeLists.txt3
-rw-r--r--zephyr/shim/chip/npcx/include/rom_chip.h57
-rw-r--r--zephyr/shim/chip/npcx/system_external_storage.c141
3 files changed, 201 insertions, 0 deletions
diff --git a/zephyr/shim/chip/npcx/CMakeLists.txt b/zephyr/shim/chip/npcx/CMakeLists.txt
index e5c16b7144..3c841da1fe 100644
--- a/zephyr/shim/chip/npcx/CMakeLists.txt
+++ b/zephyr/shim/chip/npcx/CMakeLists.txt
@@ -7,3 +7,6 @@ zephyr_include_directories(include)
zephyr_sources(clock.c)
zephyr_sources_ifdef(CONFIG_CROS_KB_RAW_NPCX keyboard_raw.c)
zephyr_sources_ifdef(CONFIG_CROS_EC system.c)
+
+zephyr_sources_ifdef(CONFIG_PLATFORM_EC_EXTERNAL_STORAGE
+ system_external_storage.c)
diff --git a/zephyr/shim/chip/npcx/include/rom_chip.h b/zephyr/shim/chip/npcx/include/rom_chip.h
new file mode 100644
index 0000000000..aab166e6f1
--- /dev/null
+++ b/zephyr/shim/chip/npcx/include/rom_chip.h
@@ -0,0 +1,57 @@
+/* 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.
+ */
+
+#ifndef __CROS_EC_ROM_CHIP_H
+#define __CROS_EC_ROM_CHIP_H
+
+#include "common.h"
+
+/* Enumerations of ROM api functions */
+enum API_SIGN_OPTIONS_T {
+ SIGN_NO_CHECK = 0,
+ SIGN_CRC_CHECK = 1,
+};
+
+enum API_RETURN_STATUS_T {
+ /* Successful download */
+ API_RET_STATUS_OK = 0,
+ /* Address is outside of flash or not 4 bytes aligned. */
+ API_RET_STATUS_INVALID_SRC_ADDR = 1,
+ /* Address is outside of RAM or not 4 bytes aligned. */
+ API_RET_STATUS_INVALID_DST_ADDR = 2,
+ /* Size is 0 or not 4 bytes aligned. */
+ API_RET_STATUS_INVALID_SIZE = 3,
+ /* Flash Address + Size is out of flash. */
+ API_RET_STATUS_INVALID_SIZE_OUT_OF_FLASH = 4,
+ /* RAM Address + Size is out of RAM. */
+ API_RET_STATUS_INVALID_SIZE_OUT_OF_RAM = 5,
+ /* Wrong sign option. */
+ API_RET_STATUS_INVALID_SIGN = 6,
+ /* Error during Code copy. */
+ API_RET_STATUS_COPY_FAILED = 7,
+ /* Execution Address is outside of RAM */
+ API_RET_STATUS_INVALID_EXE_ADDR = 8,
+ /* Bad CRC value */
+ API_RET_STATUS_INVALID_SIGNATURE = 9,
+};
+
+/* Macro functions of ROM api functions */
+#define ADDR_DOWNLOAD_FROM_FLASH (*(volatile uint32_t *) 0x40)
+#define download_from_flash(src_offset, dest_addr, size, sign, exe_addr, \
+ status) \
+ (((download_from_flash_ptr) ADDR_DOWNLOAD_FROM_FLASH) \
+ (src_offset, dest_addr, size, sign, exe_addr, status))
+
+/* Declarations of ROM api functions */
+typedef void (*download_from_flash_ptr) (
+ uint32_t src_offset, /* The offset of the data to be downloaded */
+ uint32_t dest_addr, /* The address of the downloaded data in the RAM*/
+ uint32_t size, /* Number of bytes to download */
+ enum API_SIGN_OPTIONS_T sign, /* Need CRC check or not */
+ uint32_t exe_addr, /* jump to this address after download if not zero */
+ enum API_RETURN_STATUS_T *status /* Status fo download */
+);
+
+#endif /* __CROS_EC_ROM_CHIP_H */
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;
+ }
+}