From f3dba7f80caccadb9938e6488b7878f096d4baf3 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Fri, 4 Jun 2021 11:44:29 -0600 Subject: zephyr: npcx9: implement system_download_from_flash BRANCH=none BUG=b:188605676 TEST=run `sysjump RW` on brya Signed-off-by: Yuval Peress Change-Id: Ic771a0452cd044355dd2a0e0f32fa6e2d3711a44 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2936009 Reviewed-by: Keith Short --- zephyr/shim/chip/npcx/include/system_chip.h | 6 ++ zephyr/shim/chip/npcx/system_download_from_flash.c | 106 ++++++++++++++++++++- zephyr/shim/chip/npcx/system_external_storage.c | 3 +- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/zephyr/shim/chip/npcx/include/system_chip.h b/zephyr/shim/chip/npcx/include/system_chip.h index 44a60b47b5..c77c2a8338 100644 --- a/zephyr/shim/chip/npcx/include/system_chip.h +++ b/zephyr/shim/chip/npcx/include/system_chip.h @@ -58,6 +58,12 @@ void system_mpu_config(void); /* The utilities and variables depend on npcx chip family */ #if defined(CONFIG_SOC_SERIES_NPCX5) || \ defined(CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API) +/* Bypass for GMDA issue of ROM api utilities only on npcx5 series or if + * CONFIG_PLATFORM_EC_WORKAROUND_FLASH_DOWNLOAD_API is defined. + */ +void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr, + uint32_t size, uint32_t exeAddr); + /* Begin address for hibernate utility; defined in linker script */ extern unsigned int __flash_lpfw_start; diff --git a/zephyr/shim/chip/npcx/system_download_from_flash.c b/zephyr/shim/chip/npcx/system_download_from_flash.c index 9e80df8f2d..bf50f736cd 100644 --- a/zephyr/shim/chip/npcx/system_download_from_flash.c +++ b/zephyr/shim/chip/npcx/system_download_from_flash.c @@ -3,11 +3,13 @@ * found in the LICENSE file. */ #include +#include #include "common.h" #include "system_chip.h" /* Modules Map */ +#define NPCX_PMC_BASE_ADDR 0x4000D000 #define NPCX_GDMA_BASE_ADDR 0x40011000 /******************************************************************************/ @@ -15,6 +17,7 @@ #define NPCX_GDMA_CTL REG32(NPCX_GDMA_BASE_ADDR + 0x000) #define NPCX_GDMA_SRCB REG32(NPCX_GDMA_BASE_ADDR + 0x004) #define NPCX_GDMA_DSTB REG32(NPCX_GDMA_BASE_ADDR + 0x008) +#define NPCX_GDMA_TCNT REG32(NPCX_GDMA_BASE_ADDR + 0x00C) /******************************************************************************/ /* GDMA register fields */ @@ -33,6 +36,29 @@ #define NPCX_GDMA_CTL_GDMAERR 20 #define NPCX_GDMA_CTL_BLOCK_BUG_CORRECTION_DISABLE 26 +/******************************************************************************/ +/* Low Power RAM definitions */ +#define NPCX_LPRAM_CTRL REG32(0x40001044) + +/******************************************************************************/ +/* Power Management Controller (PMC) Registers */ +#define NPCX_PWDWN_CTL_ADDR(offset) (((offset) < 6) ? \ + (NPCX_PMC_BASE_ADDR + 0x008 + (offset)) : \ + (NPCX_PMC_BASE_ADDR + 0x024)) +#define NPCX_PWDWN_CTL(offset) REG8(NPCX_PWDWN_CTL_ADDR(offset)) + +/* PMC enumeration */ +enum NPCX_PMC_PWDWN_CTL_T { + NPCX_PMC_PWDWN_1 = 0, + NPCX_PMC_PWDWN_2 = 1, + NPCX_PMC_PWDWN_3 = 2, + NPCX_PMC_PWDWN_4 = 3, + NPCX_PMC_PWDWN_5 = 4, + NPCX_PMC_PWDWN_6 = 5, + NPCX_PMC_PWDWN_7 = 6, + NPCX_PMC_PWDWN_CNT, +}; + /* Sysjump utilities in low power ram for npcx series. */ noreturn void __keep __attribute__ ((section(".lowpower_ram2"))) __start_gdma(uint32_t exeAddr) @@ -68,4 +94,82 @@ __start_gdma(uint32_t exeAddr) /* Should never get here */ while (1) ; -} \ No newline at end of file +} + +/* Begin address of Suspend RAM for little FW (GDMA utilities). */ +#define LFW_OFFSET 0x160 +uintptr_t __lpram_lfw_start = CONFIG_LPRAM_BASE + LFW_OFFSET; + +void system_download_from_flash(uint32_t srcAddr, uint32_t dstAddr, + uint32_t size, uint32_t exeAddr) +{ + int i; + uint8_t chunkSize = 16; /* 4 data burst mode. ie.16 bytes */ + /* + * GDMA utility in Suspend RAM. Setting bit 0 of address to indicate + * it's a thumb branch for cortex-m series CPU. + */ + void (*__start_gdma_in_lpram)(uint32_t) = + (void(*)(uint32_t))(__lpram_lfw_start | 0x01); + + /* + * Before enabling burst mode for better performance of GDMA, it's + * important to make sure srcAddr, dstAddr and size of transactions + * are 16 bytes aligned in case failure occurs. + */ + __ASSERT_NO_MSG((size % chunkSize) == 0 && (srcAddr % chunkSize) == 0 && + (dstAddr % chunkSize) == 0); + + /* Check valid address for jumpiing */ + __ASSERT_NO_MSG(exeAddr != 0x0); + + /* Enable power for the Low Power RAM */ + CLEAR_BIT(NPCX_PWDWN_CTL(NPCX_PMC_PWDWN_6), 6); + + /* Enable Low Power RAM */ + NPCX_LPRAM_CTRL = 1; + + /* + * Initialize GDMA for flash reading. + * [31:21] - Reserved. + * [20] - GDMAERR = 0 (Indicate GMDA transfer error) + * [19] - Reserved. + * [18] - TC = 0 (Terminal Count. Indicate operation is end.) + * [17] - Reserved. + * [16] - SOFTREQ = 0 (Don't trigger here) + * [15] - DM = 0 (Set normal demand mode) + * [14] - Reserved. + * [13:12] - TWS. = 10 (One double-word for every GDMA transaction) + * [11:10] - Reserved. + * [9] - BME = 1 (4-data ie.16 bytes - Burst mode enable) + * [8] - SIEN = 0 (Stop interrupt disable) + * [7] - SAFIX = 0 (Fixed source address) + * [6] - Reserved. + * [5] - SADIR = 0 (Source address incremented) + * [4] - DADIR = 0 (Destination address incremented) + * [3:2] - GDMAMS = 00 (Software mode) + * [1] - Reserved. + * [0] - ENABLE = 0 (Don't enable yet) + */ + NPCX_GDMA_CTL = 0x00002200; + + /* Set source base address */ + NPCX_GDMA_SRCB = CONFIG_MAPPED_STORAGE_BASE + srcAddr; + + /* Set destination base address */ + NPCX_GDMA_DSTB = dstAddr; + + /* Set number of transfers */ + NPCX_GDMA_TCNT = (size / chunkSize); + + /* Clear Transfer Complete event */ + SET_BIT(NPCX_GDMA_CTL, NPCX_GDMA_CTL_TC); + + /* Copy the __start_gdma_in_lpram instructions to LPRAM */ + for (i = 0; i < &__flash_lplfw_end - &__flash_lplfw_start; i++) + *((uint32_t *)__lpram_lfw_start + i) = + *(&__flash_lplfw_start + i); + + /* Start GDMA in Suspend RAM */ + __start_gdma_in_lpram(exeAddr); +} diff --git a/zephyr/shim/chip/npcx/system_external_storage.c b/zephyr/shim/chip/npcx/system_external_storage.c index 4b77a3972f..b53db04e18 100644 --- a/zephyr/shim/chip/npcx/system_external_storage.c +++ b/zephyr/shim/chip/npcx/system_external_storage.c @@ -65,7 +65,8 @@ void system_jump_to_booter(void) * 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) +#if defined(CONFIG_SOC_SERIES_NPCX5) || \ + defined(CONFIG_PLATFORM_EC_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 */ -- cgit v1.2.1