diff --git a/config/examples/renesas-rx65n.config b/config/examples/renesas-rx65n.config index 38909bb6d..64eb33d14 100644 --- a/config/examples/renesas-rx65n.config +++ b/config/examples/renesas-rx65n.config @@ -14,7 +14,7 @@ ALLOW_DOWNGRADE?=0 NVM_FLASH_WRITEONCE?=0 WOLFBOOT_VERSION?=0 SPMATH?=1 -RAM_CODE?=0 +RAM_CODE?=1 DUALBANK_SWAP?=0 # reserve 1KB for wolfBoot header diff --git a/config/examples/renesas-rx72n.config b/config/examples/renesas-rx72n.config index 14d9437a9..971fedc29 100644 --- a/config/examples/renesas-rx72n.config +++ b/config/examples/renesas-rx72n.config @@ -14,7 +14,7 @@ ALLOW_DOWNGRADE?=0 NVM_FLASH_WRITEONCE?=0 WOLFBOOT_VERSION?=0 SPMATH?=1 -RAM_CODE?=0 +RAM_CODE?=1 DUALBANK_SWAP?=0 # reserve 1KB for wolfBoot header @@ -24,8 +24,8 @@ DUALBANK_SWAP?=0 # Optionally switch to big endian data if MDE is set #BIG_ENDIAN=1 -# Flash is 4MB with 64KB sector size -WOLFBOOT_SECTOR_SIZE?=0x10000 +# Flash is 4MB with 32KB sector size +WOLFBOOT_SECTOR_SIZE?=0x8000 # wolfBoot is last sector of flash and includes vector tables WOLFBOOT_ORIGIN=0xFFFF0000 diff --git a/docs/Targets.md b/docs/Targets.md index c1743795c..1fe084617 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2195,7 +2195,7 @@ Current Firmware Version: 1 Hit any key to call wolfBoot_success the firmware. ``` -Default Onboard Flash Memory Layout (4MB) (64KB sector): +Default Onboard Flash Memory Layout (4MB) (32KB sector): | Description | Address | Size | | ----------------- | ---------- | -------------------- | diff --git a/hal/renesas-ra.c b/hal/renesas-ra.c index 1f6b00e6c..4e90ff867 100644 --- a/hal/renesas-ra.c +++ b/hal/renesas-ra.c @@ -1,6 +1,6 @@ /* renesas-ra.c * - * Stubs for custom HAL implementation. Defines the + * Stubs for custom HAL implementation. Defines the * functions used by wolfboot for a specific target. * * Copyright (C) 2023 wolfSSL Inc. @@ -64,12 +64,12 @@ void hal_init(void) #endif err = R_FLASH_HP_Close(&g_flash0_ctrl); err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg); - + if(err != FSP_ERR_ALREADY_OPEN && err != FSP_SUCCESS){ printf("ERROR: %d\n", err); hal_panic(); } - + /* Setup Default Block 0 as Startup Setup Block */ err = R_FLASH_HP_StartUpAreaSelect(&g_flash0_ctrl, FLASH_STARTUP_AREA_BLOCK0, true); if(err != FSP_SUCCESS){ @@ -120,7 +120,7 @@ static int blockWrite(const uint8_t *data, uint32_t addr, uint32_t len) for(; len; len-=MINIMUM_BLOCK, data+=MINIMUM_BLOCK, addr+=MINIMUM_BLOCK) { /* for the case "data" ls a flash address */ memcpy(save, data, MINIMUM_BLOCK); - + if(R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)save, addr, MINIMUM_BLOCK) != FSP_SUCCESS) return -1; @@ -128,7 +128,7 @@ static int blockWrite(const uint8_t *data, uint32_t addr, uint32_t len) return 0; } -#define IS_FLASH(addr) (addr) >= 0xffc00000 ? 1 : 0 +#define IS_FLASH_ADDR(addr) (addr) >= 0xffc00000 ? 1 : 0 int hal_flash_write(uint32_t addr, const uint8_t *data, int int_len) { @@ -138,21 +138,21 @@ int hal_flash_write(uint32_t addr, const uint8_t *data, int int_len) uint8_t address_tmp = (uint8_t)(addr - ALIGN_FLASH(addr)); if(addr != ALIGN_FLASH(addr)) { - + memset(save, 0, sizeof(save)); - - save_len = (addr - ALIGN_FLASH(addr)) < len ? + + save_len = (addr - ALIGN_FLASH(addr)) < len ? (addr - ALIGN_FLASH(addr)) : len; - - memcpy(save, (const void *)ALIGN_FLASH(addr), + + memcpy(save, (const void *)ALIGN_FLASH(addr), MINIMUM_BLOCK * sizeof(uint32_t)); memcpy(save + (address_tmp), data, save_len); addr = ALIGN_FLASH(addr); - + if((err=R_FLASH_HP_Erase(&g_flash0_ctrl, addr, 1)) != FSP_SUCCESS) return -1; - - if((err=R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)save, addr, + + if((err=R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)save, addr, MINIMUM_BLOCK * sizeof(uint32_t))) != FSP_SUCCESS) return -1; @@ -180,12 +180,12 @@ int hal_flash_write(uint32_t addr, const uint8_t *data, int int_len) memcpy(save, data, len); if(R_FLASH_HP_Erase(&g_flash0_ctrl, addr, 1) != FSP_SUCCESS) return -1; - if(R_FLASH_HP_Write(&g_flash0_ctrl, + if(R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)save, addr, MINIMUM_BLOCK) != FSP_SUCCESS) goto error; } return 0; - + error: return -1; } @@ -194,7 +194,7 @@ int hal_flash_erase(uint32_t address, int int_len) { uint32_t len = (uint32_t)int_len; #ifdef WOLFBOOT_DUALBANK - uint32_t block_size = (address <= 0x80000 && address >= 0x10000) + uint32_t block_size = (address <= 0x80000 && address >= 0x10000) || address >= 0x210000 ? (32*1024) : (8*1024); #else /* Lenier mode */ uint32_t block_size = address >= 0x10000 ? (32*1024) : (8*1024); @@ -234,9 +234,9 @@ void hal_flash_lock(void) FLASH_START_ADDR, FLASH_END_ADDR) != FSP_SUCCESS) hal_panic(); - + #ifdef WOLFBOOT_DUALBANK - if(R_FLASH_HP_AccessWindowSet(&g_flash0_ctrl, + if(R_FLASH_HP_AccessWindowSet(&g_flash0_ctrl, FLASH1_START_ADDR, FLASH1_END_ADDR) != FSP_SUCCESS) hal_panic(); @@ -250,10 +250,10 @@ void RAMFUNCTION hal_flash_dualbank_swap(void) flash_cmd_t cmd = FLASH_CMD_SWAPFLAG_TOGGLE; hal_flash_unlock(); - + if(R_FLASH_HP_Control(cmd, NULL) != FSP_SUCCESS) hal_panic(); - + hal_flash_lock(); } diff --git a/hal/renesas-rx.c b/hal/renesas-rx.c index d42b23f5a..83e8578b5 100644 --- a/hal/renesas-rx.c +++ b/hal/renesas-rx.c @@ -41,14 +41,7 @@ #include "hal.h" #include "printf.h" #include "renesas-rx.h" - -#ifdef USE_RENESAS_BSP - #define wolfBoot_printf printf - #include "r_flash_rx_if.h" - #include "r_flash_rx.h" -#else - #include "printf.h" -#endif +#include "printf.h" #if defined(WOLFBOOT_RENESAS_TSIP) && \ !defined(WOLFBOOT_RENESAS_APP) @@ -61,7 +54,9 @@ TsipUserCtx pkInfo; #endif -#if defined(EXT_FLASH) && defined(TEST_FLASH) +/* forward declaration */ +int hal_flash_init(void); +#ifdef TEST_FLASH static int test_flash(void); #endif @@ -352,15 +347,10 @@ void hal_init(void) uart_write("wolfBoot HAL Init\n", 18); #endif -#if defined(EXT_FLASH) && defined(TEST_FLASH) - if (test_flash() != 0) { - wolfBoot_printf("Flash Test Failed!\n"); - } -#endif + hal_flash_init(); -#ifdef USE_RENESAS_BSP - if (R_FLASH_Open() != FLASH_SUCCESS) - hal_panic(); +#ifdef TEST_FLASH + test_flash(); #endif #if defined(WOLFBOOT_RENESAS_TSIP) && \ @@ -375,19 +365,19 @@ void hal_init(void) encrypted_user_key_data = (struct rsa2048_pub*)keystore_get_buffer(0); key_type = keystore_get_key_type(0); - switch(key_type){ - + switch (key_type) { case AUTH_KEY_RSA2048: tsip_key_type = TSIP_RSA2048; break; case AUTH_KEY_RSA4096: tsip_key_type = TSIP_RSA4096; break; - case AUTH_KEY_ED448: + case AUTH_KEY_ECC256: case AUTH_KEY_ECC384: case AUTH_KEY_ECC521: + /* TODO: ECC */ case AUTH_KEY_ED25519: - case AUTH_KEY_ECC256: + case AUTH_KEY_ED448: case AUTH_KEY_RSA3072: default: tsip_key_type = -1; @@ -399,17 +389,19 @@ void hal_init(void) hal_panic(); } /* inform user key */ - tsip_inform_user_keys_ex((byte*)&encrypted_user_key_data->wufpk, - (byte*)&encrypted_user_key_data->initial_vector, - (byte*)&encrypted_user_key_data->encrypted_user_key, - 0/* dummy */); + tsip_inform_user_keys_ex( + (byte*)&encrypted_user_key_data->wufpk, + (byte*)&encrypted_user_key_data->initial_vector, + (byte*)&encrypted_user_key_data->encrypted_user_key, + 0/* dummy */ + ); /* TSIP specific RSA public key */ if (tsip_use_PublicKey_buffer_crypt(&pkInfo, (const char*)&encrypted_user_key_data->encrypted_user_key, RSA2048_PUB_SIZE, tsip_key_type) != 0) { - wolfboot_printf("ERROR tsip_use_PublicKey_buffer\n"); - hal_panic(); + wolfboot_printf("ERROR tsip_use_PublicKey_buffer\n"); + hal_panic(); } /* Init Crypt Callback */ pkInfo.sing_hash_type = sha256_mac; @@ -419,8 +411,7 @@ void hal_init(void) wolfboot_printf("ERROR: wc_CryptoCb_CryptInitRenesasCmn %d\n", err); hal_panic(); } -#endif - +#endif /* TSIP */ } void hal_prepare_boot(void) @@ -428,141 +419,140 @@ void hal_prepare_boot(void) } -#define IS_FLASH(addr) (addr) >= FLASH_ADDR ? 1 : 0 +int hal_flash_init(void) +{ + /* Flash Write Enable */ + FLASH_FWEPROR = FLASH_FWEPROR_FLWE; -#ifdef USE_RENESAS_BSP + /* Disable FCU interrupts */ + FLASH_FAEINT &= ~( + FLASH_FAEINT_DFAEIE | + FLASH_FAEINT_CMDLKIE | + FLASH_FAEINT_CFAEIE); -#define MIN_PROG (0x8000) -#define ALIGN_FLASH(a) ((a) / MIN_PROG * MIN_PROG) -static uint8_t save[MIN_PROG]; + /* Set the flash clock speed */ + FLASH_FPCKAR = (FLASH_FPCKAR_KEY | + FLASH_FPCKAR_PCKA(FCLK / 1000000UL)); -int blockWrite(const uint8_t *data, uint32_t addr, int len) -{ - for(; len; len-=MIN_PROG, data+=MIN_PROG, addr+=MIN_PROG) { - memcpy(save, data, MIN_PROG); /* for the case "data" ls a flash address */ - if(R_FLASH_Write((uint32_t)save, addr, MIN_PROG) != FLASH_SUCCESS) - return -1; - } return 0; } +/* write up to 256 bytes at a time */ int RAMFUNCTION hal_flash_write(uint32_t addr, const uint8_t *data, int len) { - uint32_t save_len = 0; - - if (addr != ALIGN_FLASH(addr)) { - save_len = (addr - ALIGN_FLASH(addr)) < (uint32_t)len ? - (addr - ALIGN_FLASH(addr)) : (uint32_t)len; - memcpy(save, (const void *)ALIGN_FLASH(addr), MIN_PROG); - memcpy(save + (addr - ALIGN_FLASH(addr)), data, save_len); - addr = ALIGN_FLASH(addr); - if (R_FLASH_Erase((flash_block_address_t)addr, 1) != FLASH_SUCCESS) - return -1; - if (R_FLASH_Write((uint32_t)save, addr, MIN_PROG) != FLASH_SUCCESS) - return -1; - len -= save_len; - data += save_len; - addr += MIN_PROG; - } + int ret, i; + const uint16_t* data16 = (const uint16_t*)data; - if (len > 0) { - if (blockWrite(data, addr, ALIGN_FLASH(len)) < 0) - goto error; - addr += ALIGN_FLASH(len); - data += ALIGN_FLASH(len); - len -= ALIGN_FLASH(len); - } + while (len > 0) { + FLASH_FSADDR = addr; - if (len > 0) { - memcpy(save, (const void *)addr, MIN_PROG); - memcpy(save, data, len); - if (R_FLASH_Erase((flash_block_address_t)addr, 1) != FLASH_SUCCESS) - return -1; - if (R_FLASH_Write((uint32_t)save, addr, MIN_PROG) != FLASH_SUCCESS) - goto error; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_PROGRAM; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_PROGRAM_CODE_LENGTH; + + /* write 128 * 2 bytes */ + for (i=0; i < FLASH_FACI_CMD_PROGRAM_CODE_LENGTH; i++) { + FLASH_FACI_CMD16 = *data16++; + } + + FLASH_FACI_CMD8 = FLASH_FACI_CMD_FINAL; + + /* Wait for FCU operation to complete */ + while ((FLASH_FSTATR & FLASH_FSTATR_FRDY) == 0); + + len += (FLASH_FACI_CMD_PROGRAM_CODE_LENGTH * 2); } return 0; -error: - return -1; } int RAMFUNCTION hal_flash_erase(uint32_t address, int len) { - /* last blocks are 8KB */ - int block_size = address >= 0xffff0000UL ? - FLASH_CF_SMALL_BLOCK_SIZE : FLASH_CF_MEDIUM_BLOCK_SIZE; + int block_size; - if (len % block_size != 0) + /* verify this is a flash address */ + if (!IS_FLASH_ADDR(address)) { return -1; - for ( ; len; address+=block_size, len-=block_size) { - if (R_FLASH_Erase((flash_block_address_t)address, 1) - != FLASH_SUCCESS) - return -1; } - return 0; -} -void RAMFUNCTION hal_flash_unlock(void) -{ - flash_access_window_config_t info; + /* make sure len is multiple of block sizze */ + block_size = FLASH_BLOCK_SIZE(address); + if (len % block_size != 0) { + return -1; + } - info.start_addr = (uint32_t) FLASH_CF_BLOCK_INVALID; - info.end_addr = (uint32_t) FLASH_CF_BLOCK_0; - R_BSP_InterruptsDisable(); - if(R_FLASH_Control(FLASH_CMD_ACCESSWINDOW_SET, (void *)&info) - != FLASH_SUCCESS) - hal_panic(); - R_BSP_InterruptsEnable(); - return; -} + /* erase block(s) */ + while (len > 0) { + FLASH_FSADDR = address; -void RAMFUNCTION hal_flash_lock(void) -{ - flash_access_window_config_t info; - info.start_addr = (uint32_t) FLASH_CF_BLOCK_END; - info.end_addr = (uint32_t) FLASH_CF_BLOCK_END; - R_BSP_InterruptsDisable(); - if(R_FLASH_Control(FLASH_CMD_ACCESSWINDOW_SET, (void *)&info) - != FLASH_SUCCESS) - hal_panic(); - R_BSP_InterruptsEnable(); - return; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_BLOCK_ERASE; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_FINAL; + + /* Wait for FCU operation to complete */ + while ((FLASH_FSTATR & FLASH_FSTATR_FRDY) == 0); + + address += block_size; + len -= block_size; + } + return 0; } -void RAMFUNCTION hal_flash_dualbank_swap(void) +static int RAMFUNCTION hal_flash_write_faw(uint32_t faw) { - flash_cmd_t cmd = FLASH_CMD_SWAPFLAG_TOGGLE; - wolfBoot_printf("FLASH_CMD_SWAPFLAG_TOGGLE=%d\n", FLASH_CMD_SWAPFLAG_TOGGLE); + volatile uint8_t* cmdArea = (volatile uint8_t*)FLASH_FACI_CMD_AREA; + +#ifndef BIG_ENDIAN_ORDER + faw = __builtin_bswap32(faw); +#endif + hal_flash_unlock(); - if(R_FLASH_Control(cmd, NULL) != FLASH_SUCCESS) - hal_panic(); - hal_flash_lock(); -} -#else + /* Flash Access Window Write */ + FLASH_FSADDR = 0x00FF5D60; /* FAW Register Start */ + FLASH_FACI_CMD8 = FLASH_FACI_CMD_CONFIGURATION_SET; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_CONFIGURATION_LENGTH; /* len=8 */ + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD16 = (uint16_t)(faw & 0xFFFF); + FLASH_FACI_CMD16 = (uint16_t)((faw >> 16) & 0xFFFF); + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD16 = 0xFFFF; + FLASH_FACI_CMD8 = FLASH_FACI_CMD_FINAL; + + /* Wait for FCU operation to complete */ + while ((FLASH_FSTATR & FLASH_FSTATR_FRDY) == 0); + + hal_flash_lock(); -int hal_flash_write(uint32_t address, const uint8_t *data, int len) -{ - (void)address; - (void)data; - (void)len; return 0; } -int hal_flash_erase(uint32_t address, int len) + +void RAMFUNCTION hal_flash_dualbank_swap(void) { - (void)address; - (void)len; - return 0; + uint32_t faw = FLASH_FAWMON; + faw ^= FLASH_FAWMON_BTFLG; /* flip BTFLG */ + hal_flash_write_faw(faw); } -void hal_flash_unlock(void) + +void RAMFUNCTION hal_flash_unlock(void) { + /* Enable code flash entry for program/erase */ + FLASH_FENTRYR = (FLASH_FENTRYR_KEY | + FLASH_FENTRYR_DATA_READ | FLASH_FENTRYR_CODE_PR); + + /* Make sure any pending FACI commands are cancelled */ + FLASH_FCMDR = FLASH_FACI_CMD_FORCED_STOP; + while ((FLASH_FSTATR & FLASH_FSTATR_FRDY) == 0); + return; } -void hal_flash_lock(void) +void RAMFUNCTION hal_flash_lock(void) { + /* Disable code flash entry */ + FLASH_FENTRYR = (FLASH_FENTRYR_KEY | + FLASH_FENTRYR_CODE_READ | FLASH_FENTRYR_DATA_READ); return; } -#endif /* USE_RENESAS_BSP */ void* hal_get_primary_address(void) { @@ -574,48 +564,43 @@ void* hal_get_update_address(void) return (void*)WOLFBOOT_PARTITION_UPDATE_ADDRESS; } +#ifdef TEST_FLASH - -#if defined(EXT_FLASH) && defined(TEST_FLASH) #ifndef TEST_ADDRESS -#define TEST_ADDRESS 0x200000 /* 2MB */ +#define TEST_ADDRESS (0xFFFC0000) /* 3,840 KB offset in 4MB flash */ #endif + /* #define TEST_FLASH_READONLY */ + +static uint32_t pageData[WOLFBOOT_SECTOR_SIZE/sizeof(uint32_t)]; /* force 32-bit alignment */ + static int test_flash(void) { int ret; uint32_t i; - uint32_t pageData[WOLFBOOT_SECTOR_SIZE/4]; /* force 32-bit alignment */ + uint8_t* pagePtr = (uint8_t*)TEST_ADDRESS; #ifndef TEST_FLASH_READONLY /* Erase sector */ - ret = ext_flash_erase(TEST_ADDRESS, WOLFBOOT_SECTOR_SIZE); + ret = hal_flash_erase(TEST_ADDRESS, sizeof(pageData)); wolfBoot_printf("Erase Sector: Ret %d\n", ret); /* Write Pages */ for (i=0; i 120MHz) */ + #define FLASH_MEMWAIT (*(volatile uint8_t *)(FLASH_BASE + 0x1C)) + #define FLASH_MEMWAIT_MEMWAIT(n) ((n) << 0) /* 0=no wait, 1=one wait cycle (ICLK > 120MHz) */ #else -#define FLASH_SIZE 0x200000UL /* 2MB */ + #define FLASH_SIZE 0x200000UL /* 2MB */ -#define FLASH_ROMWT (*(volatile uint8_t *)(FLASH_BASE + 0x1C)) -#define FLASH_ROMWT_ROMWT(n) ((n) << 0) /* 0=no wait, 1=one wait cycle, 2=two wait cycles */ + #define FLASH_ROMWT (*(volatile uint8_t *)(FLASH_BASE + 0x1C)) + #define FLASH_ROMWT_ROMWT(n) ((n) << 0) /* 0=no wait, 1=one wait cycle, 2=two wait cycles */ #endif +#define FLASH_BOOT_BLOCK_START (0xFFFF0000UL) +#define FLASH_BLOCK_SIZE_SMALL (8192) +#define FLASH_BLOCK_SIZE_MEDIUM (32768) + +#define FLASH_BLOCK_SIZE(addr) \ + (((addr) >= FLASH_BOOT_BLOCK_START) ? \ + FLASH_BLOCK_SIZE_SMALL : FLASH_BLOCK_SIZE_MEDIUM) + #define FLASH_ADDR (0xFFFFFFFFUL - FLASH_SIZE + 1) +#define IS_FLASH_ADDR(addr) ((addr) >= FLASH_ADDR ? 1 : 0) + +/* FCAI Commands (RX72N RM Table 62.11) */ +#define FLASH_FACI_CMD_PROGRAM 0xE8 +#define FLASH_FACI_CMD_PROGRAM_CODE_LENGTH 128 +#define FLASH_FACI_CMD_PROGRAM_DATA_LENGTH 2 +#define FLASH_FACI_CMD_BLOCK_ERASE 0x20 +#define FLASH_FACI_CMD_PROGRAM_ERASE_SUSPEND 0xB0 +#define FLASH_FACI_CMD_STATUS_CLEAR 0x50 +#define FLASH_FACI_CMD_FORCED_STOP 0xB3 +#define FLASH_FACI_CMD_BLANK_CHECK 0x71 +#define FLASH_FACI_CMD_CONFIGURATION_SET 0x40 +#define FLASH_FACI_CMD_CONFIGURATION_LENGTH 8 +#define FLASH_FACI_CMD_LOCK_BIT_PROGRAM 0x77 +#define FLASH_FACI_CMD_LOCK_BIT_READ 0x71 +#define FLASH_FACI_CMD_FINAL 0xD0 + /* Serial Communication Interface */ #define SCI_BASE(n) (SYSTEM_BASE + 0xA000 + ((n) * 0x20)) @@ -313,9 +399,9 @@ void hal_delay_us(uint32_t us); #define QSPI_SPBFCR_TXTRG(n) (((n) & 0x7) << 3) /* Transmit Buffer Data Trigger Num */ #define QSPI_SPBFCR_RXRST (1 << 6) /* Receive Buffer Data Reset */ #define QSPI_SPBFCR_TXRST (1 << 7) /* Transmit Buffer Data Reset */ -#define QSPI_SPBDCR (*(volatile uint16_t *)(QSPI_BASE + 0x1A)) /* Buffer Data Count Set */ -#define QSPI_SPBDCR_RXBC(n) ((n) & 0x3F) -#define QSPI_SPBDCR_TXBC(n) (((n) & 0x3F) << 8) +#define QSPI_SPBDCR (*(volatile uint16_t *)(QSPI_BASE + 0x1A)) /* Buffer Data Count Set */ +#define QSPI_SPBDCR_RXBC (QSPI_SPBDCR & 0x3F) +#define QSPI_SPBDCR_TXBC ((QSPI_SPBDCR >> 8) & 0x3F) #define QSPI_SPBMUL(n) (*(volatile uint32_t *)(QSPI_BASE + 0x1C + (((n) & 0x3) * 4))) /* Transfer Data Length Multiplier Setting */ #define QSPI_FIFO_SIZE 32 /* bytes */ diff --git a/hal/rx65n.ld b/hal/rx65n.ld index 275ea8652..95a3a0990 100644 --- a/hal/rx65n.ld +++ b/hal/rx65n.ld @@ -32,6 +32,7 @@ SECTIONS .text : { + __start_text = .; *(.text) *(.text.*) *(P) @@ -116,6 +117,8 @@ SECTIONS .data : AT(_mdata) { _data = .; + . = ALIGN(4); + KEEP(*(.ramcode)) *(.data) *(.data.*) *(D) diff --git a/hal/rx72n.ld b/hal/rx72n.ld index 9bba1a68b..82a8b06c4 100644 --- a/hal/rx72n.ld +++ b/hal/rx72n.ld @@ -31,6 +31,7 @@ SECTIONS .text : { + __start_text = .; *(.text) *(.text.*) *(P) @@ -115,6 +116,8 @@ SECTIONS .data : AT(_mdata) { _data = .; + . = ALIGN(4); + KEEP(*(.ramcode)) *(.data) *(.data.*) *(D) @@ -126,6 +129,7 @@ SECTIONS .bss : { _bss = .; + *(.dynbss) *(.bss) *(.bss.**) *(COMMON) diff --git a/hal/spi/spi_drv_renesas_rx.c b/hal/spi/spi_drv_renesas_rx.c index bc8520fe0..113ce1106 100644 --- a/hal/spi/spi_drv_renesas_rx.c +++ b/hal/spi/spi_drv_renesas_rx.c @@ -34,16 +34,29 @@ #if defined(SPI_FLASH) || defined(QSPI_FLASH) +#ifdef SPI_FLASH +static int rx_spi_init_done = 0; +#endif +#ifdef QSPI_FLASH +static int rx_qspi_init_done = 0; +static uint16_t rx_qspi_cmd_def; +#endif + /* RSPI1: P27/RSPCKB-A, P26/MOSIB-A, P30/MISOB-A, P31/SSLB0-A */ /* QSPI: PD2/QIO2-B, PD3/QIO3-B, PD4/QSSL-B, PD5/QSPCLK-B, PD6/QIO0-B, PD7/QIO1-B */ void spi_init(int polarity, int phase) { - uint32_t reg; #ifdef SPI_FLASH /* Release RSPI1 module stop (clear bit) */ PROTECT_OFF(); /* SYS_MSTPCRB: bit 17=RSPI0, 16=RSPI1, SYS_MSTPCRC: bit 22=RSPI2 */ +#if FLASH_RSPI_PORT == 0 + SYS_MSTPCRB &= ~(1 << 17); +#elif FLASH_RSPI_PORT == 1 SYS_MSTPCRB &= ~(1 << 16); +#elif FLASH_RSPI_PORT == 2 + SYS_MSTPCRC &= ~(1 << 22); +#endif PROTECT_ON(); /* Configure P26-27 and P30-31 for alt mode */ @@ -96,6 +109,8 @@ void spi_init(int polarity, int phase) /* Master SPI operation (4-wire method) */ RSPI_SPCR(FLASH_RSPI_PORT) = RSPI_SPCR_MSTR; + + rx_spi_init_done++; #endif /* SPI_FLASH */ #ifdef QSPI_FLASH @@ -129,14 +144,14 @@ void spi_init(int polarity, int phase) QSPI_SPCR = QSPI_SPCR_MSTR; /* Master mode */ QSPI_SSLP &= ~QSPI_SSLP_SSLP; /* SS Active low */ QSPI_SPPCR = (QSPI_SPPCR_MOIFV | QSPI_SPPCR_MOIDE); /* enable idle fixing */ - QSPI_SPBR = 1; /* 30Mbps */ + QSPI_SPBR = 1; /* 30Mhz */ QSPI_SPCKD = QSPI_SPCKD_SCKDL(0); /* 1 clock delay (SSL assert and first clock cycle) */ QSPI_SSLND = QSPI_SSLND_SLNDL(0); /* 1 clock delay (last clock cycle and SSL negation) */ QSPI_SPND = QSPI_SPND_SPNDL(0); /* Next-Access Delay: 1RSPCK+2PCLK */ QSPI_SPDCR = 0; /* no dummy TX */ /* Setup default QSPI commands */ - reg = ( + rx_qspi_cmd_def = ( QSPI_SPCMD_SPIMOD(0) | /* Single SPI */ QSPI_SPCMD_SPB(0) | /* use byte */ QSPI_SPCMD_BRDV(0) | /* div/1 (no div) */ @@ -146,17 +161,18 @@ void spi_init(int polarity, int phase) QSPI_SPCMD_SCKDEN /* enable RSPCK Delay */ ); if (polarity) - reg |= QSPI_SPCMD_CPOL; + rx_qspi_cmd_def |= QSPI_SPCMD_CPOL; if (phase) - reg |= QSPI_SPCMD_CPHA; - QSPI_SPCMD(0) = reg; - QSPI_SPCMD(1) = reg; - QSPI_SPCMD(2) = reg; - QSPI_SPCMD(3) = reg; + rx_qspi_cmd_def |= QSPI_SPCMD_CPHA; + QSPI_SPCMD(0) = rx_qspi_cmd_def; + QSPI_SPCMD(1) = rx_qspi_cmd_def; + QSPI_SPCMD(2) = rx_qspi_cmd_def; + QSPI_SPCMD(3) = rx_qspi_cmd_def; + + rx_qspi_init_done++; #endif /* QSPI_FLASH */ (void)polarity; (void)phase; - (void)reg; } void spi_release(void) @@ -211,6 +227,11 @@ uint8_t spi_read(void) int spi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int flags) { uint32_t i; + if (!rx_spi_init_done) { + wolfBoot_printf("SPI init not yet called\n"); + return -1; + } + spi_cs_on(SPI_CS_TPM_PIO_BASE, cs); for (i = 0; i < sz; i++) { spi_write((const char)tx[i]); @@ -228,57 +249,42 @@ int spi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int flags) #ifdef QSPI_FLASH -/* dataSz in bytes */ static uint32_t fifoLvl = 0; -static void qspi_flush(void) +static void qspi_cmd(const uint8_t* cmd, uint32_t cmdSz) { uint8_t tmp; - - /* workaround for issue with RX FIFO */ - hal_delay_us(fifoLvl); /* 1us per byte */ - while (fifoLvl > 0) { - tmp = QSPI_SPDR8; - fifoLvl--; - } -} -/* write only */ -static void qspi_cmd(const uint8_t* data, uint32_t dataSz) -{ - uint8_t tmp; - while (dataSz > 0) { - /* Wait for transmit empty flag */ + while (cmdSz > 0) { while ((QSPI_SPSR & QSPI_SPSR_SPTEF) == 0); - tmp = 0xFF; - if (data) - tmp = *data++; - QSPI_SPDR8 = tmp; + if (cmd != NULL) + QSPI_SPDR8 = *cmd++; + else + QSPI_SPDR8 = 0xFF; + QSPI_SPSR &= ~QSPI_SPSR_SPTEF; + cmdSz--; fifoLvl++; - dataSz--; - - /* flush RX FIFO */ - if (fifoLvl >= QSPI_FIFO_SIZE) { - qspi_flush(); - } } } -/* TODO: Handle timeout */ + +/* dataSz in bytes */ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) { volatile uint32_t tmp; + uint32_t i; uint8_t *pTx, *pRx; - if (fifoLvl > 0) { - qspi_flush(); + /* flush anything in the RX FIFO */ + while (fifoLvl > 0) { + while ((QSPI_SPSR & QSPI_SPSR_SPRFF) == 0); + tmp = QSPI_SPDR8; + QSPI_SPSR &= ~QSPI_SPSR_SPRFF; + fifoLvl--; } - /* Clear TX/RX Flags */ - QSPI_SPSR |= (QSPI_SPSR_SPRFF | QSPI_SPSR_SPTEF); - /* Do full FIFO (32 bytes) TX/RX - word */ while (dataSz >= (QSPI_FIFO_SIZE/2)) { - /* Transmit Data */ + /* Transfer bytes - fill 16 bytes */ while ((QSPI_SPSR & QSPI_SPSR_SPTEF) == 0); - while (fifoLvl < (QSPI_FIFO_SIZE/2)) { + for (i=0; i<(QSPI_FIFO_SIZE/2); i+=4) { tmp = 0xFFFFFFFF; if (txData) { tmp = *txData++; @@ -287,28 +293,24 @@ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) #endif } QSPI_SPDR32 = tmp; + dataSz -= 4; fifoLvl += 4; } - QSPI_SPSR |= QSPI_SPSR_SPTEF; + QSPI_SPSR &= ~QSPI_SPSR_SPTEF; - /* handle RX */ + /* Recieve bytes - (previous 16 bytes) */ while ((QSPI_SPSR & QSPI_SPSR_SPRFF) == 0); - if (fifoLvl >= QSPI_FIFO_SIZE) { - /* Recieve bytes */ - while (fifoLvl > 0) { - tmp = QSPI_SPDR32; - if (rxData) { - #ifndef BIG_ENDIAN_ORDER - tmp = __builtin_bswap32(tmp); - #endif - *rxData++ = tmp; - } - fifoLvl -= 4; + while (fifoLvl > (QSPI_FIFO_SIZE/2)) { + tmp = QSPI_SPDR32; + if (rxData) { + #ifndef BIG_ENDIAN_ORDER + tmp = __builtin_bswap32(tmp); + #endif + *rxData++ = tmp; } + fifoLvl -= 4; } - QSPI_SPSR |= QSPI_SPSR_SPRFF; - - dataSz -= QSPI_FIFO_SIZE/2; + QSPI_SPSR &= ~QSPI_SPSR_SPRFF; } /* Remainder < FIFO TX/RX - byte */ @@ -316,26 +318,29 @@ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) pRx = (uint8_t*)rxData; /* Transmit Data */ - /* Wait for transmit empty flag */ - while ((QSPI_SPSR & QSPI_SPSR_SPTEF) == 0); while (dataSz > 0) { + while ((QSPI_SPSR & QSPI_SPSR_SPTEF) == 0); if (pTx) QSPI_SPDR8 = *pTx++; else QSPI_SPDR8 = 0xFF; + QSPI_SPSR &= ~QSPI_SPSR_SPTEF; dataSz--; fifoLvl++; } - /* Recieve bytes */ - /* Wait for RX ready */ + /* wait for transfer to finish */ while ((QSPI_SPSR & QSPI_SPSR_SPSSLF) == 0); + + /* Recieve bytes */ while (fifoLvl > 0) { + while ((QSPI_SPSR & QSPI_SPSR_SPRFF) == 0); if (pRx) *pRx++ = QSPI_SPDR8; else tmp = QSPI_SPDR8; fifoLvl--; + QSPI_SPSR &= ~QSPI_SPSR_SPRFF; } return 0; @@ -348,51 +353,50 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, uint32_t dummySz, uint8_t* data, uint32_t dataSz, uint32_t dataMode) { + int ret; uint8_t seq = 0; - uint16_t cmd_def; volatile uint32_t reg; + uint32_t timeout = 10000; - /* capture command defaults */ - cmd_def = QSPI_SPCMD(0) & ( - QSPI_SPCMD_CPOL | QSPI_SPCMD_CPHA | QSPI_SPCMD_SSLKP | - QSPI_SPCMD_SPNDEN | QSPI_SPCMD_SLNDEN | QSPI_SPCMD_SCKDEN | - QSPI_SPCMD_BRDV_MASK | QSPI_SPCMD_SPB_MASK - ); + if (!rx_qspi_init_done) { + wolfBoot_printf("QSPI init not yet called\n"); + return -1; + } - /* Clear flags */ - QSPI_SPSR |= (QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); + /* Clear flags - write 0 to bit to clear */ + QSPI_SPSR &= ~(QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); /* Reset buffers */ QSPI_SPBFCR |= (QSPI_SPBFCR_RXRST | QSPI_SPBFCR_TXRST); reg = QSPI_SPBFCR; /* SPBFCR requires dummy read after write */ - /* Set FIFO Trigger Level */ + /* Set FIFO Trigger Level - must be set when SPCR.SPE=0 */ //QSPI_SPBFCR = QSPI_SPBFCR_RXTRG(5) | QSPI_SPBFCR_TXTRG(3); /* RX Trig=16 bytes, TX Trig=16 bytes */ QSPI_SPBFCR = QSPI_SPBFCR_RXTRG(0) | QSPI_SPBFCR_TXTRG(6); /* RX Trig=1 byte, TX Trig=0 bytes */ reg = QSPI_SPBFCR; /* SPBFCR requires dummy read after write */ /* Command / Instruction - Write (command always SPI mode) */ QSPI_SPBMUL(seq) = 1; /* Set Data length */ - QSPI_SPCMD(seq) = (cmd_def | QSPI_SPCMD_SPIMOD(0)); + QSPI_SPCMD(seq) = (rx_qspi_cmd_def | QSPI_SPCMD_SPIMOD(0)); seq++; /* Address Write */ - if (addrMode != QSPI_DATA_MODE_NONE) { + if (addrSz > 0 && addrMode != QSPI_DATA_MODE_NONE) { QSPI_SPBMUL(seq) = addrSz; - QSPI_SPCMD(seq) = (cmd_def | QSPI_SPCMD_SPIMOD(addrMode-1)); + QSPI_SPCMD(seq) = (rx_qspi_cmd_def | QSPI_SPCMD_SPIMOD(addrMode-1)); seq++; } - /* Alternate bytes + dummy */ - if (altMode != QSPI_DATA_MODE_NONE || dummySz > 0) { - QSPI_SPBMUL(seq) = altSz + dummySz; - QSPI_SPCMD(seq) = (cmd_def | QSPI_SPCMD_SPIMOD(altMode-1)); + /* Alternate bytes */ + if (altSz > 0 && altMode != QSPI_DATA_MODE_NONE) { + QSPI_SPBMUL(seq) = altSz; + QSPI_SPCMD(seq) = (rx_qspi_cmd_def | QSPI_SPCMD_SPIMOD(altMode-1)); seq++; } /* Data */ - if (dataMode != QSPI_DATA_MODE_NONE) { + if (dataSz > 0 && dataMode != QSPI_DATA_MODE_NONE) { QSPI_SPBMUL(seq) = dataSz; - QSPI_SPCMD(seq) = (cmd_def | QSPI_SPCMD_SPIMOD(dataMode-1)); + QSPI_SPCMD(seq) = (rx_qspi_cmd_def | QSPI_SPCMD_SPIMOD(dataMode-1)); if (fmode == QSPI_MODE_READ) QSPI_SPCMD(seq) |= QSPI_SPCMD_SPREAD; seq++; @@ -410,25 +414,33 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, /* Transfer Data for sequences */ qspi_cmd(&cmd, 1); if (addrMode != QSPI_DATA_MODE_NONE) { - qspi_cmd((uint8_t*)&addr, addrSz); + qspi_cmd((const uint8_t*)&addr, addrSz); } if (altMode != QSPI_DATA_MODE_NONE) { - qspi_cmd((uint8_t*)&alt, altSz); + qspi_cmd((const uint8_t*)&alt, altSz); } if (dummySz > 0) { - qspi_cmd(NULL, dummySz); + qspi_cmd(NULL, dummySz/8); } if (fmode == QSPI_MODE_READ) qspi_data(NULL, (uint32_t*)data, dataSz); else qspi_data((const uint32_t*)data, NULL, dataSz); - /* Clear flags */ - QSPI_SPSR |= (QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); + /* wait for slave select to de-assert */ + while ((QSPI_SPSR & QSPI_SPSR_SPSSLF) == 0 && --timeout > 0) { + hal_delay_us(1); + } + + /* check for timeout (-1) or success */ + ret = (timeout == 0) ? -1 : 0; + + /* Clear flags - write 0 to bit to clear */ + QSPI_SPSR &= ~(QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); /* Disable QSPI */ QSPI_SPCR &= ~QSPI_SPCR_SPE; - return 0; + return ret; } #endif /* QSPI_FLASH */ diff --git a/src/boot_renesas.c b/src/boot_renesas.c index a67a22a81..6f0697ccf 100644 --- a/src/boot_renesas.c +++ b/src/boot_renesas.c @@ -22,20 +22,27 @@ #include #include "wolfboot/wolfboot.h" #include "hal.h" +#include "image.h" #ifdef _RENESAS_RZN_ extern uint32_t IMAGE_APP_RAM_start; #endif -/* This is the main loop for the bootloader. - * - * It performs the following actions: - * - globally disable interrupts - * - update the Interrupt Vector using the address of the app - * - Set the initial stack pointer and the offset of the app - * - Change the stack pointer - * - Call the application entry point - * - */ + +#ifdef __RX__ +#include "hal/renesas-rx.h" +#endif + +void RAMFUNCTION arch_reboot(void) +{ +#if defined(__RX__) + /* Disable protect registers */ + PROTECT_OFF(); + + /* Issue software reset */ + SYS_SWRR = SYS_SWRR_RESET; +#endif +} + #if defined(__RX__) && defined(__CCRX__) #pragma inline_asm longJump @@ -45,6 +52,7 @@ static void longJump(const uint32_t *app_offset) } #endif +/* Calls the application entry point */ void do_boot(const uint32_t *app_offset) { void (*app_entry)(void); diff --git a/src/qspi_flash.c b/src/qspi_flash.c index 6a98161e4..2049cdc09 100644 --- a/src/qspi_flash.c +++ b/src/qspi_flash.c @@ -144,8 +144,8 @@ /* forward declarations */ static int qspi_wait_ready(void); static int qspi_status(uint8_t* status); -#ifdef TEST_FLASH -static int test_flash(void); +#ifdef TEST_EXT_FLASH +static int test_ext_flash(void); #endif static inline int qspi_command_simple(uint8_t fmode, uint8_t cmd, @@ -352,8 +352,8 @@ uint16_t spi_flash_probe(void) qspi_enter_4byte_addr(); #endif -#ifdef TEST_FLASH - test_flash(); +#ifdef TEST_EXT_FLASH + test_ext_flash(); #endif return 0; } @@ -477,11 +477,14 @@ void spi_flash_release(void) #endif /* QSPI_FLASH || OCTOSPI_FLASH */ -#ifdef TEST_FLASH -/* Start Address for test - 2MB */ -#define TEST_ADDRESS (2 * 1024 * 1024) +#ifdef TEST_EXT_FLASH -static int test_flash(void) +#ifndef TEST_EXT_ADDRESS + /* Start Address for test - 2MB */ + #define TEST_EXT_ADDRESS (2 * 1024 * 1024) +#endif + +static int test_ext_flash(void) { int ret; uint32_t i; @@ -490,20 +493,20 @@ static int test_flash(void) #ifndef TEST_FLASH_READONLY /* Erase sector */ - ret = ext_flash_erase(TEST_ADDRESS, FLASH_SECTOR_SIZE); + ret = ext_flash_erase(TEST_EXT_ADDRESS, FLASH_SECTOR_SIZE); wolfBoot_printf("Sector Erase: Ret %d\n", ret); /* Write Page */ for (i=0; i