From ac6060f966334591e2a23457efedd60854ab54fa Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Thu, 17 Feb 2022 13:04:00 +0100 Subject: [PATCH] code_relocation: Extend the nocopy sample to nRF5340dk The nRF5340dk is shipping an external QSPI flash that can be used to do XIP from. Extend the code_relocation nocopy sample to support this platform so that part of the functions are executed from internal flash and others from external flash. Signed-off-by: Carlo Caione --- .../code_relocation_nocopy/CMakeLists.txt | 1 + .../code_relocation_nocopy/README.rst | 33 ++++++ .../boards/nrf5340dk_nrf5340_cpuapp.conf | 3 + .../nrf5340dk_nrf5340_cpuapp/ext_mem_init.c | 112 ++++++++++++++++++ .../linker_arm_nocopy.ld | 15 +++ .../code_relocation_nocopy/prj.conf | 1 + .../code_relocation_nocopy/sample.yaml | 2 +- .../code_relocation_nocopy/src/main.c | 8 +- 8 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c diff --git a/samples/application_development/code_relocation_nocopy/CMakeLists.txt b/samples/application_development/code_relocation_nocopy/CMakeLists.txt index 5759dd1c9e3..6e9a6f365b2 100644 --- a/samples/application_development/code_relocation_nocopy/CMakeLists.txt +++ b/samples/application_development/code_relocation_nocopy/CMakeLists.txt @@ -7,6 +7,7 @@ project(code_relocation_nocopy) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) +target_sources_ifdef(CONFIG_NRFX_QSPI app PRIVATE boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c) # Run ext_code from the external flash (XIP). No need to copy. zephyr_code_relocate(src/ext_code.c EXTFLASH_TEXT NOCOPY) diff --git a/samples/application_development/code_relocation_nocopy/README.rst b/samples/application_development/code_relocation_nocopy/README.rst index 1a55ca2bfe0..8ace0988aa8 100644 --- a/samples/application_development/code_relocation_nocopy/README.rst +++ b/samples/application_development/code_relocation_nocopy/README.rst @@ -11,3 +11,36 @@ using a custom linker script. Differently from the code relocation sample, this sample is relocating the content of the ext_code.c file to a different FLASH section and the code is XIP directly from there without the need to copy / relocate the code. + +nRF5340dk platform instructions +******************************* + +The nRF5340 PDK has a 64 Mb external flash memory supporting Quad SPI. It is +possible to do XIP from the external flash memory. + +The external flash memory is mapped to 0x10000000. + +In this sample we relocate some of the code to the external flash memory with +the remaining Zephyr kernel in the internal flash. + +Compile the code: + $ west build -b nrf5340dk_nrf5340_cpuapp samples/application_development/code_relocation_nocopy --pristine + +Get the HEX file from the ELF: + $ arm-linux-gnueabihf-objcopy -O ihex build/zephyr/zephyr.elf zephyr.hex + +Erase the external FLASH (just to be sure): + $ nrfjprog --qspicustominit --qspieraseall + +Write the HEX to internal and external FLASH: + $ nrfjprog --coprocessor CP_APPLICATION --sectorerase --qspisectorerase --program zephyr.hex + +Execution output: + + *** Booting Zephyr OS build v3.0.0-rc3-25-g0df32cec1ff2 *** + Address of main function 0x4f9 + Address of function_in_ext_flash 0x10000001 + Address of var_ext_sram_data 0x200000a0 (10) + Address of function_in_sram 0x20000001 + Address of var_sram_data 0x200000a4 (10) + Hello World! nrf5340dk_nrf5340_cpuapp diff --git a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..c0f73f34517 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,3 @@ +CONFIG_NRFX_QSPI=y +CONFIG_GPIO=y +CONFIG_NRF_ENABLE_CACHE=n diff --git a/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c new file mode 100644 index 00000000000..6527d5861a3 --- /dev/null +++ b/samples/application_development/code_relocation_nocopy/boards/nrf5340dk_nrf5340_cpuapp/ext_mem_init.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define QSPI_STD_CMD_WRSR 0x01 +#define QSPI_STD_CMD_WRDI 0x04 +#define QSPI_STD_CMD_RSTEN 0x66 +#define QSPI_STD_CMD_RST 0x99 + +#define QSPI_NODE DT_NODELABEL(qspi) +#define QSPI_PROP_AT(prop, idx) DT_PROP_BY_IDX(QSPI_NODE, prop, idx) + +static inline int qspi_get_zephyr_ret_code(nrfx_err_t res) +{ + switch (res) { + case NRFX_SUCCESS: + return 0; + case NRFX_ERROR_INVALID_PARAM: + case NRFX_ERROR_INVALID_ADDR: + return -EINVAL; + case NRFX_ERROR_INVALID_STATE: + return -ECANCELED; + case NRFX_ERROR_BUSY: + case NRFX_ERROR_TIMEOUT: + default: + return -EBUSY; + } +} + +static int qspi_ext_mem_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + int ret; + + nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_1); + + static nrfx_qspi_config_t qspi_config = { + .pins = { + .sck_pin = DT_PROP(QSPI_NODE, sck_pin), + .csn_pin = QSPI_PROP_AT(csn_pins, 0), + .io0_pin = QSPI_PROP_AT(io_pins, 0), + .io1_pin = QSPI_PROP_AT(io_pins, 1), + .io2_pin = QSPI_PROP_AT(io_pins, 2), + .io3_pin = QSPI_PROP_AT(io_pins, 3), + }, + .irq_priority = NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY, + .prot_if = { + .readoc = NRF_QSPI_READOC_READ4IO, + .writeoc = NRF_QSPI_WRITEOC_PP4IO, + .addrmode = NRF_QSPI_ADDRMODE_24BIT, + .dpmconfig = false + }, + .phy_if = { + .sck_freq = 1, + .sck_delay = 0x05, + .spi_mode = NRF_QSPI_MODE_0, + .dpmen = false + } + }; + + nrfx_err_t res = nrfx_qspi_init(&qspi_config, NULL, NULL); + + ret = qspi_get_zephyr_ret_code(res); + if (ret < 0) { + return ret; + } + + /* Enable XiP */ + nrf_qspi_xip_set(NRF_QSPI, true); + + uint8_t temporary = 0x40; + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = QSPI_STD_CMD_RSTEN, + .length = NRF_QSPI_CINSTR_LEN_1B, + .io2_level = true, + .io3_level = true, + .wipwait = true, + .wren = true + }; + + /* Send reset enable */ + nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + + /* Send reset command */ + cinstr_cfg.opcode = QSPI_STD_CMD_RST; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + + /* Switch to qspi mode and high performance */ + cinstr_cfg.opcode = QSPI_STD_CMD_WRSR; + cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL); + + /* Send write disable command */ + cinstr_cfg.opcode = QSPI_STD_CMD_WRDI; + cinstr_cfg.wren = false; + cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_1B; + nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + + return 0; +} + +SYS_INIT(qspi_ext_mem_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); diff --git a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld index 8520525e119..f06371614ca 100644 --- a/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld +++ b/samples/application_development/code_relocation_nocopy/linker_arm_nocopy.ld @@ -18,6 +18,19 @@ #include #include +#if CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP + +/* + * nRF5340dk is shipping a QSPI external flash mapped at 0x1000_0000 that can + * be used for XIP + */ +MEMORY +{ + EXTFLASH (wx) : ORIGIN = 0x10000000, LENGTH = 0x800000 +} + +#else + /* * Add another fake portion of FLASH to simulate a secondary or external FLASH * that we can do XIP from. @@ -30,4 +43,6 @@ MEMORY EXTFLASH (wx) : ORIGIN = 0x5000, LENGTH = EXTFLASH_SIZE } +#endif /* CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP */ + #include diff --git a/samples/application_development/code_relocation_nocopy/prj.conf b/samples/application_development/code_relocation_nocopy/prj.conf index 22d46057bee..b58ecd6ee94 100644 --- a/samples/application_development/code_relocation_nocopy/prj.conf +++ b/samples/application_development/code_relocation_nocopy/prj.conf @@ -3,3 +3,4 @@ CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_nocopy.ld" CONFIG_COVERAGE=n CONFIG_XIP=y +CONFIG_LOG=y diff --git a/samples/application_development/code_relocation_nocopy/sample.yaml b/samples/application_development/code_relocation_nocopy/sample.yaml index e200c338525..28e24de8a98 100644 --- a/samples/application_development/code_relocation_nocopy/sample.yaml +++ b/samples/application_development/code_relocation_nocopy/sample.yaml @@ -3,7 +3,7 @@ sample: name: code relocation nocopy tests: sample.application_development.code_relocation_nocopy: - platform_allow: qemu_cortex_m3 + platform_allow: qemu_cortex_m3 nrf5340dk_nrf5340_cpuapp tags: linker harness: console harness_config: diff --git a/samples/application_development/code_relocation_nocopy/src/main.c b/samples/application_development/code_relocation_nocopy/src/main.c index 8544e58e16b..c151916c2ca 100644 --- a/samples/application_development/code_relocation_nocopy/src/main.c +++ b/samples/application_development/code_relocation_nocopy/src/main.c @@ -27,12 +27,18 @@ void disable_mpu_rasr_xn(void) */ for (index = 0U; index < 8; index++) { MPU->RNR = index; +#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) + if (MPU->RBAR & MPU_RBAR_XN_Msk) { + MPU->RBAR ^= MPU_RBAR_XN_Msk; + } +#else if (MPU->RASR & MPU_RASR_XN_Msk) { MPU->RASR ^= MPU_RASR_XN_Msk; } +#endif /* CONFIG_ARMV8_M_BASELINE || CONFIG_ARMV8_M_MAINLINE */ } } -#endif /* CONFIG_ARM_MPU */ +#endif /* CONFIG_ARM_MPU */ extern void function_in_ext_flash(void); extern void function_in_sram(void);