From 486d04eb6edf1ad707178733ecca100bb5b31375 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 19 Sep 2024 16:08:32 -0700 Subject: [PATCH] Fixes for building nRF5340 for both application and network cores. Revert some "CORE" logic, easier to have different targets. --- .github/workflows/test-configs.yml | 8 +++- config/examples/nrf5340.config | 4 ++ config/examples/nrf5340_net.config | 49 ++++++++++++++++++++ docs/Targets.md | 40 +++++++++++++--- hal/nrf5340.c | 32 ++++++++++--- hal/nrf5340.h | 74 ++++++++++++++++++++++++------ hal/nrf5340.ld | 5 +- hal/nrf5340_net.c | 28 +++++++++++ hal/nrf5340_net.ld | 51 ++++++++++++++++++++ options.mk | 5 -- test-app/app_nrf5340.c | 6 +-- test-app/app_nrf5340_net.c | 70 ++++++++++++++++++++++++++++ 12 files changed, 334 insertions(+), 38 deletions(-) create mode 100644 config/examples/nrf5340_net.config create mode 100644 hal/nrf5340_net.c create mode 100644 hal/nrf5340_net.ld create mode 100644 test-app/app_nrf5340_net.c diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 35d2cc626..c86b5b0ef 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -116,12 +116,18 @@ jobs: arch: arm config-file: ./config/examples/nrf52840.config - nrf5340_test: + nrf5340_app_test: uses: ./.github/workflows/test-build.yml with: arch: arm config-file: ./config/examples/nrf5340.config + nrf5340_net_test: + uses: ./.github/workflows/test-build.yml + with: + arch: arm + config-file: ./config/examples/nrf5340_net.config + nxp_p1021_test: uses: ./.github/workflows/test-build.yml with: diff --git a/config/examples/nrf5340.config b/config/examples/nrf5340.config index fda5763bf..7588cdab7 100644 --- a/config/examples/nrf5340.config +++ b/config/examples/nrf5340.config @@ -43,3 +43,7 @@ WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x200000 V?=0 DEBUG?=0 DEBUG_UART?=1 +USE_GCC=1 + +CFLAGS_EXTRA+=-DDEBUG_FLASH + diff --git a/config/examples/nrf5340_net.config b/config/examples/nrf5340_net.config new file mode 100644 index 000000000..a7ecc9669 --- /dev/null +++ b/config/examples/nrf5340_net.config @@ -0,0 +1,49 @@ +ARCH?=ARM +TZEN?=0 +TARGET?=nrf5340_net +SIGN?=ECC256 +HASH?=SHA256 +WOLFBOOT_VERSION?=1 +VTOR?=1 +CORTEX_M0?=0 +CORTEX_M33?=1 +NO_ASM?=0 +NO_MPU=1 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE?=0 + +SPMATH?=1 +RAM_CODE?=1 + +DUALBANK_SWAP?=0 +FLAGS_HOME=0 +DISABLE_BACKUP=1 +EXT_FLASH?=0 +SPI_FLASH?=0 +QSPI_FLASH?=0 + +# Flash base for network core +ARCH_FLASH_OFFSET=0x01000000 + +# Flash is 4KB pages (app) 2KB pages (net) +WOLFBOOT_SECTOR_SIZE?=0x1000 + +# Application Partition Size (256KB-64KB) +WOLFBOOT_PARTITION_SIZE?=0x18000 + +# Reserve 64KB for wolfBoot +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x01010000 + +# Flash offset for update (not used) +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0 + +# Flash offset for swap (not used) +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0 + +V?=0 +DEBUG?=0 +DEBUG_UART?=1 +USE_GCC=1 + +CFLAGS_EXTRA+=-DDEBUG_FLASH + diff --git a/docs/Targets.md b/docs/Targets.md index 7ad43ee26..518395d4b 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2133,23 +2133,49 @@ Tested with the Nordic nRF5340-DK. This device has two cores: The cores communicate using the IPC peripheral. -### Building Nordic nRF5340 +The network core can access application core resources (flash, RAM, and peripherals) when granted permission through the application's DCNF and SPU settings. A small portion of the application core RAM is dedicated to the exchange of messages between the application and network cores. -Setup the configuration to build: `cp config/examples/nrf5340.config .config` +### Building / Flashing Nordic nRF5340 -Build application core loading using: `make clean && make` -Build network core loader using: `make CORE=2` +#### Application Core -Flashing with JLink: +Flash base: 0x00000000, SRAM base: 0x20000000 + +Building Application core: + +```sh +cp config/examples/nrf5340.config .config +make clean +make +``` + +Flashing Application core with JLink: ``` JLinkExe -device nRF5340_xxAA_APP -if SWD -speed 4000 -jtagconf -1,-1 -autoconnect 1 -erase loadbin factory.bin 0x0 rnh ``` -Note: For network core use: `-device nRF5340_xxAA_NET` +#### Network Core + +Flash base: 0x01000000, SRAM base: 0x21000000 + +Building Network core: + +```sh +cp config/examples/nrf5340_net.config .config +make clean +make +``` + +Flashing Network core with JLink: + +``` +JLinkExe -device nRF5340_xxAA_NET -if SWD -speed 4000 -jtagconf -1,-1 -autoconnect 1 +loadbin factory.bin 0x01000000 +rnh +``` ### Debugging Nordic nRF5340 diff --git a/hal/nrf5340.c b/hal/nrf5340.c index c4110c735..f5239d94c 100644 --- a/hal/nrf5340.c +++ b/hal/nrf5340.c @@ -1,6 +1,6 @@ -/* nrf52.c +/* nrf5340.c * - * Copyright (C) 2021 wolfSSL Inc. + * Copyright (C) 2024 wolfSSL Inc. * * This file is part of wolfBoot. * @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* Note: Also used by TARGET_nrf5340_net */ #ifdef TARGET_nrf5340 #include @@ -28,6 +29,14 @@ #include "printf.h" #include "nrf5340.h" +/* TODO: + * Key Storage: See 7.1.18.4.2 Key storage: + * The key storage region of the UICR can contain multiple keys of different type, including symmetrical keys, hashes, public/private key pairs and other device secrets + * Key headers are allocated an address range of 0x400 in the UICR memory map, allowing a total of 128 keys to be addressable inside the key storage region. + * The key storage region contains multiple key slots, where each slot consists of a key header and an associated key value. The key value is limited to 128 bits. + * Any key size greater than 128 bits must be divided and distributed over multiple key slot instances. + */ + #ifdef TEST_FLASH static int test_flash(void); #endif @@ -40,7 +49,10 @@ static int test_flash(void); void uart_init(void) { - /* nRF5340-DK UART0=P1.01, UART1=P0.20 */ + /* nRF5340-DK: + * App: UART0=P1.01, UART1=P0.20 + * Net: UART0= */ + UART_ENABLE(UART_SEL) = 0; #if UART_SEL == 0 GPIO_PIN_CNF(1, 1) = GPIO_CNF_OUT; @@ -181,12 +193,18 @@ static void clock_init(void) while (CLOCK_HFCLKSTARTED == 0); } -/* CPU is running at 128MHz so 128 NOP's = 1us */ void sleep_us(unsigned int us) { - unsigned int nop_us = (CPU_CLOCK / 1000000); - us *= nop_us; - while (us-- > 0) { + /* Calculate ops per us (128MHz=128 instructions per 1us */ + unsigned long nop_us = (CPU_CLOCK / 10000000); + nop_us *= us; + /* instruction for each iteration */ +#ifdef DEBUG + nop_us /= 5; +#else + nop_us /= 2; +#endif + while (nop_us-- > 0) { NOP(); } } diff --git a/hal/nrf5340.h b/hal/nrf5340.h index 138b46984..3fd25abb2 100644 --- a/hal/nrf5340.h +++ b/hal/nrf5340.h @@ -24,18 +24,18 @@ /* Build-time gate for secure or non-secure peripherals. * At boot-time peripherals are secure */ -#if defined(CORE) && CORE == 2 - #define TARGET_nrf5340_NET /* core 2 */ - +#ifdef TARGET_nrf5340_net + /* Network core */ #undef QSPI_FLASH /* not supported on network core */ #else - #define TARGET_nrf5340_APP /* core 1 */ + /* Application core */ #ifndef TZEN + /* at reset/power on wolfBoot is using secure bases */ #define TZEN #endif #endif -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #define CPU_CLOCK 128000000UL /* 128MHz */ #else #define CPU_CLOCK 64000000UL /* 64MHz */ @@ -44,6 +44,8 @@ /* Assembly helpers */ #define DMB() __asm__ volatile ("dmb") +#define DSB() __asm__ volatile ("dsb") +#define ISB() __asm__ volatile ("isb") #define NOP() __asm__ volatile ("nop") void sleep_us(unsigned int us); @@ -51,8 +53,51 @@ void sleep_us(unsigned int us); /* PSEL Port (bit 5) - Used for various PSEL (UART,SPI,QSPI,I2C,NFC) */ #define PSEL_PORT(n) (((n) & 0x1) << 5) +/* Domain Configuration */ +#ifdef TARGET_nrf5340 + #ifdef TZEN + #define DCNF_BASE (0x50000000) + #else + #define DCNF_BASE (0x40000000) + #endif +#else + #define DCNF_BASE (0x41000000) +#endif + +#define DCNF_CPUID *((volatile uint32_t *)(DCNF_BASE + 0x420)) +#ifdef TARGET_nrf5340 + /* allows blocking of network cores ability to resources on application core */ + #define DCNF_EXTPERI0_PROT *((volatile uint32_t *)(DCNF_BASE + 0x440)) + #define DCNF_EXTRAM0_PROT *((volatile uint32_t *)(DCNF_BASE + 0x460)) /* Eight 64KB slaves bit 0=0x20000000-0x20010000 (64KB) */ + #define DCNF_EXTCODE0_PROT *((volatile uint32_t *)(DCNF_BASE + 0x480)) +#endif + +/* OTP */ +#define UICR_BASE (0x00FF8000UL) + +/* Reset */ +#ifdef TARGET_nrf5340 + #ifdef TZEN + #define RESET_BASE (0x50005000) + #else + #define RESET_BASE (0x40005000) + #endif +#else + #define RESET_BASE (0x41005000) +#endif +#define NETWORK_RESETREAS *((volatile uint32_t *)(RESET_BASE + 0x400)) +#define NETWORK_RESETREAS_RESETPIN (1 << 0) +#define NETWORK_RESETREAS_DOG0 (1 << 1) /* watchdog timer 0 */ +#define NETWORK_RESETREAS_SREQ (1 << 3) /* soft reset */ +#define NETWORK_RESETREAS_OFF (1 << 5) /* wake from off */ +#define NETWORK_RESETREAS_MFORCEOFF (1 << 23) +#define NETWORK_FORCEOFF *((volatile uint32_t *)(RESET_BASE + 0x614)) +#define NETWORK_FORCEOFF_RELEASE 0 +#define NETWORK_FORCEOFF_HOLD 1 + + /* Non-volatile memory controller */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define NVMC_BASE (0x50039000) #else @@ -78,7 +123,7 @@ void sleep_us(unsigned int us); #define FLASH_PAGE_SIZE (4096) /* Clock control */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define CLOCK_BASE (0x50005000) #else @@ -109,7 +154,7 @@ void sleep_us(unsigned int us); /* GPIO Port (0-1) */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define GPIO_BASE(n) (0x50842500 + (((n) & 0x1) * 0x300)) #else @@ -137,14 +182,14 @@ void sleep_us(unsigned int us); #define GPIO_CNF_MCUSEL(n) (((n) & 0x7) << 28) /* UART (0-1) */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define UART_BASE(n) (0x50008000 + (((n) & 0x1) * 0x1000)) #else #define UART_BASE(n) (0x40008000 + (((n) & 0x1) * 0x1000)) #endif #else - #define UART_BASE(n) (0x41013000) /* only UARTE0 */ + #define UART_BASE(n) (0x41013000) /* UARTE0 only */ #endif #define UART_TASK_STARTTX(n) *((volatile uint32_t *)(UART_BASE(n) + 0x008)) @@ -163,7 +208,7 @@ void sleep_us(unsigned int us); void uart_write_sz(const char* c, unsigned int sz); /* SPI (0-2) */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define SPI_BASE(n) (0x50008000 + (((n) & 0x3) * 0x1000)) #else @@ -200,7 +245,7 @@ void uart_write_sz(const char* c, unsigned int sz); #define SPI_FREQ_M32 0x14000000 /* QSPI */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define QSPI_BASE (0x5002B000) #else @@ -276,10 +321,13 @@ void uart_write_sz(const char* c, unsigned int sz); #define QSPI_CINSTRCONF_WREN (1 << 15) /* send WREN opcode 0x6 before */ #define QSPI_IFTIMING_RXDELAY(n) (((n) & 0x7) << 8) +#else + /* Disable QSPI Flash */ + #undef QSPI_FLASH #endif /* interprocessor communication (IPC) peripheral */ -#ifdef TARGET_nrf5340_APP +#ifdef TARGET_nrf5340 #ifdef TZEN #define IPC_BASE (0x5002A000) #else diff --git a/hal/nrf5340.ld b/hal/nrf5340.ld index ac56d3a6d..9f1c9809e 100644 --- a/hal/nrf5340.ld +++ b/hal/nrf5340.ld @@ -1,7 +1,8 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + FLASH (rx) : ORIGIN = @ARCH_FLASH_OFFSET@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ + FLASH_NET (rx) : ORIGIN = 0x01000000, LENGTH = 256K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } SECTIONS diff --git a/hal/nrf5340_net.c b/hal/nrf5340_net.c new file mode 100644 index 000000000..bce3e01ba --- /dev/null +++ b/hal/nrf5340_net.c @@ -0,0 +1,28 @@ +/* nrf5340_net.c + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef TARGET_nrf5340_net + +/* use code from nrf5340.c */ +#define TARGET_nrf5340 +#include "nrf5340.c" + +#endif /* TARGET_* */ diff --git a/hal/nrf5340_net.ld b/hal/nrf5340_net.ld new file mode 100644 index 000000000..888253875 --- /dev/null +++ b/hal/nrf5340_net.ld @@ -0,0 +1,51 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = @ARCH_FLASH_OFFSET@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ + RAM(rwx) : ORIGIN = 0x21000000, LENGTH = 64K +} + +SECTIONS +{ + .text : + { + _start_text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + *(.init*) + *(.fini*) + . = ALIGN(4); + _end_text = .; + } > FLASH + + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + + _stored_data = .; + + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(4); + _end_data = .; + } > RAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + __bss_end__ = .; + _end = .; + } > RAM + . = ALIGN(4); +} + +END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/options.mk b/options.mk index bbf7e6b05..dee8d488b 100644 --- a/options.mk +++ b/options.mk @@ -851,8 +851,3 @@ endif ifneq ($(KEYVAULT_MAX_ITEMS),) CFLAGS+=-DKEYVAULT_MAX_ITEMS=$(KEYVAULT_MAX_ITEMS) endif - - -ifneq ($(CORE),) - CFLAGS+=-DCORE=$(CORE) -endif diff --git a/test-app/app_nrf5340.c b/test-app/app_nrf5340.c index f8736bd45..ab17e4485 100644 --- a/test-app/app_nrf5340.c +++ b/test-app/app_nrf5340.c @@ -52,7 +52,7 @@ void main(void) uart_init(); wolfBoot_printf("========================\n"); - wolfBoot_printf("nRF5340 wolfBoot demo app\n"); + wolfBoot_printf("nRF5340 wolfBoot (application core)\n"); wolfBoot_printf("Copyright 2024 wolfSSL Inc\n"); wolfBoot_printf("GPL v3\n"); wolfBoot_printf("Version : 0x%lx\r\n", app_version); @@ -64,7 +64,7 @@ void main(void) /* Toggle LED loop */ while (1) { gpiotoggle(port, pin); - for (i = 0; i < 800000; i++) /* Wait a bit. */ - NOP(); + + sleep_us(100 * 1000); } } diff --git a/test-app/app_nrf5340_net.c b/test-app/app_nrf5340_net.c new file mode 100644 index 000000000..f102c7d4d --- /dev/null +++ b/test-app/app_nrf5340_net.c @@ -0,0 +1,70 @@ +/* nrf5340.c + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include +#include "wolfboot/wolfboot.h" +#include "hal/nrf5340.h" +#include "printf.h" + +void gpiotoggle(uint32_t port, uint32_t pin) +{ + uint32_t reg_val = GPIO_OUT(port); + GPIO_OUTCLR(port) = reg_val & (1 << pin); + GPIO_OUTSET(port) = (~reg_val) & (1 << pin); +} + +void main(void) +{ + int i; + /* nRF5340-DK LEDs: + * LED1 P0.28 + * LED2 P0.29 + * LED3 P0.30 + * LED4 P0.31 */ + uint32_t port = 0; + uint32_t pin = 28; + uint32_t app_version; + + GPIO_PIN_CNF(port, pin) = 1; /* Output */ + + app_version = wolfBoot_current_firmware_version(); + + uart_init(); + + wolfBoot_printf("========================\n"); + wolfBoot_printf("nRF5340 wolfBoot (network core)\n"); + wolfBoot_printf("Copyright 2024 wolfSSL Inc\n"); + wolfBoot_printf("GPL v3\n"); + wolfBoot_printf("Version : 0x%lx\r\n", app_version); + wolfBoot_printf("========================\n"); + + /* mark boot successful */ + wolfBoot_success(); + + /* Toggle LED loop */ + while (1) { + gpiotoggle(port, pin); + + sleep_us(100 * 1000); + } +}