diff options
author | Yuval Peress <peress@chromium.org> | 2021-02-12 11:21:04 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-12 19:58:00 +0000 |
commit | fafdc0f8c191c877dc56bc1e45b45e5144039cb7 (patch) | |
tree | 67ac088f82fb4f20270ca4f09418771555e1b25a | |
parent | c2998b09577747f8b9c8b1abdc2a3f9bcc967641 (diff) | |
download | chrome-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>
-rw-r--r-- | zephyr/shim/chip/npcx/CMakeLists.txt | 3 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/include/rom_chip.h | 57 | ||||
-rw-r--r-- | zephyr/shim/chip/npcx/system_external_storage.c | 141 |
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; + } +} |