Skip to content

Commit

Permalink
Merge pull request wolfSSL#464 from MulattoKid/flexspi_safe
Browse files Browse the repository at this point in the history
Fix DCache not being invalidated after erasing/writing to flash on i.MX RT10xx
  • Loading branch information
dgarske authored Jul 3, 2024
2 parents f60de60 + 83359a2 commit 40ccd9e
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 45 deletions.
14 changes: 10 additions & 4 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO_DRIVERS) \
-I$(MCUXPRESSO_DRIVERS)/drivers \
-I$(MCUXPRESSO)/drivers \
-I$(MCUXPRESSO)/drivers/cache/armv7-m7 \
-I$(MCUXPRESSO)/drivers/common \
-I$(MCUXPRESSO)/drivers/flexspi \
-I$(MCUXPRESSO)/drivers/lpuart \
Expand All @@ -405,7 +406,8 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO)/utilities/debug_console
OBJS+=\
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
$(MCUXPRESSO)/drivers/flexspi/fsl_flexspi.o
$(MCUXPRESSO)/drivers/flexspi/fsl_flexspi.o \
$(MCUXPRESSO)/drivers/cache/armv7-m7/fsl_cache.o
ifeq ($(DEBUG_UART),1)
OBJS+= $(MCUXPRESSO)/drivers/lpuart/fsl_lpuart.o
endif
Expand All @@ -415,7 +417,8 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO_DRIVERS)/utilities/debug_console
OBJS+=\
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_flexspi.o
$(MCUXPRESSO_DRIVERS)/drivers/fsl_flexspi.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_cache.o
ifeq ($(DEBUG_UART),1)
OBJS+= $(MCUXPRESSO_DRIVERS)/drivers/fsl_lpuart.o
endif
Expand All @@ -431,6 +434,11 @@ ifeq ($(TARGET),imx_rt)
CFLAGS+=-I$(MCUXPRESSO)/boards/evkmimxrt1060/xip/
endif

ifeq ($(MCUXPRESSO_CPU),MIMXRT1062DVL6B)
ARCH_FLASH_OFFSET=0x60000000
CFLAGS+=-I$(MCUXPRESSO)/boards/evkbmimxrt1060/xip/
endif

ifeq ($(MCUXPRESSO_CPU),MIMXRT1061CVJ5B)
ARCH_FLASH_OFFSET=0x60000000
CFLAGS+=-I$(MCUXPRESSO)/boards/evkmimxrt1060/xip/
Expand All @@ -448,10 +456,8 @@ ifeq ($(TARGET),imx_rt)

ifeq ($(PKA),1)
ifeq ($(MCUXSDK),1)
PKA_EXTRA_OBJS+= $(MCUXPRESSO)/drivers/cache/armv7-m7/fsl_cache.o
PKA_EXTRA_OBJS+= $(MCUXPRESSO)/drivers/dcp/fsl_dcp.o
else
PKA_EXTRA_OBJS+= $(MCUXPRESSO_DRIVERS)/drivers/fsl_cache.o
PKA_EXTRA_OBJS+= $(MCUXPRESSO_DRIVERS)/drivers/fsl_dcp.o
endif
PKA_EXTRA_OBJS+=./lib/wolfssl/wolfcrypt/src/port/nxp/dcp_port.o
Expand Down
65 changes: 36 additions & 29 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -1379,15 +1379,19 @@ wolfBoot support for iMX-RT1060/iMX-RT1050 has been tested using MCUXpresso SDK

DCP support (hardware acceleration for SHA256 operations) can be enabled by using PKA=1 in the configuration file.

Firmware can be directly uploaded to the target by copying `factory.bin` to the virtual USB drive associated to the device, or by loading the image directly into flash using a JTAG/SWD debugger.

The RT1050 EVKB board comes wired to use the 64MB HyperFlash. If you'd like to use QSPI there is a rework that can be performed (see AN12183). The default onboard QSPI 8MB ISSI IS25WP064A (`CONFIG_FLASH_IS25WP064A`). To use a 64Mbit Winbond W25Q64JV define `CONFIG_FLASH_W25Q64JV` (16Mbit, 32Mbit, 128Mbit, 256Mbit and 512Mbit versions are also available). These options are also available for the RT1042 and RT1061 target.

You can also get the SDK and CMSIS bundles using these repositories:
* https://github.com/nxp-mcuxpresso/mcux-sdk
* https://github.com/nxp-mcuxpresso/CMSIS_5
Use MCUXSDK=1 with this option, since the pack paths are different.

Example:
```
MCUXSDK?=1
MCUXPRESSO?=$(PWD)/../mcux-sdk
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MIMXRT1062
MCUXPRESSO_CMSIS?="$(PWD)/../CMSIS_5/CMSIS"
```

