Skip to content

Commit

Permalink
Progress implementing support for network core flash update. The appl…
Browse files Browse the repository at this point in the history
…ication core will check external flash for network core update and send to network core over shared memory. Added support for custom partition id.
  • Loading branch information
dgarske committed Sep 24, 2024
1 parent 7e0e1e7 commit c1992fc
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 24 deletions.
6 changes: 4 additions & 2 deletions config/examples/nrf5340.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ WOLFBOOT_PARTITION_SIZE?=0xEE000
# External Flash offset for application update (1MB)
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0

# External Flash offset for network update (256KB)
WOLFBOOT_PARTITION2_UPDATE_ADDRESS?=0x100000
# External Flash offset for network update at 0x100000 (size=256KB)

# External Flash offset for swap (4KB)
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x140000
Expand All @@ -45,4 +44,7 @@ DEBUG?=0
DEBUG_UART?=1
USE_GCC=1

# Enable support for multiple partitions
CFLAGS_EXTRA+=-DWOLFBOOT_MULTI_PARTITION

CFLAGS_EXTRA+=-DDEBUG_FLASH
7 changes: 7 additions & 0 deletions docs/flash_partitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ The running firmware is responsible for transferring a new firmware image throug
and store it in the secondary slot. If an update is initiated, the bootloader will replace or swap
the firmware in the boot partition at the next reboot.

## Custom Partitions

To support additional custom partitions use the `WOLFBOOT_MULTI_PARTITION` build options.
* Enabled with `CFLAGS_EXTRA+=-DWOLFBOOT_MULTI_PARTITION`.
* Requires implementation of `void* hal_partition_addr(int part, int* is_ext);`.
* Use tools/keytools/sign with `--id 3` or larger (up to 16).
* See `hal/nrf5340.c` for an example.

## Partition status and sector flags

Expand Down
86 changes: 69 additions & 17 deletions hal/nrf5340.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,13 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
uint32_t end = address + len - 1;
uint32_t p;
uint32_t page_sz = (address < FLASH_BASE_NET) ?
FLASH_PAGESZ_APP :
FLASH_PAGESZ_NET;
#ifdef DEBUG_FLASH
wolfBoot_printf("Internal Flash Erase: addr 0x%x, len %d\n", address, len);
#endif
for (p = address; p <= end; p += FLASH_PAGE_SIZE) {
for (p = address; p <= end; p += page_sz) {
/* set both secure and non-secure registers */
NVMC_CONFIG = NVMC_CONFIG_EEN;
NVMC_CONFIGNS = NVMC_CONFIG_EEN;
Expand Down Expand Up @@ -224,44 +227,93 @@ void sleep_us(unsigned int us)
}
}

/* Stringification */
#ifndef WC_STRINGIFY
#define _WC_STRINGIFY_L2(str) #str
#define WC_STRINGIFY(str) _WC_STRINGIFY_L2(str)
#ifdef TARGET_nrf5340_app
void hal_net_core(int hold) /* 1=hold, 0=release*/
{
if (hold) {
/* stop the network core from booting */
NETWORK_FORCEOFF = NETWORK_FORCEOFF_HOLD;
}
else {
/* release network core - errata 161 network core release */
NETWORK_ERRATA_161 = 1;
NETWORK_FORCEOFF = NETWORK_FORCEOFF_RELEASE;
sleep_us(5);
NETWORK_FORCEOFF = NETWORK_FORCEOFF_HOLD;
sleep_us(1);
NETWORK_FORCEOFF = NETWORK_FORCEOFF_RELEASE;
NETWORK_ERRATA_161 = 0;
}
}
#endif

void hal_init(void)
{
#ifdef DEBUG_UART
const char* bootStr = "wolfBoot HAL Init (" CORE_STR " core)\n";
#endif

clock_init();

#ifdef TARGET_nrf5340_app
/* stop the network core from booting */
NETWORK_FORCEOFF = NETWORK_FORCEOFF_HOLD;
/* Configure nRF5340 Network MCU into Secure domain (bus accesses by
* Network MCU will have Secure attribute set).
* This is needed for the network core to be able to read the shared RAM
* area used for IPC. */
SPU_EXTDOMAIN_PERM(0) =
(SPU_EXTDOMAIN_PERM_SECATTR_SECURE | SPU_EXTDOMAIN_PERM_UNLOCK);
#endif

#ifdef DEBUG_UART
uart_init();
uart_write("wolfBoot HAL Init (" CORE_STR " core)\n", 29);
uart_write(bootStr, strlen(bootStr));
#endif

#ifdef TEST_FLASH
if (test_flash() != 0) {
wolfBoot_printf("Internal flash Test Failed!\n");
}
#endif

#ifdef TARGET_nrf5340_net
/* Wait for update or boot command from application core */
#endif
}


#ifdef WOLFBOOT_MULTI_PARTITION
#define PART_NETWORK_CORE 3
#define PART_NETWORK_EXT_ADDR 0x100000UL
void* hal_partition_addr(int part, int* is_ext)
{
void* ptr = NULL;
if (part == PART_NETWORK_CORE) { /* network partition */
/* External Flash offset for network update at 0x100000 (size=256KB) */
ptr = (void*)PART_NETWORK_EXT_ADDR;
*is_ext = 1;
}
return ptr;
}
#endif

