diff options
author | martin yan <martin.yan@microchip.corp-partner.google.com> | 2022-06-02 16:32:18 -0400 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-06-09 20:55:08 +0000 |
commit | 84703209f27ee4413600cb9d229774dc99083a8d (patch) | |
tree | a2cc1241a23d1e26781cbf96a6897368fd17cb26 | |
parent | 02afda7df5b23708ba3d8a7f0b5d2f66ae099ffe (diff) | |
download | chrome-ec-84703209f27ee4413600cb9d229774dc99083a8d.tar.gz |
zephyr: mchp: Support sysjump function
Support sysjump function, similar mechanism as other vendor
implementation
BUG=none
BRANCH=main
TEST=Test on adlrvp_mchp project via console sysinfo and sysjump RW/RO
Signed-off-by: martin yan <martin.yan@microchip.corp-partner.google.com>
Change-Id: Ic5e0c32408f993de01579ac5a77b6b84a2fe5811
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3686760
Reviewed-by: Wai-Hong Tam <waihong@google.com>
-rw-r--r-- | zephyr/shim/chip/mchp/include/flash_chip.h | 16 | ||||
-rw-r--r-- | zephyr/shim/chip/mchp/system.c | 23 | ||||
-rw-r--r-- | zephyr/shim/chip/mchp/system_download_from_flash.c | 18 | ||||
-rw-r--r-- | zephyr/shim/chip/mchp/system_external_storage.c | 89 | ||||
-rw-r--r-- | zephyr/shim/src/watchdog.c | 5 |
5 files changed, 122 insertions, 29 deletions
diff --git a/zephyr/shim/chip/mchp/include/flash_chip.h b/zephyr/shim/chip/mchp/include/flash_chip.h index 9af8bd330d..b3677fb45c 100644 --- a/zephyr/shim/chip/mchp/include/flash_chip.h +++ b/zephyr/shim/chip/mchp/include/flash_chip.h @@ -11,15 +11,19 @@ * Similar to W25X40, both only have one status reg */ #define CONFIG_SPI_FLASH_W25X40 /* Internal SPI flash type. */ - #define CONFIG_FLASH_WRITE_SIZE 0x1 /* minimum write size */ #define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 /* one page size for write */ -#define CONFIG_FLASH_ERASE_SIZE 0x10000 +#define CONFIG_FLASH_ERASE_SIZE 0x1000 #define CONFIG_FLASH_BANK_SIZE CONFIG_FLASH_ERASE_SIZE -/* RO image resides at start of protected region, right after header */ -#define CONFIG_RO_STORAGE_OFF CONFIG_RO_HDR_SIZE - -#define CONFIG_RW_STORAGE_OFF 0 +/* RO image resides at 4KB offset in protected region + * The first 4KB in the protected region starting at offset 0 contains + * the Boot-ROM TAGs and Boot-ROM Header for EC_RO. These objects are + * not loaded into RAM. + * RW image is never loaded by the Boot-ROM therefore no TAG or Header + * is needed. RW starts at offset 0 in RW storage region. + */ +#define CONFIG_RO_STORAGE_OFF 0x1000 +#define CONFIG_RW_STORAGE_OFF 0 #endif /* __CROS_EC_FLASH_CHIP_H */ diff --git a/zephyr/shim/chip/mchp/system.c b/zephyr/shim/chip/mchp/system.c index f4e0d09d4d..25fdfc9897 100644 --- a/zephyr/shim/chip/mchp/system.c +++ b/zephyr/shim/chip/mchp/system.c @@ -11,6 +11,29 @@ LOG_MODULE_REGISTER(shim_xec_system, LOG_LEVEL_ERR); +#define GET_BBRAM_OFS(node) \ + DT_PROP(DT_PATH(named_bbram_regions, node), offset) +#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size) + +/* + * Reset image type back to RO in BBRAM as watchdog resets. + * Watchdog reset will reset EC chip, ROM loader loads RO + * image stored in SPI flash chip in default. + */ +void cros_chip_wdt_handler(const struct device *wdt_dev, int channel_id) +{ + const struct device *bbram_dev = DEVICE_DT_GET(DT_NODELABEL(bbram)); + uint32_t value = EC_IMAGE_RO; + + if (!device_is_ready(bbram_dev)) { + LOG_ERR("WDT ISR: device %s is not ready", bbram_dev->name); + return; + } + + bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load), + GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value); +} + static void chip_bbram_status_check(void) { const struct device *bbram_dev; diff --git a/zephyr/shim/chip/mchp/system_download_from_flash.c b/zephyr/shim/chip/mchp/system_download_from_flash.c index 665db2cccd..99026fe822 100644 --- a/zephyr/shim/chip/mchp/system_download_from_flash.c +++ b/zephyr/shim/chip/mchp/system_download_from_flash.c @@ -10,6 +10,10 @@ #include "system_chip.h" /* Modules Map */ +#define WDT_NODE DT_INST(0, microchip_xec_watchdog) +#define STRUCT_WDT_REG_BASE_ADDR \ + ((struct wdt_regs *)(DT_REG_ADDR(WDT_NODE))) + #define PCR_NODE DT_INST(0, microchip_xec_pcr) #define STRUCT_PCR_REG_BASE_ADDR \ ((struct pcr_regs *)DT_REG_ADDR_BY_IDX(PCR_NODE, 0)) @@ -26,15 +30,15 @@ (MCHP_QMSPI_STS_DONE | MCHP_QMSPI_STS_DMA_DONE) #define QSPI_STATUS_ERR \ - (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \ + (MCHP_QMSPI_STS_TXB_ERR | MCHP_QMSPI_STS_RXB_ERR | \ MCHP_QMSPI_STS_PROG_ERR | MCHP_QMSPI_STS_LDMA_RX_ERR) - noreturn void __keep __attribute__ ((section(".code_in_sram2"))) __start_qspi(uint32_t resetVectAddr) { struct pcr_regs *pcr = STRUCT_PCR_REG_BASE_ADDR; struct qmspi_regs *qspi = STRUCT_QSPI_REG_BASE_ADDR; + struct wdt_regs *wdt = STRUCT_WDT_REG_BASE_ADDR; uint32_t qsts = 0; uint32_t exeAddr = 0; @@ -47,6 +51,9 @@ __start_qspi(uint32_t resetVectAddr) break; } + /* Stop the watchdog */ + wdt->CTRL &= ~MCHP_WDT_CTRL_EN; + qspi->MODE &= ~(MCHP_QMSPI_M_ACTIVATE); if (qsts & QSPI_STATUS_ERR) { pcr->SYS_RST |= MCHP_PCR_SYS_RESET_NOW; @@ -67,8 +74,7 @@ __start_qspi(uint32_t resetVectAddr) ; } -/* PK SCM */ -uintptr_t __lfw_sram_start = 0x127800; +uintptr_t __lfw_sram_start = CONFIG_CROS_EC_RAM_BASE + CONFIG_CROS_EC_RAM_SIZE; typedef void (*START_QSPI_IN_SRAM_FP)(uint32_t); @@ -85,9 +91,9 @@ void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr, /* Check valid address for jumpiing */ __ASSERT_NO_MSG(exeAddr != 0x0); - + /* Configure QMSPI controller */ qspi->MODE = MCHP_QMSPI_M_SRST; - fdiv = 4; + fdiv = 2; if (pcr->TURBO_CLK & MCHP_PCR_TURBO_CLK_96M) fdiv *= 2; diff --git a/zephyr/shim/chip/mchp/system_external_storage.c b/zephyr/shim/chip/mchp/system_external_storage.c index 2c7312db3a..c326a07328 100644 --- a/zephyr/shim/chip/mchp/system_external_storage.c +++ b/zephyr/shim/chip/mchp/system_external_storage.c @@ -4,13 +4,35 @@ */ #include <zephyr/devicetree.h> -#include <zephyr/drivers/syscon.h> +#include <zephyr/drivers/bbram.h> +#include <soc.h> #include "clock_chip.h" #include "common.h" #include "system.h" #include "system_chip.h" +#include "config_chip.h" +#define MCHP_ECRO_WORD 0x4F524345u /* ASCII ECRO */ +#define MCHP_ECRW_WORD 0x57524345u /* ASCII ECRW */ +#define MCHP_PCR_NODE DT_INST(0, microchip_xec_pcr) + +#define GET_BBRAM_OFS(node) \ + DT_PROP(DT_PATH(named_bbram_regions, node), offset) +#define GET_BBRAM_SZ(node) DT_PROP(DT_PATH(named_bbram_regions, node), size) + +static const struct device *const bbram_dev = + COND_CODE_1(DT_HAS_CHOSEN(cros_ec_bbram), + DEVICE_DT_GET(DT_CHOSEN(cros_ec_bbram)), NULL); + +/* Build image type string in RO/RW image */ +#ifdef CONFIG_CROS_EC_RO +const uint32_t mchp_image_type = MCHP_ECRO_WORD; +#elif CONFIG_CROS_EC_RW +const uint32_t mchp_image_type = MCHP_ECRW_WORD; +#else +#error "Unsupported image type!" +#endif /* * Make sure CONFIG_XXX flash offsets are correct for MEC172x 512KB SPI flash. @@ -29,19 +51,12 @@ void system_jump_to_booter(void) 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; + flash_used = CONFIG_CROS_EC_RW_SIZE; break; -#endif case EC_IMAGE_RO: default: /* Jump to RO by default */ - flash_offset = 0x100; /* 256 bytes */ - flash_used = (352 * 1024); + flash_offset = CONFIG_PLATFORM_EC_RO_HEADER_OFFSET; + flash_used = CONFIG_CROS_EC_RO_SIZE; break; } @@ -53,9 +68,11 @@ void system_jump_to_booter(void) /* MCHP Read selected image from SPI flash into SRAM * Need a jump to little-fw (LFW). - * MEC172x Boot-ROM load API is probably not usuable for this. */ - system_download_from_flash(flash_offset, 0xC0000u, flash_used, 0xC0004); + system_download_from_flash(flash_offset, + CONFIG_CROS_EC_PROGRAM_MEMORY_BASE, + flash_used, + (CONFIG_CROS_EC_PROGRAM_MEMORY_BASE + 4u)); } uint32_t system_get_lfw_address(void) @@ -66,13 +83,51 @@ uint32_t system_get_lfw_address(void) enum ec_image system_get_shrspi_image_copy(void) { - return EC_IMAGE_RO; + enum ec_image img = EC_IMAGE_UNKNOWN; + uint32_t value = 0u; + + if (bbram_dev) { + if (!bbram_read(bbram_dev, GET_BBRAM_OFS(ec_img_load), + GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value)) { + img = (enum ec_image)(value & 0x7fu); + } + } + + if (img == EC_IMAGE_UNKNOWN) { + img = EC_IMAGE_RO; + if (mchp_image_type == MCHP_ECRW_WORD) { + img = EC_IMAGE_RW; + } + system_set_image_copy(img); + } + + return img; } -/* - * This configures HW to point to EC_RW or EC_RO. +/* Flash is not memory mapped. Store a flag indicating the image. + * ECS WDT_CNT is register available to applications. It implements bits[3:0] + * which are not reset by a watch dog event only by VTR/chip reset. + * VBAT memory is safer only if the board has a stable VBAT power rail. */ void system_set_image_copy(enum ec_image copy) { - /* TODO(b/226599277): check if further development is requested */ + uint32_t value = (uint32_t)copy; + + if (!bbram_dev) { + return; + } + + switch (copy) { + case EC_IMAGE_RW: + case EC_IMAGE_RW_B: + value = EC_IMAGE_RW; + break; + case EC_IMAGE_RO: + default: + value = EC_IMAGE_RO; + break; + } + + bbram_write(bbram_dev, GET_BBRAM_OFS(ec_img_load), + GET_BBRAM_SZ(ec_img_load), (uint8_t *)&value); } diff --git a/zephyr/shim/src/watchdog.c b/zephyr/shim/src/watchdog.c index afb385054b..00cd5c4c30 100644 --- a/zephyr/shim/src/watchdog.c +++ b/zephyr/shim/src/watchdog.c @@ -27,6 +27,11 @@ static void wdt_warning_handler(const struct device *wdt_dev, int channel_id) #ifdef TEST_BUILD wdt_warning_triggered = true; #endif +#ifdef CONFIG_SOC_SERIES_MEC172X + extern void cros_chip_wdt_handler(const struct device *wdt_dev, + int channel_id); + cros_chip_wdt_handler(wdt_dev, channel_id); +#endif } int watchdog_init(void) |