### Custom Device Configuration Data (DCD)

On iMX-RT10xx it is possible to load a custom DCD section from an external
Expand All @@ -1401,58 +1405,61 @@ section, e.g.:
If an external `.dcd_data` section is provided, the option `NXP_CUSTOM_DCD=1` must
be added to the configuration.

### Flashing

### Testing Update

First make the update partition, pre-triggered for update
Firmware can be directly uploaded to the target by copying `factory.bin` to the virtual USB drive associated to the device, or by loading the image directly into flash using a JTAG/SWD debugger.

```sh
tools/scripts/prepare_update.sh
```
The RT1050 EVKB board comes wired to use the 64MB HyperFlash. If you'd like to use QSPI there is a rework that can be performed (see AN12183). The default onboard QSPI 8MB ISSI IS25WP064A (`CONFIG_FLASH_IS25WP064A`). To use a 64Mbit Winbond W25Q64JV define `CONFIG_FLASH_W25Q64JV` (16Mbit, 32Mbit, 128Mbit, 256Mbit and 512Mbit versions are also available). These options are also available for the RT1042 and RT1061 target.

Then connect to the board with JLinkExe, for the rt1040 do:
If you have updated the MCULink to use JLink then you can connect to the board with JLinkExe using one of the following commands:

```sh
# HyperFlash
JLinkExe -if swd -speed 5000 -Device "MIMXRT1042xxxxB"
JLinkExe -if swd -speed 5000 -Device "MIMXRT1052XXX6A"
JLinkExe -if swd -speed 5000 -Device "MIMXRT1062XXX6B"
# QSPI
JLinkExe -if swd -speed 5000 -Device "MIMXRT1042xxxxB?BankAddr=0x60000000&Loader=QSPI"
JLinkExe -if swd -speed 5000 -Device "MIMXRT1052XXX6A?BankAddr=0x60000000&Loader=QSPI"
JLinkExe -if swd -speed 5000 -Device "MIMXRT1062XXX6B?BankAddr=0x60000000&Loader=QSPI"
```

For the rt1050 do:
Flash using:

```sh
# HyperFlash
JLinkExe -if swd -speed 5000 -Device "MIMXRT1052XXX6A"
# QSPI
JLinkExe -if swd -speed 5000 -Device "MIMXRT1052XXX6A?BankAddr=0x60000000&Loader=QSPI"
loadbin factory.bin 0x60000000
```

For the rt-1060:
### Testing Update

First make the update partition, pre-triggered for update:

```sh
# HyperFlash
JLinkExe -if swd -speed 5000 -Device "MIMXRT1062XXX6B"
# QSPI
JLinkExe -if swd -speed 5000 -Device "MIMXRT1062XXX6B?BankAddr=0x60000000&Loader=QSPI"
./tools/scripts/prepare_update.sh
```

Now flash the board:
Run the "loadbin" commands to flash the update:

```sh
loadbin factory.bin 0x60000000
loadbin update.bin 0x60030000
```

Reboot device. Expected output:

```
wolfBoot Test app, version = 1
wolfBoot Test app, version = 8
```

### NXP iMX-RT Debugging JTAG / JLINK