void hal_prepare_boot(void)
{
#ifdef TARGET_nrf5340_app
/* release network core - errata 161 network core release */
NETWORK_ERRATA_161 = 1;
NETWORK_FORCEOFF = NETWORK_FORCEOFF_RELEASE;
sleep_us(5);
NETWORK_FORCEOFF = NETWORK_FORCEOFF_HOLD;
sleep_us(1);
NETWORK_FORCEOFF = NETWORK_FORCEOFF_RELEASE;
NETWORK_ERRATA_161 = 0;
#ifdef WOLFBOOT_MULTI_PARTITION
/* check if there is an update for network core */
struct wolfBoot_image net;
int ret = wolfBoot_open_image(&net, PART_NETWORK_CORE);
if (ret == 0) {
wolfBoot_printf("Network version: 0x%x\n",
wolfBoot_get_blob_version(net.hdr));
}
else {
wolfBoot_printf("Failed finding network core update at 0x%x\n",
PART_NETWORK_EXT_ADDR);
}
#endif

/* release network core - issue boot command */
#endif
}

Expand All @@ -270,7 +322,7 @@ void hal_prepare_boot(void)
#ifdef TEST_FLASH

#ifndef TEST_ADDRESS
#define TEST_ADDRESS (0xFA000UL)
#define TEST_ADDRESS (FLASH_BASE_ADDR + (FLASH_SIZE - WOLFBOOT_SECTOR_SIZE))
#endif

/* #define TEST_FLASH_READONLY */
Expand Down
36 changes: 32 additions & 4 deletions hal/nrf5340.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,31 @@
#endif
#endif

/* Clock */
#ifdef TARGET_nrf5340_app
#define CPU_CLOCK 128000000UL /* 128MHz */
#define CPU_CLOCK 128000000UL /* 128MHz */
#else
#define CPU_CLOCK 64000000UL /* 64MHz */
#define CPU_CLOCK 64000000UL /* 64MHz */
#endif

/* Flash */
#define FLASH_PAGESZ_APP (4096) /* 4KB Page */
#define FLASH_BASE_APP (0x00000000)
#define FLASH_SIZE_APP (1024UL * 1024UL) /* 1MB Flash */

#define FLASH_PAGESZ_NET (2048) /* 2KB Page */
#define FLASH_BASE_NET (0x01000000)
#define FLASH_SIZE_NET (256UL * 1024UL) /* 256KB Flash */

#ifdef TARGET_nrf5340_app
#define FLASH_PAGE_SIZE FLASH_PAGESZ_APP
#define FLASH_BASE_ADDR FLASH_BASE_APP
#define FLASH_SIZE FLASH_SIZE_APP
#else
#define FLASH_PAGE_SIZE FLASH_PAGESZ_NET
#define FLASH_BASE_ADDR FLASH_BASE_NET
#define FLASH_SIZE FLASH_SIZE_NET
#endif

/* Assembly helpers */
#define DMB() __asm__ volatile ("dmb")
Expand Down Expand Up @@ -75,6 +94,17 @@ void sleep_us(unsigned int us);
#define DCNF_EXTCODE0_PROT *((volatile uint32_t *)(DCNF_BASE + 0x480))
#endif

#ifdef TARGET_nrf5340_app
/* SPU */
#define SPU_BASE 0x50003000UL
#define SPU_EXTDOMAIN_PERM(n) *((volatile uint32_t *)(SPU_BASE + 0x440 + ((n) * 0x4)))
#define SPU_EXTDOMAIN_PERM_SECATTR_NONSECURE 0
#define SPU_EXTDOMAIN_PERM_SECATTR_SECURE (1 << 4)
#define SPU_EXTDOMAIN_PERM_UNLOCK 0
#define SPU_EXTDOMAIN_PERM_LOCK (1 << 8)
#define SPU_EXTDOMAIN_PERM_SECUREMAPPING_MASK (0x3)
#endif

/* OTP */
#define UICR_BASE (0x00FF8000UL)

Expand Down Expand Up @@ -124,8 +154,6 @@ void sleep_us(unsigned int us);
#define NVMC_WRITEUICRNS_SET 1
#define NVMC_WRITEUICRNS_KEY 0xAFBE5A70

#define FLASH_PAGE_SIZE (4096)

/* Clock control */
#ifdef TARGET_nrf5340_app
#ifdef TZEN
Expand Down
4 changes: 4 additions & 0 deletions include/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ void hal_flash_unlock(void);
void hal_flash_lock(void);
void hal_prepare_boot(void);

#ifdef WOLFBOOT_MULTI_PARTITION
void* hal_partition_addr(int part, int* is_ext);
#endif

#ifdef DUALBANK_SWAP
void hal_flash_dualbank_swap(void);
#endif
Expand Down
7 changes: 6 additions & 1 deletion include/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,15 @@ int keyslot_id_by_sha(const uint8_t *hint);
# else
# define SWAP_EXT 0
# endif
#ifdef WOLFBOOT_MULTI_PARTITION
# define IS_EXT_DEFAULT 1
#else
# define IS_EXT_DEFAULT 0
#endif
# define PARTN_IS_EXT(pn) \
((pn == PART_BOOT || pn == PART_DTS_BOOT) ? BOOT_EXT: \
((pn == PART_UPDATE || pn == PART_DTS_UPDATE) ? UPDATE_EXT : \
((pn == PART_SWAP) ? SWAP_EXT : 0)))
((pn == PART_SWAP) ? SWAP_EXT : IS_EXT_DEFAULT)))
# define PART_IS_EXT(x) (!(x)->not_ext) && PARTN_IS_EXT(((x)->part))


Expand Down
8 changes: 8 additions & 0 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,15 @@ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)
img->hdr = (void*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
}
else {
#ifdef WOLFBOOT_MULTI_PARTITION
int is_ext = 0;
img->hdr = hal_partition_addr(part, &is_ext);
if (img->hdr == NULL)
return -1;
img->not_ext = !is_ext;
#else
return -1;
#endif
}

/* fetch header address
Expand Down

0 comments on commit c1992fc

Please sign in to comment.