```sh
# rt-1040
# Start JLink GDB server for your device
JLinkGDBServer -Device MIMXRT1042xxxxB -speed 5000 -if swd -port 3333
# rt-1050
JLinkGDBServer -Device MIMXRT1052xxx6A -speed 5000 -if swd -port 3333
# rt-1060
JLinkGDBServer -Device MIMXRT1062xxx6B -speed 5000 -if swd -port 3333

# From wolfBoot directory
arm-none-eabi-gdb
add-symbol-file test-app/image.elf 0x60010100
mon reset init
Expand Down Expand Up @@ -2214,8 +2221,8 @@ Note:
### Running on 64-bit QEMU

Two example configuration files are available: `config/examples/x86_fsp_qemu.config` and `config/examples/x86_fsp_qemu_seal.config`.
Both will try to load a 64bit ELF/Multiboot2 payload from the emulated sata drive.
The second one is an example of configuration that also do measure boot and seal/unseal secrets using a TPM.
Both will try to load a 64bit ELF/Multiboot2 payload from the emulated sata drive.
The second one is an example of configuration that also do measure boot and seal/unseal secrets using a TPM.

A test ELF/Multiboot2 image is provided as well. To test `config/examples/x86_fsp_qemu.config` use the following steps:

Expand Down Expand Up @@ -2502,7 +2509,7 @@ To compile a flashable image run the following steps:
cp config/examples/kontron_vx3060_s2.config .config
./tools/scripts/x86_fsp/tgl/tgl_download_fsp.sh
make tpmtools
./tools/scripts/x86_fsp/tgl/assemble_image.sh -k
./tools/scripts/x86_fsp/tgl/assemble_image.sh -k
make CFLAGS_EXTRA="-DHAVE_ECC256"
./tools/scripts/x86_fsp/tgl/assemble_image.sh -n /path/to/original/flash/dump
```
Expand Down
41 changes: 38 additions & 3 deletions hal/imx_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <target.h>
#include "image.h"
#include "printf.h"
#include "fsl_cache.h"
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "fsl_nor_flash.h"
Expand All @@ -42,6 +43,10 @@
#include "evkmimxrt1060_flexspi_nor_config.h"
#define USE_GET_CONFIG
#endif
#ifdef CPU_MIMXRT1062DVL6B
#include "evkbmimxrt1060_flexspi_nor_config.h"
#define USE_GET_CONFIG
#endif
#ifdef CPU_MIMXRT1061CVJ5B
#include "evkmimxrt1060_flexspi_nor_config.h"
#endif
Expand Down Expand Up @@ -261,7 +266,7 @@ const flexspi_nor_config_t FLASH_CONFIG_SECTION qspiflash_config = {


/** Flash configuration in the .flash_config section of flash **/
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
#define CONFIG_FLASH_SIZE (8 * 1024 * 1024) /* 8MBytes */
#define CONFIG_FLASH_PAGE_SIZE 256UL /* 256Bytes */
#define CONFIG_FLASH_SECTOR_SIZE (4 * 1024) /* 4KBytes */
Expand Down Expand Up @@ -589,7 +594,10 @@ const flexspi_nor_config_t FLASH_CONFIG_SECTION qspiflash_config = {


#ifndef __FLASH_BASE
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1061CVJ5B) || defined(CPU_MIMXRT1052DVJ6B) || defined(CPU_MIMXRT1042XJM5B)
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B) || \
defined(CPU_MIMXRT1061CVJ5B) || \
defined(CPU_MIMXRT1052DVJ6B) || \
defined(CPU_MIMXRT1042XJM5B)
#define __FLASH_BASE 0x60000000
#elif defined(CPU_MIMXRT1064DVL6A)
#define __FLASH_BASE 0x70000000
Expand Down Expand Up @@ -708,7 +716,9 @@ static void clock_init(void)
CCM_CBCDR_AHB_PODF(2) |
CCM_CBCDR_IPG_PODF(2);

#if defined(CPU_MIMXRT1064DVL6A) || defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1061CVJ5B)
#if defined(CPU_MIMXRT1064DVL6A) || \
defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B) || \
defined(CPU_MIMXRT1061CVJ5B)
/* Configure FLEXSPI2 CLOCKS */
CCM->CBCMR =
(CCM->CBCMR &
Expand Down Expand Up @@ -861,13 +871,27 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
wolfBoot_printf("flash write: addr 0x%x, len %d\n",
address - FLASH_BASE, len);
#endif
/**
* Disable interrupts before accessing flash when using XIP
* (note 4 p.279 in i.MX RT1060 Processor Reference Manual, Rev. 3, 07/2021)
*/
asm volatile("cpsid i");
for (i = 0; i < len; i+= CONFIG_FLASH_PAGE_SIZE) {
memcpy(wbuf, data + i, CONFIG_FLASH_PAGE_SIZE);
status = g_bootloaderTree->flexSpiNorDriver->program(0, FLEXSPI_CONFIG,
(address + i) - FLASH_BASE, wbuf);
/**
* Flash is memory mapped, so the address range must be invalidated in data cache
* to ensure coherency between flash and cache
*/
DCACHE_InvalidateByRange(address + i, sizeof(wbuf));
if (status != kStatus_Success)
{
asm volatile("cpsie i");
return -1;
}
}
asm volatile("cpsie i");
return 0;
}

Expand All @@ -887,8 +911,19 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
wolfBoot_printf("flash erase: addr 0x%x, len %d\n",
address - FLASH_BASE, len);
#endif
/**
* Disable interrupts before accessing flash when using XIP
* (note 4 p.279 in i.MX RT1060 Processor Reference Manual, Rev. 3, 07/2021)
*/
asm volatile("cpsid i");
status = g_bootloaderTree->flexSpiNorDriver->erase(0, FLEXSPI_CONFIG,
address - FLASH_BASE, len);
/**
* Flash is memory mapped, so the address range must be invalidated in data cache
* to ensure coherency between flash and cache
*/
DCACHE_InvalidateByRange(address, len);
asm volatile("cpsie i");
if (status != kStatus_Success)
return -1;
return 0;
Expand Down
7 changes: 7 additions & 0 deletions test-app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ ifeq ($(TARGET),imx_rt)
ifeq ($(MCUXSDK),1)
APP_OBJS+=\
$(MCUXPRESSO)/drivers/igpio/fsl_gpio.o \
$(MCUXPRESSO)/drivers/cache/armv7-m7/fsl_cache.o \
$(MCUXPRESSO)/drivers/common/fsl_common.o \
$(MCUXPRESSO)/drivers/common/fsl_common_arm.o \
$(MCUXPRESSO)/drivers/flexspi/fsl_flexspi.o \
Expand All @@ -271,6 +272,7 @@ ifeq ($(TARGET),imx_rt)
else
APP_OBJS+=\
$(MCUXPRESSO_DRIVERS)/drivers/fsl_gpio.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_cache.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_common.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_common_arm.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_flexspi.o \
Expand All @@ -293,6 +295,11 @@ ifeq ($(TARGET),imx_rt)
-I$(MCUXPRESSO)/boards/evkmimxrt1060/xip/
APP_OBJS+=$(MCUXPRESSO_DRIVERS)/system_MIMXRT1062.o
endif
ifeq ($(MCUXPRESSO_CPU),MIMXRT1062DVL6B)
CFLAGS+=-I$(MCUXPRESSO_DRIVERS)/project_template/ \
-I$(MCUXPRESSO)/boards/evkbmimxrt1060/xip/
APP_OBJS+=$(MCUXPRESSO_DRIVERS)/system_MIMXRT1062.o
endif
ifeq ($(MCUXPRESSO_CPU),MIMXRT1064DVL6A)
CFLAGS+=-I$(MCUXPRESSO_DRIVERS)/project_template/ \
-I$(MCUXPRESSO)/boards/evkmimxrt1064/xip/
Expand Down
6 changes: 4 additions & 2 deletions test-app/app_imx_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ void init_debug_console(void)
DbgConsole_Init(UART_INSTANCE, UART_BAUDRATE, UART_TYPE, uartClkSrcFreq);
}

#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A)
#if defined(CPU_MIMXRT1064DVL6A) || \
defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Pin settings (same for both 1062 and 1064) */
void rt1060_init_pins(void)
{
Expand Down Expand Up @@ -151,7 +152,8 @@ void rt1040_init_pins(void)
void main(void)
{
imx_rt_init_boot_clock();
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1064DVL6A)
#if defined(CPU_MIMXRT1064DVL6A) || \
defined(CPU_MIMXRT1062DVL6A) || defined(MIMXRT1062DVL6B)
rt1060_init_pins();
#elif defined(CPU_MIMXRT1052DVJ6B)
rt1050_init_pins();
Expand Down
14 changes: 7 additions & 7 deletions test-app/imx_rt_clock_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,21 @@ void imx_rt_init_boot_clock(void)
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
/* Disable Flexspi clock gate. */
CLOCK_DisableClock(kCLOCK_FlexSpi);
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Set FLEXSPI_PODF. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 1);
/* Set Flexspi clock source. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
#endif
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Set FLEXSPI_PODF. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);
/* Set Flexspi clock source. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 1);
#endif
#endif

#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Disable Flexspi2 clock gate. */
CLOCK_DisableClock(kCLOCK_FlexSpi2);
/* Set FLEXSPI2_PODF. */
Expand Down Expand Up @@ -214,12 +214,12 @@ void imx_rt_init_boot_clock(void)
/* Disable CAN clock gate. */
CLOCK_DisableClock(kCLOCK_Can1);
CLOCK_DisableClock(kCLOCK_Can2);
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
CLOCK_DisableClock(kCLOCK_Can3);
#endif
CLOCK_DisableClock(kCLOCK_Can1S);
CLOCK_DisableClock(kCLOCK_Can2S);
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
CLOCK_DisableClock(kCLOCK_Can3S);
#endif
/* Set CAN_CLK_PODF. */
Expand Down Expand Up @@ -346,7 +346,7 @@ void imx_rt_init_boot_clock(void)
CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1);
/* Enable Enet output. */
CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Set Enet2 output divider. */
CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_ENET2_DIV_SELECT(0);
/* Enable Enet2 output. */
Expand Down Expand Up @@ -400,7 +400,7 @@ void imx_rt_init_boot_clock(void)
IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0);
/* Set ENET1 Tx clock source. */
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false);
#ifdef CPU_MIMXRT1062DVL6A
#if defined(CPU_MIMXRT1062DVL6A) || defined(CPU_MIMXRT1062DVL6B)
/* Set ENET2 Tx clock source. */
#if defined(FSL_IOMUXC_DRIVER_VERSION) && (FSL_IOMUXC_DRIVER_VERSION != (MAKE_VERSION(2, 0, 0)))
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET2RefClkMode, false);
Expand Down

0 comments on commit 40ccd9e

Please sign in to comment.