From 0791d76d653365107813fadc8ba980155e645665 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 14 Nov 2024 15:44:22 +0100 Subject: [PATCH 01/18] Draft: support for rp2350 --- config/examples/rp2350.config | 25 +++++++++++ hal/rp2350-ns.ld | 50 ++++++++++++++++++++++ hal/rp2350.c | 80 +++++++++++++++++++++++++++++++++++ hal/rp2350.ld | 71 +++++++++++++++++++++++++++++++ 4 files changed, 226 insertions(+) create mode 100644 config/examples/rp2350.config create mode 100644 hal/rp2350-ns.ld create mode 100644 hal/rp2350.c create mode 100644 hal/rp2350.ld diff --git a/config/examples/rp2350.config b/config/examples/rp2350.config new file mode 100644 index 0000000000..bede6d6096 --- /dev/null +++ b/config/examples/rp2350.config @@ -0,0 +1,25 @@ +ARCH?=ARM +TZEN?=0 +TARGET?=rp2350 +SIGN?=ECC256 +HASH?=SHA256 +DEBUG?=0 +VTOR?=1 +CORTEX_M33?=1 +NO_ASM?=0 +NO_MPU=1 +EXT_FLASH?=0 +SPI_FLASH?=0 +ALLOW_DOWNGRADE?=0 +SPMATH?=1 +RAM_CODE?=1 +WOLFBOOT_PARTITION_SIZE?=0x40000 +WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x10040000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=10080000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x100C0000 + +PICO_SDK_PATH=/home/dan/src/pico-sdk + +# Use a larger image header size to enforce alignment requirements for the interrupt vector table +IMAGE_HEADER_SIZE?=1024 diff --git a/hal/rp2350-ns.ld b/hal/rp2350-ns.ld new file mode 100644 index 0000000000..64c5c8d1eb --- /dev/null +++ b/hal/rp2350-ns.ld @@ -0,0 +1,50 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00082000 +} + +SECTIONS +{ + .text : + { + _start_text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + . = ALIGN(8); + _end_text = .; + } > FLASH + + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + + _stored_data = .; + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(8); + KEEP(*(.ramcode)) + . = ALIGN(8); + _end_data = .; + } > RAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + _end_bss = .; + __bss_end__ = .; + _end = .; + } > RAM + . = ALIGN(8); +} + +END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/rp2350.c b/hal/rp2350.c new file mode 100644 index 0000000000..d1d11060d8 --- /dev/null +++ b/hal/rp2350.c @@ -0,0 +1,80 @@ +/* rp2350.c + * + * Stubs for custom HAL implementation. Defines the + * functions used by wolfboot for a specific target. + * + * Copyright (C) 2021 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 "image.h" + + +#define SIO_BASE (0xD0000000U) +#define SIO_CPUID (*(volatile uint32_t *)(SIO_BASE + 0x00)) + +const uint32_t VTOR_ADDR = 0xE000ED08; +const uint32_t BOOTROM_VTABLE_OFFSET = 0x00000000; + +void __attribute__((naked)) jmp_to_rom_vector(void) +{ + __asm volatile( + "ldr r0, =BOOTROM_VTABLE_OFFSET\n" + "ldr r1, =VTOR_ADDR\n" + "str r0, [r1]\n" + "ldmia r0!, {r1, r2}\n" + "msr msp, r1\n" + "bx r2\n" + ); +} + +#ifdef __WOLFBOOT +void hal_init(void) +{ + /* Keep CPU1 in ROM */ + if (SIO_CPUID != 0) { + jmp_to_rom_vector(); + } +} + +void hal_prepare_boot(void) +{ +} + +#endif + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + return 0; /* on success. */ +} + +void RAMFUNCTION hal_flash_unlock(void) +{ +} + +void RAMFUNCTION hal_flash_lock(void) +{ +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + return 0; /* on success. */ +} + diff --git a/hal/rp2350.ld b/hal/rp2350.ld new file mode 100644 index 0000000000..31aca58d9c --- /dev/null +++ b/hal/rp2350.ld @@ -0,0 +1,71 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00012000 + RAM_HEAP (rw): ORIGIN = 0x20012000, LENGTH = 0xc000 /* 49152 B Heap for wolfcrypt/PKCS11 */ + RAM_KV (rw): ORIGIN = 0x2001e000, LENGTH = 0x2000 + FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x18000 + FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x38000, LENGTH = 0x8000 +} + +SECTIONS +{ + .text : + { + _start_text = .; + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + . = ALIGN(8); + _end_text = .; + } > FLASH + + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > FLASH + + .gnu.sgstubs : + { + . += 0x400; + . = ALIGN(4); + *(.gnu.sgstubs*) /* Secure Gateway stubs */ + . = ALIGN(4); + } >FLASH_NSC + + _stored_data = .; + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(8); + KEEP(*(.ramcode)) + . = ALIGN(8); + _end_data = .; + } > RAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + _end_bss = .; + __bss_end__ = .; + _end = .; + } > RAM + . = ALIGN(8); +} + +END_STACK = ORIGIN(RAM) + LENGTH(RAM); + +_keyvault_origin = ORIGIN(RAM_KV); +_keyvault_size = LENGTH(RAM_KV); + +_flash_keyvault = ORIGIN(FLASH_KEYVAULT); +_flash_keyvault_size = LENGTH(FLASH_KEYVAULT); + +_start_heap = ORIGIN(RAM_HEAP); +_heap_size = LENGTH(RAM_HEAP); From 10ddb3e8476ebe2aa09cf91aa40756bea8f74e2a Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 14 Nov 2024 16:05:22 +0100 Subject: [PATCH 02/18] arch.mk: rp2350 --- arch.mk | 16 +++++++++++++++- src/boot_arm.c | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch.mk b/arch.mk index dad4355448..446312a36a 100644 --- a/arch.mk +++ b/arch.mk @@ -221,6 +221,20 @@ ifeq ($(ARCH),ARM) SPI_TARGET=stm32 endif + ifeq ($(TARGET),rp2350) + CORTEX_M33=1 + CFLAGS+=-Ihal + ARCH_FLASH_OFFSET=0x10000000 + WOLFBOOT_ORIGIN=0x10000000 + ifeq ($(TZEN),1) + LSCRIPT_IN=hal/$(TARGET).ld + else + LSCRIPT_IN=hal/$(TARGET)-ns.ld + endif + SPI_TARGET=raspberrypi_pico + CFLAGS+=-DPICO_SDK_PATH=$(PICO_SDK_PATH) + endif + ifeq ($(TARGET),sama5d3) CORTEX_A5=1 UPDATE_OBJS:=src/update_ram.o @@ -1079,7 +1093,7 @@ ifeq ($(TARGET),sim) CFLAGS+=-DWOLFSSL_SP_DIV_WORD_HALF endif ifeq ($(WOLFHSM_CLIENT),1) - WOLFHSM_CLIENT_OBJS += $(LIBDIR)/wolfHSM/port/posix/posix_transport_tcp.o + WOLFHSM_CLIENT_OBJS += $(LIBDIR)/wolfHSM/port/posix/posix_transport_tcp.o endif endif diff --git a/src/boot_arm.c b/src/boot_arm.c index d975365c04..0a5faaf3c2 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -527,7 +527,7 @@ void (* const IV[])(void) = /* Fill with extra unused handlers */ #if defined(TARGET_stm32l5) || defined(TARGET_stm32u5) || \ - defined(TARGET_stm32h7) + defined(TARGET_stm32h7) || defined(TARGET_rp2350) isr_empty, isr_empty, isr_empty, From 628fbe5524dde473ad498a014c05e25125e3c953 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Wed, 4 Dec 2024 17:11:46 +0100 Subject: [PATCH 03/18] Using CMake from IDE directory --- IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt | 72 ++++++++++++++++++++ IDE/pico-sdk/rp23550/wolfboot/README.md | 9 +++ hal/rp2350.ld | 71 ------------------- src/update_flash.c | 5 ++ 4 files changed, 86 insertions(+), 71 deletions(-) create mode 100644 IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt create mode 100644 IDE/pico-sdk/rp23550/wolfboot/README.md delete mode 100644 hal/rp2350.ld diff --git a/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt b/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt new file mode 100644 index 0000000000..67840f083d --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.13) +set(WOLFBOOT_PATH ../../../../) +set(CMAKE_CXX_COMPILER arm-none-eabi-gcc) + +include(${PICO_SDK_PATH}/pico_sdk_init.cmake) + +set(PICOTOOL_FETCH_FROM_GIT_PATH 1) + +project(wolfboot) + +# initialize the Raspberry Pi Pico SDK +pico_sdk_init() + + +add_executable(wolfboot + ${WOLFBOOT_PATH}/src/image.c + ${WOLFBOOT_PATH}/src/loader.c + ${WOLFBOOT_PATH}/src/update_flash.c + ${WOLFBOOT_PATH}/src/keystore.c + ${WOLFBOOT_PATH}/src/libwolfboot.c + ${WOLFBOOT_PATH}/src/boot_arm.c + + ${WOLFBOOT_PATH}/hal/rp2350.c + + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/sp_int.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/sp_cortexm.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/memory.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/random.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/sha256.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/sha512.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/aes.c + ${WOLFBOOT_PATH}/lib/wolfssl/wolfcrypt/src/ecc.c +) + +# Add cflags +target_compile_options(wolfboot PRIVATE + -D__WOLFBOOT + -D__ARM_ARCH_6M__ + -DWOLFSSL_USER_SETTINGS + -mcpu=cortex-m33 + -DCORTEX_M33 + -DWOLFSSL_SP_ASM + -DWOLFSSL_SP_ARM_CORTEX_M_ASM + -DWOLFSSL_ARM_ARCH=8 + -DARCH_FLASH_OFFSET=0x10000000 + -DWOLFBOOT_ORIGIN=0x10000000 + -DBOOTLOADER_PARTITION_SIZE=0x40000 + -DWOLFBOOT_ARCH_ARM + -DTARGET_rp2350 + -DWOLFBOOT_SIGN_ECC256 + -DRAM_CODE + -DFILL_BYTE=0xFF + -Os + -DWOLFBOOT_NO_MPU + -DWOLFBOOT_HASH_SHA256 + -DIMAGE_HEADER_SIZE=1024 + -Wstack-usage=7632 +) + + +target_include_directories(wolfboot PRIVATE + ${WOLFBOOT_PATH}/include + ${WOLFBOOT_PATH}/lib/wolfssl +) + +target_link_libraries(wolfboot pico_stdlib hardware_flash) + +pico_enable_stdio_usb(wolfboot 1) +pico_enable_stdio_uart(wolfboot 0) + + +pico_add_extra_outputs(wolfboot) diff --git a/IDE/pico-sdk/rp23550/wolfboot/README.md b/IDE/pico-sdk/rp23550/wolfboot/README.md new file mode 100644 index 0000000000..5acac952ff --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/README.md @@ -0,0 +1,9 @@ +### Building wolfBoot for raspberry pico 2 + +``` +mkdir build +cd build +cmake .. -DPICO_SDK_PATH=path/to/pico-sdk -DFAMILY=rp2350 +make +``` + diff --git a/hal/rp2350.ld b/hal/rp2350.ld deleted file mode 100644 index 31aca58d9c..0000000000 --- a/hal/rp2350.ld +++ /dev/null @@ -1,71 +0,0 @@ -MEMORY -{ - FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00012000 - RAM_HEAP (rw): ORIGIN = 0x20012000, LENGTH = 0xc000 /* 49152 B Heap for wolfcrypt/PKCS11 */ - RAM_KV (rw): ORIGIN = 0x2001e000, LENGTH = 0x2000 - FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x18000 - FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x38000, LENGTH = 0x8000 -} - -SECTIONS -{ - .text : - { - _start_text = .; - KEEP(*(.isr_vector)) - *(.text*) - *(.rodata*) - . = ALIGN(8); - _end_text = .; - } > FLASH - - .edidx : - { - . = ALIGN(4); - *(.ARM.exidx*) - } > FLASH - - .gnu.sgstubs : - { - . += 0x400; - . = ALIGN(4); - *(.gnu.sgstubs*) /* Secure Gateway stubs */ - . = ALIGN(4); - } >FLASH_NSC - - _stored_data = .; - .data : AT (_stored_data) - { - _start_data = .; - KEEP(*(.data*)) - . = ALIGN(8); - KEEP(*(.ramcode)) - . = ALIGN(8); - _end_data = .; - } > RAM - - .bss (NOLOAD) : - { - _start_bss = .; - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(8); - _end_bss = .; - __bss_end__ = .; - _end = .; - } > RAM - . = ALIGN(8); -} - -END_STACK = ORIGIN(RAM) + LENGTH(RAM); - -_keyvault_origin = ORIGIN(RAM_KV); -_keyvault_size = LENGTH(RAM_KV); - -_flash_keyvault = ORIGIN(FLASH_KEYVAULT); -_flash_keyvault_size = LENGTH(FLASH_KEYVAULT); - -_start_heap = ORIGIN(RAM_HEAP); -_heap_size = LENGTH(RAM_HEAP); diff --git a/src/update_flash.c b/src/update_flash.c index 914b0b4833..ad93b6ac32 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -39,7 +39,12 @@ int WP11_Library_Init(void); #endif #ifdef RAM_CODE +#ifndef TARGET_rp2350 extern unsigned int _start_text; +#else +extern unsigned int __logical_binary_start; +unsigned int _start_text = (unsigned int)&__logical_binary_start; +#endif static volatile const uint32_t __attribute__((used)) wolfboot_version = WOLFBOOT_VERSION; #ifdef EXT_FLASH From 359c59fa479a57b924bc779412f565b28a750b93 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 5 Dec 2024 13:23:17 +0100 Subject: [PATCH 04/18] Added IDE/pico-sdk dir to build wolfboot+blink app --- .gitignore | 4 ++ IDE/pico-sdk/rp23550/test-app/CMakeLists.txt | 24 +++++++++ IDE/pico-sdk/rp23550/test-app/blink.c | 53 +++++++++++++++++++ .../rp23550/test-app/build-signed-app.sh | 14 +++++ IDE/pico-sdk/rp23550/test-app/flash_app.jlink | 6 +++ IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt | 2 +- .../rp23550/wolfboot/build-wolfboot.sh | 10 ++++ IDE/pico-sdk/rp23550/wolfboot/debug.sh | 2 + IDE/pico-sdk/rp23550/wolfboot/erase.jlink | 6 +++ .../rp23550/wolfboot/flash_wolfboot.jlink | 6 +++ Makefile | 7 +++ arch.mk | 1 + config/examples/rp2350.config | 8 +-- docs/Targets.md | 5 ++ hal/rp2350-ns.ld | 50 ----------------- hal/rp2350.c | 27 ++-------- src/boot_arm.c | 4 +- 17 files changed, 149 insertions(+), 80 deletions(-) create mode 100644 IDE/pico-sdk/rp23550/test-app/CMakeLists.txt create mode 100644 IDE/pico-sdk/rp23550/test-app/blink.c create mode 100755 IDE/pico-sdk/rp23550/test-app/build-signed-app.sh create mode 100644 IDE/pico-sdk/rp23550/test-app/flash_app.jlink create mode 100755 IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh create mode 100755 IDE/pico-sdk/rp23550/wolfboot/debug.sh create mode 100644 IDE/pico-sdk/rp23550/wolfboot/erase.jlink create mode 100644 IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink delete mode 100644 hal/rp2350-ns.ld diff --git a/.gitignore b/.gitignore index d229addd5a..ce006b5746 100644 --- a/.gitignore +++ b/.gitignore @@ -231,6 +231,10 @@ IDE/Renesas/e2studio/RX72N/app_RenesasRX01/src/smc_gen IDE/Renesas/e2studio/RX72N/wolfBoot/HardwareDebug IDE/Renesas/e2studio/RX72N/wolfBoot/src/smc_gen +# IDE pico-sdk build directories +IDE/pico-sdk/rp23550/wolfboot/build +IDE/pico-sdk/rp23550/test-app/build + # Renesas Libraries lib/r_bsp lib/r_config diff --git a/IDE/pico-sdk/rp23550/test-app/CMakeLists.txt b/IDE/pico-sdk/rp23550/test-app/CMakeLists.txt new file mode 100644 index 0000000000..cd7825a586 --- /dev/null +++ b/IDE/pico-sdk/rp23550/test-app/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.13) +set(WOLFBOOT_PATH ../../../../) +set(CMAKE_CXX_COMPILER arm-none-eabi-gcc) + +include(${PICO_SDK_PATH}/pico_sdk_init.cmake) + +set(PICOTOOL_FETCH_FROM_GIT_PATH ../wolfboot/build/picotool) +set(BOOT_STAGE2_FILE ${CMAKE_CURRENT_LIST_DIR}/boot2_empty.S) + +project(blink) + +# initialize the Raspberry Pi Pico SDK +pico_sdk_init() + + +add_executable(blink + blink.c +) + +target_link_libraries(blink pico_stdlib) + +# create map/bin/hex/uf2 file etc. +pico_add_extra_outputs(blink) + diff --git a/IDE/pico-sdk/rp23550/test-app/blink.c b/IDE/pico-sdk/rp23550/test-app/blink.c new file mode 100644 index 0000000000..e588b0e8a3 --- /dev/null +++ b/IDE/pico-sdk/rp23550/test-app/blink.c @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/stdlib.h" + +// Pico W devices use a GPIO on the WIFI chip for the LED, +// so when building for Pico W, CYW43_WL_GPIO_LED_PIN will be defined +#ifdef CYW43_WL_GPIO_LED_PIN +#include "pico/cyw43_arch.h" +#endif + +#ifndef LED_DELAY_MS +#define LED_DELAY_MS 250 +#endif + +// Perform initialisation +int pico_led_init(void) { +#if defined(PICO_DEFAULT_LED_PIN) + // A device like Pico that uses a GPIO for the LED will define PICO_DEFAULT_LED_PIN + // so we can use normal GPIO functionality to turn the led on and off + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + return PICO_OK; +#elif defined(CYW43_WL_GPIO_LED_PIN) + // For Pico W devices we need to initialise the driver etc + return cyw43_arch_init(); +#endif +} + +// Turn the led on or off +void pico_set_led(bool led_on) { +#if defined(PICO_DEFAULT_LED_PIN) + // Just set the GPIO on or off + gpio_put(PICO_DEFAULT_LED_PIN, led_on); +#elif defined(CYW43_WL_GPIO_LED_PIN) + // Ask the wifi "driver" to set the GPIO on or off + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); +#endif +} + +int main() { + int rc = pico_led_init(); + hard_assert(rc == PICO_OK); + while (true) { + pico_set_led(true); + sleep_ms(LED_DELAY_MS); + pico_set_led(false); + sleep_ms(LED_DELAY_MS); + } +} diff --git a/IDE/pico-sdk/rp23550/test-app/build-signed-app.sh b/IDE/pico-sdk/rp23550/test-app/build-signed-app.sh new file mode 100755 index 0000000000..e2605383c2 --- /dev/null +++ b/IDE/pico-sdk/rp23550/test-app/build-signed-app.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +mkdir -p build +cd build +cmake .. -DPICO_SDK_PATH=$PICO_SDK_PATH -DPICO_PLATFORM=rp2350 +cat pico_flash_region.ld | sed -e "s/0x10000000/0x10040400/g" >pico_flash_region_wolfboot.ld +cp pico_flash_region_wolfboot.ld pico_flash_region.ld +make clean && make +../../../../../tools/keytools/sign --sha256 --ecc256 blink.bin \ + ../../../../../wolfboot_signing_private_key.der 1 + +cd .. + +JLinkExe -Device RP2350_M33_0 -If swd -Speed 4000 -CommanderScript flash_app.jlink diff --git a/IDE/pico-sdk/rp23550/test-app/flash_app.jlink b/IDE/pico-sdk/rp23550/test-app/flash_app.jlink new file mode 100644 index 0000000000..d0d9e4bd10 --- /dev/null +++ b/IDE/pico-sdk/rp23550/test-app/flash_app.jlink @@ -0,0 +1,6 @@ +connect +r +loadfile build/blink_v1_signed.bin 0x10040000 +r +g +exit diff --git a/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt b/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt index 67840f083d..5ae1fb32b7 100644 --- a/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt +++ b/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt @@ -4,7 +4,7 @@ set(CMAKE_CXX_COMPILER arm-none-eabi-gcc) include(${PICO_SDK_PATH}/pico_sdk_init.cmake) -set(PICOTOOL_FETCH_FROM_GIT_PATH 1) +set(PICOTOOL_FETCH_FROM_GIT_PATH build/picotool) project(wolfboot) diff --git a/IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh b/IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh new file mode 100755 index 0000000000..8a96587a72 --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh @@ -0,0 +1,10 @@ +#!/bin/bash +#cd ../../../.. && make keytools && make src/keystore.c && cd - +cd ../../../.. && make include/target.h && cd - +mkdir -p build +cd build +cmake .. -DPICO_SDK_PATH=$PICO_SDK_PATH -DPICO_PLATFORM=rp2350 +make clean && make +cd .. +JLinkExe -Device RP2350_M33_0 -If swd -Speed 4000 -CommanderScript erase.jlink +JLinkExe -Device RP2350_M33_0 -If swd -Speed 4000 -CommanderScript flash_wolfboot.jlink diff --git a/IDE/pico-sdk/rp23550/wolfboot/debug.sh b/IDE/pico-sdk/rp23550/wolfboot/debug.sh new file mode 100755 index 0000000000..008ad0a8d1 --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/debug.sh @@ -0,0 +1,2 @@ +#!/bin/bash +JLinkGDBServer -Device RP2350_M33_0 -If swd -Speed 4000 -port 3333 diff --git a/IDE/pico-sdk/rp23550/wolfboot/erase.jlink b/IDE/pico-sdk/rp23550/wolfboot/erase.jlink new file mode 100644 index 0000000000..a4f1f72aa9 --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/erase.jlink @@ -0,0 +1,6 @@ +connect +r +erase +r +h +exit diff --git a/IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink b/IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink new file mode 100644 index 0000000000..bc05150109 --- /dev/null +++ b/IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink @@ -0,0 +1,6 @@ +connect +r +loadfile build/wolfboot.bin 0x10000000 +r +g +exit diff --git a/Makefile b/Makefile index be8d577c3b..525ecbfc17 100644 --- a/Makefile +++ b/Makefile @@ -148,6 +148,10 @@ ifeq ($(TARGET),sama5d3) MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin endif +ifeq ($(TARGET),rp2350) + MAIN_TARGET:=include/target.h keytools wolfboot_signing_private_key.der pico-sdk-info +endif + ifeq ($(FLASH_OTP_KEYSTORE),1) MAIN_TARGET+=tools/keytools/otp/otp-keystore-primer.bin @@ -451,6 +455,9 @@ secondary: $(SECONDARY_PRIVATE_KEY) src/x86/fsp_s.o: $(FSP_S_BIN) $(OBJCOPY) -I binary -O elf64-x86-64 -B i386 --rename-section .data=.fsp_s $^ $@ +pico-sdk-info: FORCE + @echo "To complete the build, check IDE/pico-sdk/rp2350" + FORCE: .PHONY: FORCE clean keytool_check diff --git a/arch.mk b/arch.mk index 446312a36a..990cedf070 100644 --- a/arch.mk +++ b/arch.mk @@ -233,6 +233,7 @@ ifeq ($(ARCH),ARM) endif SPI_TARGET=raspberrypi_pico CFLAGS+=-DPICO_SDK_PATH=$(PICO_SDK_PATH) + CFLAGS+=-I$(PICO_SDK_PATH)/src/common/pico_stdlib_headers/include endif ifeq ($(TARGET),sama5d3) diff --git a/config/examples/rp2350.config b/config/examples/rp2350.config index bede6d6096..bf08911a67 100644 --- a/config/examples/rp2350.config +++ b/config/examples/rp2350.config @@ -13,11 +13,11 @@ SPI_FLASH?=0 ALLOW_DOWNGRADE?=0 SPMATH?=1 RAM_CODE?=1 -WOLFBOOT_PARTITION_SIZE?=0x40000 +WOLFBOOT_PARTITION_SIZE?=0xC0000 WOLFBOOT_SECTOR_SIZE?=0x2000 -WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x10040000 -WOLFBOOT_PARTITION_UPDATE_ADDRESS?=10080000 -WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x100C0000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x10040000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x10100000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x101C0000 PICO_SDK_PATH=/home/dan/src/pico-sdk diff --git a/docs/Targets.md b/docs/Targets.md index 6f81d9ac2c..fdc1242c74 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -23,6 +23,7 @@ This README describes configuration of supported targets. * [NXP T1024 PPC](#nxp-qoriq-t1024-ppc) * [NXP T2080 PPC](#nxp-qoriq-t2080-ppc) * [Qemu x86-64 UEFI](#qemu-x86-64-uefi) +* [Raspberry Pi pico 2 (rp2350)](#raspberry-pi-pico-rp2350) * [Renesas RA6M4](#renesas-ra6m4) * [Renesas RX65N](#renesas-rx65n) * [Renesas RX72N](#renesas-rx72n) @@ -2511,6 +2512,10 @@ make test-sim-internal-flash-with-update Note: This also works on Mac OS, but `objcopy` does not exist. Install with `brew install binutils` and make using `OBJCOPY=/usr/local/Cellar//binutils/2.41/bin/objcopy make`. +## Raspberry Pi Pico rp2350 + +See instructions in [IDE/pico-sdk/rp2350/README.md](/IDE/pico-sdk/rp2350/README.md) + ## Renesas RX65N Tested on the: diff --git a/hal/rp2350-ns.ld b/hal/rp2350-ns.ld deleted file mode 100644 index 64c5c8d1eb..0000000000 --- a/hal/rp2350-ns.ld +++ /dev/null @@ -1,50 +0,0 @@ -MEMORY -{ - FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00082000 -} - -SECTIONS -{ - .text : - { - _start_text = .; - KEEP(*(.isr_vector)) - *(.text*) - *(.rodata*) - . = ALIGN(8); - _end_text = .; - } > FLASH - - .edidx : - { - . = ALIGN(4); - *(.ARM.exidx*) - } > FLASH - - _stored_data = .; - .data : AT (_stored_data) - { - _start_data = .; - KEEP(*(.data*)) - . = ALIGN(8); - KEEP(*(.ramcode)) - . = ALIGN(8); - _end_data = .; - } > RAM - - .bss (NOLOAD) : - { - _start_bss = .; - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(8); - _end_bss = .; - __bss_end__ = .; - _end = .; - } > RAM - . = ALIGN(8); -} - -END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/rp2350.c b/hal/rp2350.c index d1d11060d8..c47c4a71c5 100644 --- a/hal/rp2350.c +++ b/hal/rp2350.c @@ -25,33 +25,14 @@ #include #include #include "image.h" - - -#define SIO_BASE (0xD0000000U) -#define SIO_CPUID (*(volatile uint32_t *)(SIO_BASE + 0x00)) - -const uint32_t VTOR_ADDR = 0xE000ED08; -const uint32_t BOOTROM_VTABLE_OFFSET = 0x00000000; - -void __attribute__((naked)) jmp_to_rom_vector(void) -{ - __asm volatile( - "ldr r0, =BOOTROM_VTABLE_OFFSET\n" - "ldr r1, =VTOR_ADDR\n" - "str r0, [r1]\n" - "ldmia r0!, {r1, r2}\n" - "msr msp, r1\n" - "bx r2\n" - ); -} +#include "printf.h" #ifdef __WOLFBOOT void hal_init(void) { - /* Keep CPU1 in ROM */ - if (SIO_CPUID != 0) { - jmp_to_rom_vector(); - } +#ifdef PRINTF_ENABLED + stdio_init_all(); +#endif } void hal_prepare_boot(void) diff --git a/src/boot_arm.c b/src/boot_arm.c index 0a5faaf3c2..a1f2790e42 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -397,7 +397,7 @@ void isr_empty(void) -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && defined(TZEN) # define isr_securefault isr_fault #else # define isr_securefault 0 @@ -446,7 +446,7 @@ void RAMFUNCTION do_boot(const uint32_t *app_offset) /* Update IV */ VTOR = ((uint32_t)app_offset); asm volatile("msr msplim, %0" ::"r"(0)); -# if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +# if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && defined(TZEN) asm volatile("msr msp_ns, %0" ::"r"(app_end_stack)); /* Jump to non secure app_entry */ asm volatile("mov r7, %0" ::"r"(app_entry)); From a0cbbbf597ffedfa2be50014603055dcef9029f7 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 5 Dec 2024 13:25:45 +0100 Subject: [PATCH 05/18] Renamed directory --- IDE/pico-sdk/{rp23550 => rp2350}/test-app/CMakeLists.txt | 0 IDE/pico-sdk/{rp23550 => rp2350}/test-app/blink.c | 0 IDE/pico-sdk/{rp23550 => rp2350}/test-app/build-signed-app.sh | 0 IDE/pico-sdk/{rp23550 => rp2350}/test-app/flash_app.jlink | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/CMakeLists.txt | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/README.md | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/build-wolfboot.sh | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/debug.sh | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/erase.jlink | 0 IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/flash_wolfboot.jlink | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename IDE/pico-sdk/{rp23550 => rp2350}/test-app/CMakeLists.txt (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/test-app/blink.c (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/test-app/build-signed-app.sh (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/test-app/flash_app.jlink (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/CMakeLists.txt (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/README.md (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/build-wolfboot.sh (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/debug.sh (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/erase.jlink (100%) rename IDE/pico-sdk/{rp23550 => rp2350}/wolfboot/flash_wolfboot.jlink (100%) diff --git a/IDE/pico-sdk/rp23550/test-app/CMakeLists.txt b/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt similarity index 100% rename from IDE/pico-sdk/rp23550/test-app/CMakeLists.txt rename to IDE/pico-sdk/rp2350/test-app/CMakeLists.txt diff --git a/IDE/pico-sdk/rp23550/test-app/blink.c b/IDE/pico-sdk/rp2350/test-app/blink.c similarity index 100% rename from IDE/pico-sdk/rp23550/test-app/blink.c rename to IDE/pico-sdk/rp2350/test-app/blink.c diff --git a/IDE/pico-sdk/rp23550/test-app/build-signed-app.sh b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh similarity index 100% rename from IDE/pico-sdk/rp23550/test-app/build-signed-app.sh rename to IDE/pico-sdk/rp2350/test-app/build-signed-app.sh diff --git a/IDE/pico-sdk/rp23550/test-app/flash_app.jlink b/IDE/pico-sdk/rp2350/test-app/flash_app.jlink similarity index 100% rename from IDE/pico-sdk/rp23550/test-app/flash_app.jlink rename to IDE/pico-sdk/rp2350/test-app/flash_app.jlink diff --git a/IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt b/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/CMakeLists.txt rename to IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt diff --git a/IDE/pico-sdk/rp23550/wolfboot/README.md b/IDE/pico-sdk/rp2350/wolfboot/README.md similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/README.md rename to IDE/pico-sdk/rp2350/wolfboot/README.md diff --git a/IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh b/IDE/pico-sdk/rp2350/wolfboot/build-wolfboot.sh similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/build-wolfboot.sh rename to IDE/pico-sdk/rp2350/wolfboot/build-wolfboot.sh diff --git a/IDE/pico-sdk/rp23550/wolfboot/debug.sh b/IDE/pico-sdk/rp2350/wolfboot/debug.sh similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/debug.sh rename to IDE/pico-sdk/rp2350/wolfboot/debug.sh diff --git a/IDE/pico-sdk/rp23550/wolfboot/erase.jlink b/IDE/pico-sdk/rp2350/wolfboot/erase.jlink similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/erase.jlink rename to IDE/pico-sdk/rp2350/wolfboot/erase.jlink diff --git a/IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink b/IDE/pico-sdk/rp2350/wolfboot/flash_wolfboot.jlink similarity index 100% rename from IDE/pico-sdk/rp23550/wolfboot/flash_wolfboot.jlink rename to IDE/pico-sdk/rp2350/wolfboot/flash_wolfboot.jlink From dedfce9440101a63a1a69a73bfb773b8aa7a7c3b Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 5 Dec 2024 13:37:07 +0100 Subject: [PATCH 06/18] Test application distributed off-tree --- .gitignore | 7 ++- IDE/pico-sdk/rp2350/test-app/blink.c | 53 ------------------- .../rp2350/test-app/build-signed-app.sh | 4 ++ 3 files changed, 9 insertions(+), 55 deletions(-) delete mode 100644 IDE/pico-sdk/rp2350/test-app/blink.c diff --git a/.gitignore b/.gitignore index ce006b5746..0da8e1b290 100644 --- a/.gitignore +++ b/.gitignore @@ -232,8 +232,11 @@ IDE/Renesas/e2studio/RX72N/wolfBoot/HardwareDebug IDE/Renesas/e2studio/RX72N/wolfBoot/src/smc_gen # IDE pico-sdk build directories -IDE/pico-sdk/rp23550/wolfboot/build -IDE/pico-sdk/rp23550/test-app/build +IDE/pico-sdk/rp2350/wolfboot/build +IDE/pico-sdk/rp2350/test-app/build + +# Third party test application distributed off-tree +IDE/pico-sdk/rp2350/test-app/blink.c # Renesas Libraries lib/r_bsp diff --git a/IDE/pico-sdk/rp2350/test-app/blink.c b/IDE/pico-sdk/rp2350/test-app/blink.c deleted file mode 100644 index e588b0e8a3..0000000000 --- a/IDE/pico-sdk/rp2350/test-app/blink.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "pico/stdlib.h" - -// Pico W devices use a GPIO on the WIFI chip for the LED, -// so when building for Pico W, CYW43_WL_GPIO_LED_PIN will be defined -#ifdef CYW43_WL_GPIO_LED_PIN -#include "pico/cyw43_arch.h" -#endif - -#ifndef LED_DELAY_MS -#define LED_DELAY_MS 250 -#endif - -// Perform initialisation -int pico_led_init(void) { -#if defined(PICO_DEFAULT_LED_PIN) - // A device like Pico that uses a GPIO for the LED will define PICO_DEFAULT_LED_PIN - // so we can use normal GPIO functionality to turn the led on and off - gpio_init(PICO_DEFAULT_LED_PIN); - gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); - return PICO_OK; -#elif defined(CYW43_WL_GPIO_LED_PIN) - // For Pico W devices we need to initialise the driver etc - return cyw43_arch_init(); -#endif -} - -// Turn the led on or off -void pico_set_led(bool led_on) { -#if defined(PICO_DEFAULT_LED_PIN) - // Just set the GPIO on or off - gpio_put(PICO_DEFAULT_LED_PIN, led_on); -#elif defined(CYW43_WL_GPIO_LED_PIN) - // Ask the wifi "driver" to set the GPIO on or off - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); -#endif -} - -int main() { - int rc = pico_led_init(); - hard_assert(rc == PICO_OK); - while (true) { - pico_set_led(true); - sleep_ms(LED_DELAY_MS); - pico_set_led(false); - sleep_ms(LED_DELAY_MS); - } -} diff --git a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh index e2605383c2..d474c29217 100755 --- a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh +++ b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh @@ -5,6 +5,10 @@ cd build cmake .. -DPICO_SDK_PATH=$PICO_SDK_PATH -DPICO_PLATFORM=rp2350 cat pico_flash_region.ld | sed -e "s/0x10000000/0x10040400/g" >pico_flash_region_wolfboot.ld cp pico_flash_region_wolfboot.ld pico_flash_region.ld + +# Get off-tree source file from raspberry pico-examples +curl -o blink.c https://raw.githubusercontent.com/raspberrypi/pico-examples/refs/tags/sdk-2.1.0/blink/blink.c + make clean && make ../../../../../tools/keytools/sign --sha256 --ecc256 blink.bin \ ../../../../../wolfboot_signing_private_key.der 1 From d8372b000c86a359a3b2119cfef4521005648374 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 5 Dec 2024 13:39:08 +0100 Subject: [PATCH 07/18] Removed old README.md --- IDE/pico-sdk/rp2350/wolfboot/README.md | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 IDE/pico-sdk/rp2350/wolfboot/README.md diff --git a/IDE/pico-sdk/rp2350/wolfboot/README.md b/IDE/pico-sdk/rp2350/wolfboot/README.md deleted file mode 100644 index 5acac952ff..0000000000 --- a/IDE/pico-sdk/rp2350/wolfboot/README.md +++ /dev/null @@ -1,9 +0,0 @@ -### Building wolfBoot for raspberry pico 2 - -``` -mkdir build -cd build -cmake .. -DPICO_SDK_PATH=path/to/pico-sdk -DFAMILY=rp2350 -make -``` - From 343053b6af791093fecf779b1d1e7a9a1e537014 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 6 Dec 2024 10:07:36 +0100 Subject: [PATCH 08/18] [pico-sdk/rp2350] Added README.md, .gdbinit --- IDE/pico-sdk/rp2350/README.md | 95 +++++++++++++++++++++++++++ IDE/pico-sdk/rp2350/wolfboot/.gdbinit | 5 ++ 2 files changed, 100 insertions(+) create mode 100644 IDE/pico-sdk/rp2350/README.md create mode 100644 IDE/pico-sdk/rp2350/wolfboot/.gdbinit diff --git a/IDE/pico-sdk/rp2350/README.md b/IDE/pico-sdk/rp2350/README.md new file mode 100644 index 0000000000..b3290fcd09 --- /dev/null +++ b/IDE/pico-sdk/rp2350/README.md @@ -0,0 +1,95 @@ +## wolfBoot port for rp2350 (Raspberry pi pico 2) + +### Requirements + +#### External debugger + +As the two images (bootloader + application) are stored in different areas in +the flash memory, a SWD connector is required to upload the binary images into +the flash, as opposed to the default bootloader, allowing to upload non-signed +applications into a storage device + +#### PicoSDK + +Clone the repository from raspberrypi's github: + +``` +git clone https://github.com/raspberrypi/pico-sdk.git +``` + +Export the `PICO_SDK_PATH` environment variable to point to the pico-sdk directory: + +``` +export PICO_SDK_PATH=/path/to/pico-sdk +``` + +### Configuring wolfBoot to build with pico-sdk + +From wolfBoot root directory, copy the example configuration: + +``` +cp config/examples/rp2350.config .config +``` + +By default, the config file indicates the following partition layout: + +``` +wolfBoot partition: 256 KB, at address 0x10000000 to 0x1003FFFF +Boot partition: 768 KB, at address 0x10040000 to 0x1007FFFF +Update partition: 768 KB, at address 0x10100000 to 0x1013FFFF +Swap space: 4 KB, at address 0x101C0000 to 0x101C0FFF +Unused flash space: 252 KB, at address 0x101C1000 to 0x101FFFFF +``` + +You can now edit the .config file to change partition sizes/offsets, algorithms, +add/remove features, etc. + +When the configuration is complete, run `make`. This will: + +- Build the key tools (keygen & sign): +- Generate the configuration header `target.h` +- Generate a new keypair (only once), and place the public key in the +keystore + +The environment has now been prepared to build and flash the two images +(wolfBoot + test application). + +### Building and uploading wolfBoot.bin + +After preparing the configuration and creating the keypair, +return to this directory and run: + +``` +cd wolfboot +./build-wolfboot.sh +``` + +The script above will compile wolfboot as rp2350 second-stage bootloader. +This version of wolfboot incorporates the `.boot2` sequence needed to enable +the QSPI device, provided by the pico-sdk and always embedded in all +applications. + +wolfboot.bin contains the bootloader, configured as follows: + +### Building and uploading the application + +``` +cd test-app +./build-signed-app.sh +``` +The script above will compile the test application and sign it with the +wolfBoot private key. The signed application is then uploaded to the boot +partition of the flash memory, at address 0x10040000. + +The linker script included is modified to change the application entry point +from 0x10000000 to 0x10040400, which is the start of the application code, +taking into account the wolfBoot header size. + + +### Testing the application + +The application is a simple blinky example, which toggles the LED on the board +every 500ms. + +If the above steps are successful, the LED on the board should start blinking. + diff --git a/IDE/pico-sdk/rp2350/wolfboot/.gdbinit b/IDE/pico-sdk/rp2350/wolfboot/.gdbinit new file mode 100644 index 0000000000..6facaeb01d --- /dev/null +++ b/IDE/pico-sdk/rp2350/wolfboot/.gdbinit @@ -0,0 +1,5 @@ +tar rem:3333 +file build/wolfboot.elf +add-symbol-file ../test-app/build/blink.elf +foc c + From b19d9d6b3959533a5d95a4a27ba0784d3c47abfb Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 6 Dec 2024 12:30:34 +0100 Subject: [PATCH 09/18] Fixed IMAGE_HEADER_SIZE in rp2350 test-app --- IDE/pico-sdk/rp2350/test-app/build-signed-app.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh index d474c29217..e96eaca480 100755 --- a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh +++ b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh @@ -10,7 +10,8 @@ cp pico_flash_region_wolfboot.ld pico_flash_region.ld curl -o blink.c https://raw.githubusercontent.com/raspberrypi/pico-examples/refs/tags/sdk-2.1.0/blink/blink.c make clean && make -../../../../../tools/keytools/sign --sha256 --ecc256 blink.bin \ + +IMAGE_HEADER_SIZE=1024 ../../../../../tools/keytools/sign --sha256 --ecc256 blink.bin \ ../../../../../wolfboot_signing_private_key.der 1 cd .. From ae82a60a88dc2cb83d1ca266590c10c4c15ea38e Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 20 Dec 2024 16:11:24 +0100 Subject: [PATCH 10/18] rp2350: custom ldscript + TZEN work in progress --- IDE/pico-sdk/rp2350/test-app/CMakeLists.txt | 1 + .../rp2350/test-app/build-signed-app.sh | 2 - IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt | 3 +- hal/{stm32_tz.h => armv8m_tz.h} | 6 +- hal/rp2350-app.ld | 302 ++++++++++++++++++ hal/rp2350.c | 151 +++++++++ hal/rp2350.ld | 302 ++++++++++++++++++ hal/stm32_tz.c | 2 +- 8 files changed, 762 insertions(+), 7 deletions(-) rename hal/{stm32_tz.h => armv8m_tz.h} (96%) create mode 100644 hal/rp2350-app.ld create mode 100644 hal/rp2350.ld diff --git a/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt b/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt index cd7825a586..4de7c6938b 100644 --- a/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt +++ b/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable(blink blink.c ) +pico_set_linker_script(blink ../../../../../hal/rp2350-app.ld) target_link_libraries(blink pico_stdlib) # create map/bin/hex/uf2 file etc. diff --git a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh index e96eaca480..ab42ef263c 100755 --- a/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh +++ b/IDE/pico-sdk/rp2350/test-app/build-signed-app.sh @@ -3,8 +3,6 @@ mkdir -p build cd build cmake .. -DPICO_SDK_PATH=$PICO_SDK_PATH -DPICO_PLATFORM=rp2350 -cat pico_flash_region.ld | sed -e "s/0x10000000/0x10040400/g" >pico_flash_region_wolfboot.ld -cp pico_flash_region_wolfboot.ld pico_flash_region.ld # Get off-tree source file from raspberry pico-examples curl -o blink.c https://raw.githubusercontent.com/raspberrypi/pico-examples/refs/tags/sdk-2.1.0/blink/blink.c diff --git a/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt b/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt index 5ae1fb32b7..5cf1880ab1 100644 --- a/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt +++ b/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) -set(WOLFBOOT_PATH ../../../../) +set(WOLFBOOT_PATH ../../../..) set(CMAKE_CXX_COMPILER arm-none-eabi-gcc) include(${PICO_SDK_PATH}/pico_sdk_init.cmake) @@ -64,6 +64,7 @@ target_include_directories(wolfboot PRIVATE ) target_link_libraries(wolfboot pico_stdlib hardware_flash) +pico_set_linker_script(wolfboot ../../../../../hal/rp2350.ld) pico_enable_stdio_usb(wolfboot 1) pico_enable_stdio_uart(wolfboot 0) diff --git a/hal/stm32_tz.h b/hal/armv8m_tz.h similarity index 96% rename from hal/stm32_tz.h rename to hal/armv8m_tz.h index 85b41eaf6b..5282c17402 100644 --- a/hal/stm32_tz.h +++ b/hal/armv8m_tz.h @@ -1,4 +1,4 @@ -/* stm32_tz.h +/* armv8m_tz.h * * Copyright (C) 2024 wolfSSL Inc. * @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifndef STM32_TZ_INCLUDED -#define STM32_TZ_INCLUDED +#ifndef TZ_INCLUDED +#define TZ_INCLUDED #include /* SAU registers, used to define memory mapped regions */ diff --git a/hal/rp2350-app.ld b/hal/rp2350-app.ld new file mode 100644 index 0000000000..b39a3ce900 --- /dev/null +++ b/hal/rp2350-app.ld @@ -0,0 +1,302 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +MEMORY +{ + FLASH(rx) : ORIGIN = 0x10040400, LENGTH = 0x1D0000 + RAM(rwx) : ORIGIN = 0x20008000, LENGTH = 472k + SCRATCH_X(rwx) : ORIGIN = 0x2007E000, LENGTH = 4k + SCRATCH_Y(rwx) : ORIGIN = 0x2007F000, LENGTH = 4k +} + +ENTRY(_entry_point) + +SECTIONS +{ + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + /* The bootrom will enter the image at the point indicated in your + IMAGE_DEF, which is usually the reset handler of your vector table. + + The debugger will use the ELF entry point, which is the _entry_point + symbol, and in our case is *different from the bootrom's entry point.* + This is used to go back through the bootrom on debugger launches only, + to perform the same initial flash setup that would be performed on a + cold boot. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + *libgcc.a:cmse_nonsecure_call.o + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + /* Note the boot2 section is optional, and should be discarded if there is + no reference to it *inside* the binary, as it is not called by the + bootrom. (The bootrom performs a simple best-effort XIP setup and + leaves it to the binary to do anything more sophisticated.) However + there is still a size limit of 256 bytes, to ensure the boot2 can be + stored in boot RAM. + + Really this is a "XIP setup function" -- the name boot2 is historic and + refers to its dual-purpose on RP2040, where it also handled vectoring + from the bootrom into the user image. + */ + + .boot2 : { + __boot2_start__ = .; + *(.boot2) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ <= 256, + "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + *(.srodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); + + .ram_vector_table (NOLOAD): { + *(.ram_vector_table) + } > RAM + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + *(.sdata*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + *(.jcr) + . = ALIGN(4); + } > RAM AT> FLASH + + .tdata : { + . = ALIGN(4); + *(.tdata .tdata.* .gnu.linkonce.td.*) + /* All data end */ + __tdata_end = .; + } > RAM AT> FLASH + PROVIDE(__data_end__ = .); + + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .tbss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + __tls_base = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + + __tls_end = .; + } > RAM + + .bss (NOLOAD) : { + . = ALIGN(4); + __tbss_end = .; + + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + PROVIDE(__global_pointer$ = . + 2K); + *(.sbss*) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + } > RAM + /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however + to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT > FLASH + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT > FLASH + __scratch_y_source__ = LOADADDR(.scratch_y); + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (NOLOAD): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > SCRATCH_Y + + .flash_end : { + KEEP(*(.embedded_end_block*)) + PROVIDE(__flash_binary_end = .); + } > FLASH =0xaa + + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* picolibc and LLVM */ + PROVIDE (__heap_start = __end__); + PROVIDE (__heap_end = __HeapLimit); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + + /* llvm-libc */ + PROVIDE (_end = __end__); + PROVIDE (__llvm_libc_heap_limit = __HeapLimit); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") + ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") + + /* todo assert on extra code */ +} + diff --git a/hal/rp2350.c b/hal/rp2350.c index c47c4a71c5..5bb745af90 100644 --- a/hal/rp2350.c +++ b/hal/rp2350.c @@ -26,6 +26,83 @@ #include #include "image.h" #include "printf.h" +#ifdef TZEN +#include "armv8m_tz.h" +#include "pico/bootrom.h" + +#define NVIC_ICER0 (*(volatile uint32_t *)(0xE000E180)) +#define NVIC_ICPR0 (*(volatile uint32_t *)(0xE000E280)) +#define NVIC_ITNS0 (*(volatile uint32_t *)(0xE000EF00)) + +#define SCB_VTOR_NS (*(volatile uint32_t *)(0xE002ED08)) + +#define ACCESS_BITS_DBG (1 << 7) +#define ACCESS_BITS_DMA (1 << 6) +#define ACCESS_BITS_CORE1 (1 << 5) +#define ACCESS_BITS_CORE0 (1 << 4) +#define ACCESS_BITS_SP (1 << 3) +#define ACCESS_BITS_SU (1 << 2) +#define ACCESS_BITS_NSP (1 << 1) +#define ACCESS_BITS_NSU (1 << 0) +#define ACCESS_MAGIC (0xACCE0000) + + +#define ACCESS_CONTROL (0x40060000) +#define ACCESS_CONTROL_LOCK (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0000)) +#define ACCESS_CONTROL_FORCE_CORE_NS (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0004)) +#define ACCESS_CONTROL_CFGRESET (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0008)) +#define ACCESS_CONTROL_GPIOMASK0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x000C)) +#define ACCESS_CONTROL_GPIOMASK1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0010)) +#define ACCESS_CONTROL_ROM (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0014)) +#define ACCESS_CONTROL_XIP_MAIN (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0018)) +#define ACCESS_CONTROL_SRAM(block) (*(volatile uint32_t *)(ACCESS_CONTROL + 0x001C + (block) * 4)) /* block = 0..9 */ +#define ACCESS_CONTROL_DMA (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0044)) +#define ACCESS_CONTROL_USBCTRL (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0048)) +#define ACCESS_CONTROL_PIO0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x004C)) +#define ACCESS_CONTROL_PIO1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0050)) +#define ACCESS_CONTROL_PIO2 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0054)) +#define ACCESS_CONTROL_CORESIGHT_TRACE (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0058)) +#define ACCESS_CONTROL_CORESIGHT_PERIPH (*(volatile uint32_t *)(ACCESS_CONTROL + 0x005C)) +#define ACCESS_CONTROL_SYSINFO (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0060)) +#define ACCESS_CONTROL_RESETS (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0064)) +#define ACCESS_CONTROL_IO_BANK0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0068)) +#define ACCESS_CONTROL_IO_BANK1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x006C)) +#define ACCESS_CONTROL_PADS_BANK0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0070)) +#define ACCESS_CONTROL_PADS_QSPI (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0074)) +#define ACCESS_CONTROL_BUSCTRL (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0078)) +#define ACCESS_CONTROL_ADC (*(volatile uint32_t *)(ACCESS_CONTROL + 0x007C)) +#define ACCESS_CONTROL_HSTX (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0080)) +#define ACCESS_CONTROL_I2C0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0084)) +#define ACCESS_CONTROL_I2C1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0088)) +#define ACCESS_CONTROL_PWM (*(volatile uint32_t *)(ACCESS_CONTROL + 0x008C)) +#define ACCESS_CONTROL_SPI0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0090)) +#define ACCESS_CONTROL_SPI1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0094)) +#define ACCESS_CONTROL_TIMER0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x0098)) +#define ACCESS_CONTROL_TIMER1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x009C)) +#define ACCESS_CONTROL_UART0 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00A0)) +#define ACCESS_CONTROL_UART1 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00A4)) +#define ACCESS_CONTROL_OTP (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00A8)) +#define ACCESS_CONTROL_TBMAN (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00AC)) +#define ACCESS_CONTROL_POWMAN (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00B0)) +#define ACCESS_CONTROL_TRNG (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00B4)) +#define ACCESS_CONTROL_SHA256 (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00B8)) +#define ACCESS_CONTROL_SYSCFG (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00BC)) +#define ACCESS_CONTROL_CLOCKS (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00C0)) +#define ACCESS_CONTROL_XOSC (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00C4)) +#define ACCESS_CONTROL_ROSC (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00C8)) +#define ACCESS_CONTROL_PLL_SYS (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00CC)) +#define ACCESS_CONTROL_PLL_USB (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00D0)) +#define ACCESS_CONTROL_TICKS (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00D4)) +#define ACCESS_CONTROL_WATCHDOG (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00D8)) +#define ACCESS_CONTROL_PSM (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00DC)) +#define ACCESS_CONTROL_XIP_CTRL (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00E0)) +#define ACCESS_CONTROL_XIP_QMI (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00E4)) +#define ACCESS_CONTROL_XIP_AUX (*(volatile uint32_t *)(ACCESS_CONTROL + 0x00E8)) + +#endif + + + #ifdef __WOLFBOOT void hal_init(void) @@ -35,8 +112,82 @@ void hal_init(void) #endif } + +#ifdef TZEN +static void rp2350_configure_sau(void) +{ + /* Disable SAU */ + SAU_CTRL = 0; + sau_init_region(0, 0x10000000, 0x1002FFFF, 1); /* Secure flash */ + sau_init_region(1, 0x10030000, 0x1003FFFF, 1); /* Non-secure-callable flash */ + sau_init_region(2, 0x10040000, 0x101FFFFF, 0); /* Non-secure flash */ + sau_init_region(3, 0x20000000, 0x20007FFF, 1); /* Secure RAM */ + sau_init_region(4, 0x20008000, 0x2007FFFF, 0); /* Non-secure RAM */ + + /* Enable SAU */ + SAU_CTRL = 1; +} + +static void rp2350_configure_nvic(void) +{ + /* Disable all interrupts */ + NVIC_ICER0 = 0xFFFFFFFF; + NVIC_ICPR0 = 0xFFFFFFFF; + + /* Set all interrupts to non-secure */ + NVIC_ITNS0 = 0xFFFFFFFF; +} + +static void rp2350_configure_access_control(void) +{ + int i; + /* Reset ACCESSCTRL */ + const uint32_t secure_fl = (ACCESS_BITS_SU | ACCESS_BITS_SP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1 | ACCESS_MAGIC); + const uint32_t non_secure_fl = (ACCESS_BITS_NSU | ACCESS_BITS_NSP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1 | ACCESS_MAGIC); + //ACCESS_CONTROL_CFGRESET = 1; + /* Corresponding regions for the secure flash and RAM */ + //for(i = 0; i < 2; i++) { + // ACCESS_CONTROL_SRAM(i) = secure_fl; + //} + for (i = 0; i < 10; i++) { + ACCESS_CONTROL_SRAM(i) = non_secure_fl | secure_fl; + } + ACCESS_CONTROL_ROM = secure_fl; + ACCESS_CONTROL_XIP_MAIN = non_secure_fl | secure_fl; + ACCESS_CONTROL_DMA = non_secure_fl; + ACCESS_CONTROL_TRNG = secure_fl; + ACCESS_CONTROL_SYSCFG = secure_fl; + ACCESS_CONTROL_SHA256 = secure_fl; + ACCESS_CONTROL_GPIOMASK0 = 0xFFFFFFFF; + ACCESS_CONTROL_GPIOMASK1 = 0xFFFFFFFF; +// ACCESS_CONTROL_FORCE_CORE_NS = (1 << 1); /* Force core 1 to non-secure */ + ACCESS_CONTROL_PIO0 = non_secure_fl; + ACCESS_CONTROL_PIO1 = non_secure_fl; + ACCESS_CONTROL_PIO2 = non_secure_fl; + + ACCESS_CONTROL_I2C0 = non_secure_fl; + ACCESS_CONTROL_I2C1 = non_secure_fl; + ACCESS_CONTROL_PWM = non_secure_fl; + ACCESS_CONTROL_SPI0 = non_secure_fl; + ACCESS_CONTROL_SPI1 = non_secure_fl; + ACCESS_CONTROL_TIMER0 = non_secure_fl; + ACCESS_CONTROL_TIMER1 = non_secure_fl; + ACCESS_CONTROL_UART0 = non_secure_fl; + ACCESS_CONTROL_UART1 = non_secure_fl; + ACCESS_CONTROL_ADC = non_secure_fl; + +// ACCESS_CONTROL_LOCK = (1 << 0) | (1 << 1) | (1 << 3); +} +#endif + + void hal_prepare_boot(void) { +#ifdef TZEN + rp2350_configure_sau(); + rp2350_configure_nvic(); + rp2350_configure_access_control(); +#endif } #endif diff --git a/hal/rp2350.ld b/hal/rp2350.ld new file mode 100644 index 0000000000..b962f8d37b --- /dev/null +++ b/hal/rp2350.ld @@ -0,0 +1,302 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +MEMORY +{ + FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 256k + RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 24k + SCRATCH_X(rwx) : ORIGIN = 0x20006000, LENGTH = 4k + SCRATCH_Y(rwx) : ORIGIN = 0x20007000, LENGTH = 4k +} + +ENTRY(_entry_point) + +SECTIONS +{ + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + /* The bootrom will enter the image at the point indicated in your + IMAGE_DEF, which is usually the reset handler of your vector table. + + The debugger will use the ELF entry point, which is the _entry_point + symbol, and in our case is *different from the bootrom's entry point.* + This is used to go back through the bootrom on debugger launches only, + to perform the same initial flash setup that would be performed on a + cold boot. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + *libgcc.a:cmse_nonsecure_call.o + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + /* Note the boot2 section is optional, and should be discarded if there is + no reference to it *inside* the binary, as it is not called by the + bootrom. (The bootrom performs a simple best-effort XIP setup and + leaves it to the binary to do anything more sophisticated.) However + there is still a size limit of 256 bytes, to ensure the boot2 can be + stored in boot RAM. + + Really this is a "XIP setup function" -- the name boot2 is historic and + refers to its dual-purpose on RP2040, where it also handled vectoring + from the bootrom into the user image. + */ + + .boot2 : { + __boot2_start__ = .; + *(.boot2) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ <= 256, + "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + *(.srodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); + + .ram_vector_table (NOLOAD): { + *(.ram_vector_table) + } > RAM + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + *(.sdata*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + *(.jcr) + . = ALIGN(4); + } > RAM AT> FLASH + + .tdata : { + . = ALIGN(4); + *(.tdata .tdata.* .gnu.linkonce.td.*) + /* All data end */ + __tdata_end = .; + } > RAM AT> FLASH + PROVIDE(__data_end__ = .); + + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .tbss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + __tls_base = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + + __tls_end = .; + } > RAM + + .bss (NOLOAD) : { + . = ALIGN(4); + __tbss_end = .; + + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + PROVIDE(__global_pointer$ = . + 2K); + *(.sbss*) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + } > RAM + /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however + to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT > FLASH + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT > FLASH + __scratch_y_source__ = LOADADDR(.scratch_y); + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (NOLOAD): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > SCRATCH_Y + + .flash_end : { + KEEP(*(.embedded_end_block*)) + PROVIDE(__flash_binary_end = .); + } > FLASH =0xaa + + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* picolibc and LLVM */ + PROVIDE (__heap_start = __end__); + PROVIDE (__heap_end = __HeapLimit); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + + /* llvm-libc */ + PROVIDE (_end = __end__); + PROVIDE (__llvm_libc_heap_limit = __HeapLimit); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") + ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") + + /* todo assert on extra code */ +} + diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index 39c49f0302..ff6cd5a9eb 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -33,7 +33,7 @@ #include "hal/stm32h5.h" #endif -#include "hal/stm32_tz.h" +#include "hal/armv8m_tz.h" #include "image.h" #include "hal.h" From 6681e54a6a8f4f58372edf9402d1660776163d50 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 10:29:28 +0100 Subject: [PATCH 11/18] Working TZ supervisor --- IDE/pico-sdk/rp2350/test-app/CMakeLists.txt | 10 +++ IDE/pico-sdk/rp2350/test-app/runtime.c | 20 ++++++ IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt | 3 +- arch.mk | 1 + hal/rp2350-app.ld | 39 +++-------- hal/rp2350.c | 72 ++++++++++++++------- src/boot_arm.c | 3 +- 7 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 IDE/pico-sdk/rp2350/test-app/runtime.c diff --git a/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt b/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt index 4de7c6938b..789ded85cc 100644 --- a/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt +++ b/IDE/pico-sdk/rp2350/test-app/CMakeLists.txt @@ -1,11 +1,13 @@ cmake_minimum_required(VERSION 3.13) set(WOLFBOOT_PATH ../../../../) set(CMAKE_CXX_COMPILER arm-none-eabi-gcc) +set(LIB_PICO_RUNTIME_INIT=0) include(${PICO_SDK_PATH}/pico_sdk_init.cmake) set(PICOTOOL_FETCH_FROM_GIT_PATH ../wolfboot/build/picotool) set(BOOT_STAGE2_FILE ${CMAKE_CURRENT_LIST_DIR}/boot2_empty.S) +set(PICO_NO_RUNTIME 1) project(blink) @@ -15,8 +17,16 @@ pico_sdk_init() add_executable(blink blink.c + runtime.c ) +target_compile_options(blink PRIVATE + -DPICO_RUNTIME_NO_INIT_BOOTROM_RESET=1 + -DPICO_RUNTIME_NO_INIT_CLOCKS=1 + -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1 +) +target_compile_definitions(blink PRIVATE PICO_NO_RUNTIME=1) + pico_set_linker_script(blink ../../../../../hal/rp2350-app.ld) target_link_libraries(blink pico_stdlib) diff --git a/IDE/pico-sdk/rp2350/test-app/runtime.c b/IDE/pico-sdk/rp2350/test-app/runtime.c new file mode 100644 index 0000000000..f22aa5e570 --- /dev/null +++ b/IDE/pico-sdk/rp2350/test-app/runtime.c @@ -0,0 +1,20 @@ +#include +void runtime_init_bootrom_reset(void) +{ +} + +void runtime_init_clocks(void) +{ +} + + +typedef void (*preinit_fn_t)(void); + +void runtime_init_cpasr(void) +{ + volatile uint32_t *cpasr_ns = (volatile uint32_t*) 0xE000ED88; + *cpasr_ns |= 0xFF; +} + +preinit_fn_t __attribute__((section(".nonsecure_preinit_array"))) *((*nonsecure_preinit)(void)) = + { &runtime_init_cpasr }; diff --git a/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt b/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt index 5cf1880ab1..f661a78ab3 100644 --- a/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt +++ b/IDE/pico-sdk/rp2350/wolfboot/CMakeLists.txt @@ -35,10 +35,11 @@ add_executable(wolfboot # Add cflags target_compile_options(wolfboot PRIVATE -D__WOLFBOOT - -D__ARM_ARCH_6M__ -DWOLFSSL_USER_SETTINGS -mcpu=cortex-m33 -DCORTEX_M33 + -DTZEN + -mcmse -DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM -DWOLFSSL_ARM_ARCH=8 diff --git a/arch.mk b/arch.mk index 990cedf070..3d3e24ef9d 100644 --- a/arch.mk +++ b/arch.mk @@ -228,6 +228,7 @@ ifeq ($(ARCH),ARM) WOLFBOOT_ORIGIN=0x10000000 ifeq ($(TZEN),1) LSCRIPT_IN=hal/$(TARGET).ld + CFLAGS+=-DTZEN else LSCRIPT_IN=hal/$(TARGET)-ns.ld endif diff --git a/hal/rp2350-app.ld b/hal/rp2350-app.ld index b39a3ce900..f2068ae921 100644 --- a/hal/rp2350-app.ld +++ b/hal/rp2350-app.ld @@ -23,8 +23,9 @@ MEMORY { + BOOT(rx) : ORIGIN = 0x10000000, LENGTH = 0x40400 FLASH(rx) : ORIGIN = 0x10040400, LENGTH = 0x1D0000 - RAM(rwx) : ORIGIN = 0x20008000, LENGTH = 472k + RAM(rwx) : ORIGIN = 0x20010000, LENGTH = 0x6E000 SCRATCH_X(rwx) : ORIGIN = 0x2007E000, LENGTH = 4k SCRATCH_Y(rwx) : ORIGIN = 0x2007F000, LENGTH = 4k } @@ -78,15 +79,16 @@ SECTIONS . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) + /* KEEP(*(SORT(.preinit_array.*))) */ + /* KEEP(*(.preinit_array)) */ + KEEP(*(.nonsecure_preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) + /* KEEP(*(SORT(.init_array.*))) */ + /* KEEP(*(.init_array)) */ PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); @@ -100,30 +102,8 @@ SECTIONS . = ALIGN(4); } > FLASH - /* Note the boot2 section is optional, and should be discarded if there is - no reference to it *inside* the binary, as it is not called by the - bootrom. (The bootrom performs a simple best-effort XIP setup and - leaves it to the binary to do anything more sophisticated.) However - there is still a size limit of 256 bytes, to ensure the boot2 can be - stored in boot RAM. - - Really this is a "XIP setup function" -- the name boot2 is historic and - refers to its dual-purpose on RP2040, where it also handled vectoring - from the bootrom into the user image. - */ - - .boot2 : { - __boot2_start__ = .; - *(.boot2) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ <= 256, - "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") - .rodata : { *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) - *(.srodata*) . = ALIGN(4); *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) . = ALIGN(4); @@ -174,7 +154,6 @@ SECTIONS . = ALIGN(4); *(.data*) - *(.sdata*) . = ALIGN(4); *(.after_data.*) @@ -185,6 +164,7 @@ SECTIONS KEEP(*(.mutex_array)) PROVIDE_HIDDEN (__mutex_array_end = .); + . = ALIGN(4); *(.jcr) . = ALIGN(4); } > RAM AT> FLASH @@ -270,7 +250,8 @@ SECTIONS .flash_end : { KEEP(*(.embedded_end_block*)) PROVIDE(__flash_binary_end = .); - } > FLASH =0xaa + } > FLASH + /* stack limit is poorly named, but historically is maximum heap ptr */ __StackLimit = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/rp2350.c b/hal/rp2350.c index 5bb745af90..77ce5cba6c 100644 --- a/hal/rp2350.c +++ b/hal/rp2350.c @@ -36,6 +36,15 @@ #define SCB_VTOR_NS (*(volatile uint32_t *)(0xE002ED08)) +#define NSACR (*(volatile uint32_t *)(0xE000ED8C)) +#define CPACR (*(volatile uint32_t *)(0xE000ED88)) + +#define SHCSR (*(volatile uint32_t *)(0xE000ED24)) +#define SHCSR_MEMFAULTENA (1 << 16) +#define SHCSR_BUSFAULTENA (1 << 17) +#define SHCSR_USGFAULTENA (1 << 18) + + #define ACCESS_BITS_DBG (1 << 7) #define ACCESS_BITS_DMA (1 << 6) #define ACCESS_BITS_CORE1 (1 << 5) @@ -122,10 +131,19 @@ static void rp2350_configure_sau(void) sau_init_region(1, 0x10030000, 0x1003FFFF, 1); /* Non-secure-callable flash */ sau_init_region(2, 0x10040000, 0x101FFFFF, 0); /* Non-secure flash */ sau_init_region(3, 0x20000000, 0x20007FFF, 1); /* Secure RAM */ - sau_init_region(4, 0x20008000, 0x2007FFFF, 0); /* Non-secure RAM */ + sau_init_region(4, 0x20008000, 0x20081FFF, 0); /* Non-secure RAM */ + sau_init_region(6, 0x40000000, 0x5FFFFFFF, 0); /* Non-secure peripherals */ + sau_init_region(7, 0xD0000000, 0xDFFFFFFF, 0); /* Non-secure SIO region */ + /* Enable SAU */ SAU_CTRL = 1; + + /* Enable MemFault, BusFault and UsageFault */ + SHCSR |= SHCSR_MEMFAULTENA | SHCSR_BUSFAULTENA | SHCSR_USGFAULTENA; + + /* Add flag to trap misaligned accesses */ + *((volatile uint32_t *)0xE000ED14) |= 0x00000008; } static void rp2350_configure_nvic(void) @@ -142,39 +160,49 @@ static void rp2350_configure_access_control(void) { int i; /* Reset ACCESSCTRL */ - const uint32_t secure_fl = (ACCESS_BITS_SU | ACCESS_BITS_SP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1 | ACCESS_MAGIC); - const uint32_t non_secure_fl = (ACCESS_BITS_NSU | ACCESS_BITS_NSP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1 | ACCESS_MAGIC); + const uint32_t secure_fl = (ACCESS_BITS_SU | ACCESS_BITS_SP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1) | ACCESS_MAGIC; + const uint32_t non_secure_fl = (ACCESS_BITS_NSU | ACCESS_BITS_NSP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1) | ACCESS_MAGIC; + //ACCESS_CONTROL_CFGRESET = 1; /* Corresponding regions for the secure flash and RAM */ - //for(i = 0; i < 2; i++) { - // ACCESS_CONTROL_SRAM(i) = secure_fl; - //} + /* + for(i = 0; i < 2; i++) { + ACCESS_CONTROL_SRAM(i) = secure_fl; + } + */ for (i = 0; i < 10; i++) { ACCESS_CONTROL_SRAM(i) = non_secure_fl | secure_fl; } - ACCESS_CONTROL_ROM = secure_fl; + ACCESS_CONTROL_ROM = secure_fl | non_secure_fl; ACCESS_CONTROL_XIP_MAIN = non_secure_fl | secure_fl; ACCESS_CONTROL_DMA = non_secure_fl; ACCESS_CONTROL_TRNG = secure_fl; - ACCESS_CONTROL_SYSCFG = secure_fl; + ACCESS_CONTROL_SYSCFG = secure_fl | non_secure_fl; ACCESS_CONTROL_SHA256 = secure_fl; ACCESS_CONTROL_GPIOMASK0 = 0xFFFFFFFF; ACCESS_CONTROL_GPIOMASK1 = 0xFFFFFFFF; + ACCESS_CONTROL_IO_BANK0 = non_secure_fl | secure_fl; + ACCESS_CONTROL_IO_BANK1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_PADS_BANK0 = non_secure_fl | secure_fl; // ACCESS_CONTROL_FORCE_CORE_NS = (1 << 1); /* Force core 1 to non-secure */ - ACCESS_CONTROL_PIO0 = non_secure_fl; - ACCESS_CONTROL_PIO1 = non_secure_fl; - ACCESS_CONTROL_PIO2 = non_secure_fl; - - ACCESS_CONTROL_I2C0 = non_secure_fl; - ACCESS_CONTROL_I2C1 = non_secure_fl; - ACCESS_CONTROL_PWM = non_secure_fl; - ACCESS_CONTROL_SPI0 = non_secure_fl; - ACCESS_CONTROL_SPI1 = non_secure_fl; - ACCESS_CONTROL_TIMER0 = non_secure_fl; - ACCESS_CONTROL_TIMER1 = non_secure_fl; - ACCESS_CONTROL_UART0 = non_secure_fl; - ACCESS_CONTROL_UART1 = non_secure_fl; - ACCESS_CONTROL_ADC = non_secure_fl; + ACCESS_CONTROL_PIO0 = non_secure_fl | secure_fl; + ACCESS_CONTROL_PIO1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_PIO2 = non_secure_fl | secure_fl; + + ACCESS_CONTROL_I2C0 = non_secure_fl|secure_fl; + ACCESS_CONTROL_I2C1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_PWM = non_secure_fl | secure_fl; + ACCESS_CONTROL_SPI0 = non_secure_fl | secure_fl; + ACCESS_CONTROL_SPI1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_TIMER0 = non_secure_fl | secure_fl; + ACCESS_CONTROL_TIMER1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_UART0 = non_secure_fl | secure_fl; + ACCESS_CONTROL_UART1 = non_secure_fl | secure_fl; + ACCESS_CONTROL_ADC = non_secure_fl | secure_fl; + ACCESS_CONTROL_RESETS = non_secure_fl | secure_fl; + + CPACR |= 0x000000FF; /* Enable access to coprocessors CP0-CP7 */ + NSACR |= 0x000000FF; /* Enable non-secure access to coprocessors CP0-CP7 */ // ACCESS_CONTROL_LOCK = (1 << 0) | (1 << 1) | (1 << 3); } diff --git a/src/boot_arm.c b/src/boot_arm.c index a1f2790e42..100f1e6219 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -416,7 +416,8 @@ void isr_empty(void) #ifdef TZEN #include "hal.h" -#define VTOR (*(volatile uint32_t *)(0xE002ED08)) +//#define VTOR (*(volatile uint32_t *)(0xE002ED08)) +#define VTOR (*(volatile uint32_t *)(0xE000ED08)) #else #define VTOR (*(volatile uint32_t *)(0xE000ED08)) #endif From b6ed896086e7202c26998a76f3a3c345af57029e Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 12:36:19 +0100 Subject: [PATCH 12/18] Cleanup initialization code for rp2350. + TZEN=1 in config + Changed SRAM settings (allocated 256KB to the secure supervisor) + Updated documentation + Added FLASH_NSC area for sg stubs --- IDE/pico-sdk/rp2350/README.md | 49 +++++++++++++++++++------- IDE/pico-sdk/rp2350/test-app/runtime.c | 9 ----- config/examples/rp2350.config | 2 +- hal/rp2350-app.ld | 6 ++-- hal/rp2350.c | 49 +++++++++++++------------- hal/rp2350.ld | 16 ++++++--- 6 files changed, 77 insertions(+), 54 deletions(-) diff --git a/IDE/pico-sdk/rp2350/README.md b/IDE/pico-sdk/rp2350/README.md index b3290fcd09..8d0c2ce565 100644 --- a/IDE/pico-sdk/rp2350/README.md +++ b/IDE/pico-sdk/rp2350/README.md @@ -1,5 +1,27 @@ ## wolfBoot port for rp2350 (Raspberry pi pico 2) +### Support for TrustZone + +By default, TZEN=1 is enabled in the provided configuration. wolfBoot will run +from the Secure domain, and will stage the application in the Non-Secure domain. + +The flash memory is divided as follows: + +- wolfBoot partition (0x10000000 - 0x1003FFFF), 224 KB +- Non-secure callable partition (for secure gateway) (0x10038000 - 0x1003FFFF), 32 KB +- Boot partition (0x10040000 - 0x1007FFFF), 768 KB +- Update partition (0x10100000 - 0x1013FFFF), 768 KB +- Unused flash space (0x101C1000 - 0x101FFFFF), 252 KB +- Swap space (0x101C0000 - 0x101C0FFF), 4 KB + +The SRAM bank0 is assigned to the Secure domain, and enforced using both SAU and `ACCESS_CONTROL` registers. + +- Secure SRAM0-3: 0x20000000 - 0x2003FFFF, 256 KB +- Non-secure SRAM4-7: 0x20040000 - 0x2007FFFF, 256 KB +- Non-secure stack for application SRAM8-9: 0x20080000 - 0x20081FFF, 8 KB + +``` + ### Requirements #### External debugger @@ -31,18 +53,10 @@ From wolfBoot root directory, copy the example configuration: cp config/examples/rp2350.config .config ``` -By default, the config file indicates the following partition layout: - -``` -wolfBoot partition: 256 KB, at address 0x10000000 to 0x1003FFFF -Boot partition: 768 KB, at address 0x10040000 to 0x1007FFFF -Update partition: 768 KB, at address 0x10100000 to 0x1013FFFF -Swap space: 4 KB, at address 0x101C0000 to 0x101C0FFF -Unused flash space: 252 KB, at address 0x101C1000 to 0x101FFFFF -``` - You can now edit the .config file to change partition sizes/offsets, algorithms, -add/remove features, etc. +disable trustzone, add/remove features, etc. + +When TZEN=0, the application will run in the Secure domain. When the configuration is complete, run `make`. This will: @@ -61,6 +75,7 @@ return to this directory and run: ``` cd wolfboot +export PICO_SDK_PATH=... ./build-wolfboot.sh ``` @@ -69,7 +84,8 @@ This version of wolfboot incorporates the `.boot2` sequence needed to enable the QSPI device, provided by the pico-sdk and always embedded in all applications. -wolfboot.bin contains the bootloader, configured as follows: +wolfboot.bin contains the bootloader, and can be loaded into the RP2350, starting at address 0x10000000. +The script will automatically upload the binary if a JLink debugger is connected. ### Building and uploading the application @@ -85,6 +101,13 @@ The linker script included is modified to change the application entry point from 0x10000000 to 0x10040400, which is the start of the application code, taking into account the wolfBoot header size. +The application is signed with the wolfBoot private key, and the signature is +stored in the manifest header of the application binary. + +The output file `build/blink_v1_signed.bin` is automatically uploaded to the RP2350 if a JLink debugger is connected. +The application image is stored in the boot partition, starting at address 0x10040000. +The entry point of the application (0x10040400), set in the linker script `hal/rp2350-app.ld`, is the start of the application code, taking into account the wolfBoot header size. + ### Testing the application @@ -93,3 +116,5 @@ every 500ms. If the above steps are successful, the LED on the board should start blinking. +The code has been tested on a Seeed studio XIAO RP2350 board. + diff --git a/IDE/pico-sdk/rp2350/test-app/runtime.c b/IDE/pico-sdk/rp2350/test-app/runtime.c index f22aa5e570..37e91e3b8a 100644 --- a/IDE/pico-sdk/rp2350/test-app/runtime.c +++ b/IDE/pico-sdk/rp2350/test-app/runtime.c @@ -1,13 +1,4 @@ #include -void runtime_init_bootrom_reset(void) -{ -} - -void runtime_init_clocks(void) -{ -} - - typedef void (*preinit_fn_t)(void); void runtime_init_cpasr(void) diff --git a/config/examples/rp2350.config b/config/examples/rp2350.config index bf08911a67..8ad97a907f 100644 --- a/config/examples/rp2350.config +++ b/config/examples/rp2350.config @@ -1,5 +1,5 @@ ARCH?=ARM -TZEN?=0 +TZEN?=1 TARGET?=rp2350 SIGN?=ECC256 HASH?=SHA256 diff --git a/hal/rp2350-app.ld b/hal/rp2350-app.ld index f2068ae921..6b4c7e9e46 100644 --- a/hal/rp2350-app.ld +++ b/hal/rp2350-app.ld @@ -25,9 +25,9 @@ MEMORY { BOOT(rx) : ORIGIN = 0x10000000, LENGTH = 0x40400 FLASH(rx) : ORIGIN = 0x10040400, LENGTH = 0x1D0000 - RAM(rwx) : ORIGIN = 0x20010000, LENGTH = 0x6E000 - SCRATCH_X(rwx) : ORIGIN = 0x2007E000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x2007F000, LENGTH = 4k + RAM(rwx) : ORIGIN = 0x20040000, LENGTH = 0x40000 + SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k + SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k } ENTRY(_entry_point) diff --git a/hal/rp2350.c b/hal/rp2350.c index 77ce5cba6c..cbc0b6ff5a 100644 --- a/hal/rp2350.c +++ b/hal/rp2350.c @@ -1,9 +1,9 @@ /* rp2350.c * - * Stubs for custom HAL implementation. Defines the - * functions used by wolfboot for a specific target. + * Custom HAL implementation. Defines the + * functions used by wolfboot for raspberry-pi pico2 (rp2350) * - * Copyright (C) 2021 wolfSSL Inc. + * Copyright (C) 2025 wolfSSL Inc. * * This file is part of wolfBoot. * @@ -110,9 +110,6 @@ #endif - - - #ifdef __WOLFBOOT void hal_init(void) { @@ -121,7 +118,6 @@ void hal_init(void) #endif } - #ifdef TZEN static void rp2350_configure_sau(void) { @@ -130,8 +126,8 @@ static void rp2350_configure_sau(void) sau_init_region(0, 0x10000000, 0x1002FFFF, 1); /* Secure flash */ sau_init_region(1, 0x10030000, 0x1003FFFF, 1); /* Non-secure-callable flash */ sau_init_region(2, 0x10040000, 0x101FFFFF, 0); /* Non-secure flash */ - sau_init_region(3, 0x20000000, 0x20007FFF, 1); /* Secure RAM */ - sau_init_region(4, 0x20008000, 0x20081FFF, 0); /* Non-secure RAM */ + sau_init_region(3, 0x20000000, 0x2003FFFF, 1); /* Secure RAM (Low 256K) */ + sau_init_region(4, 0x20040000, 0x20081FFF, 0); /* Non-secure RAM (High 256 + 8K) */ sau_init_region(6, 0x40000000, 0x5FFFFFFF, 0); /* Non-secure peripherals */ sau_init_region(7, 0xD0000000, 0xDFFFFFFF, 0); /* Non-secure SIO region */ @@ -159,37 +155,32 @@ static void rp2350_configure_nvic(void) static void rp2350_configure_access_control(void) { int i; - /* Reset ACCESSCTRL */ - const uint32_t secure_fl = (ACCESS_BITS_SU | ACCESS_BITS_SP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1) | ACCESS_MAGIC; + const uint32_t secure_fl = (ACCESS_BITS_SU | ACCESS_BITS_SP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0) | ACCESS_MAGIC; const uint32_t non_secure_fl = (ACCESS_BITS_NSU | ACCESS_BITS_NSP | ACCESS_BITS_DMA | ACCESS_BITS_DBG | ACCESS_BITS_CORE0 | ACCESS_BITS_CORE1) | ACCESS_MAGIC; - //ACCESS_CONTROL_CFGRESET = 1; - /* Corresponding regions for the secure flash and RAM */ - /* - for(i = 0; i < 2; i++) { + /* Set access control to Secure for lower RAM (0x20000000 - 0x2003FFFF) */ + for (i = 0; i < 4; i ++) ACCESS_CONTROL_SRAM(i) = secure_fl; - } - */ - for (i = 0; i < 10; i++) { + + /* Set access control to Non-secure for upper RAM (0x20040000 - 0x20081FFF) */ + for (i = 4; i < 10; i++) ACCESS_CONTROL_SRAM(i) = non_secure_fl | secure_fl; - } + + /* Set access control for peripherals */ ACCESS_CONTROL_ROM = secure_fl | non_secure_fl; ACCESS_CONTROL_XIP_MAIN = non_secure_fl | secure_fl; ACCESS_CONTROL_DMA = non_secure_fl; ACCESS_CONTROL_TRNG = secure_fl; - ACCESS_CONTROL_SYSCFG = secure_fl | non_secure_fl; + ACCESS_CONTROL_SYSCFG = secure_fl; ACCESS_CONTROL_SHA256 = secure_fl; - ACCESS_CONTROL_GPIOMASK0 = 0xFFFFFFFF; - ACCESS_CONTROL_GPIOMASK1 = 0xFFFFFFFF; ACCESS_CONTROL_IO_BANK0 = non_secure_fl | secure_fl; ACCESS_CONTROL_IO_BANK1 = non_secure_fl | secure_fl; ACCESS_CONTROL_PADS_BANK0 = non_secure_fl | secure_fl; -// ACCESS_CONTROL_FORCE_CORE_NS = (1 << 1); /* Force core 1 to non-secure */ ACCESS_CONTROL_PIO0 = non_secure_fl | secure_fl; ACCESS_CONTROL_PIO1 = non_secure_fl | secure_fl; ACCESS_CONTROL_PIO2 = non_secure_fl | secure_fl; - ACCESS_CONTROL_I2C0 = non_secure_fl|secure_fl; + ACCESS_CONTROL_I2C0 = non_secure_fl |secure_fl; ACCESS_CONTROL_I2C1 = non_secure_fl | secure_fl; ACCESS_CONTROL_PWM = non_secure_fl | secure_fl; ACCESS_CONTROL_SPI0 = non_secure_fl | secure_fl; @@ -201,10 +192,18 @@ static void rp2350_configure_access_control(void) ACCESS_CONTROL_ADC = non_secure_fl | secure_fl; ACCESS_CONTROL_RESETS = non_secure_fl | secure_fl; + /* Force core 1 to non-secure */ + ACCESS_CONTROL_FORCE_CORE_NS = (1 << 1) | ACCESS_MAGIC; + + /* GPIO masks: Each bit represents "NS allowed" for a GPIO pin */ + ACCESS_CONTROL_GPIOMASK0 = 0xFFFFFFFF; + ACCESS_CONTROL_GPIOMASK1 = 0xFFFFFFFF; + CPACR |= 0x000000FF; /* Enable access to coprocessors CP0-CP7 */ NSACR |= 0x000000FF; /* Enable non-secure access to coprocessors CP0-CP7 */ -// ACCESS_CONTROL_LOCK = (1 << 0) | (1 << 1) | (1 << 3); + /* Lock access control */ + ACCESS_CONTROL_LOCK = non_secure_fl | secure_fl; } #endif diff --git a/hal/rp2350.ld b/hal/rp2350.ld index b962f8d37b..5ac320778c 100644 --- a/hal/rp2350.ld +++ b/hal/rp2350.ld @@ -23,10 +23,12 @@ MEMORY { - FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 256k - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 24k - SCRATCH_X(rwx) : ORIGIN = 0x20006000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20007000, LENGTH = 4k + FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 0x38000 + FLASH_NSC(rx) : ORIGIN = 0x10038000, LENGTH = 0x8000 + + RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 0x3E000 + SCRATCH_X(rwx) : ORIGIN = 0x2003E000, LENGTH = 4k + SCRATCH_Y(rwx) : ORIGIN = 0x2003F000, LENGTH = 4k } ENTRY(_entry_point) @@ -100,6 +102,12 @@ SECTIONS . = ALIGN(4); } > FLASH + .gnu.sgstubs : + { + *(.gnu.sgstubs*) /* Secure Gateway stubs */ + . = ALIGN(4); + } >FLASH_NSC + /* Note the boot2 section is optional, and should be discarded if there is no reference to it *inside* the binary, as it is not called by the bootrom. (The bootrom performs a simple best-effort XIP setup and From a14c92f15111810e6aace5458e1dcca0d0d15fed Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 17:00:58 +0100 Subject: [PATCH 13/18] Added draft build test. --- .github/workflows/test-build-pico-sdk.yml | 63 +++++++++++++++++++++++ .github/workflows/test-configs.yml | 7 +++ IDE/pico-sdk/rp2350/test-app/runtime.c | 2 +- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test-build-pico-sdk.yml diff --git a/.github/workflows/test-build-pico-sdk.yml b/.github/workflows/test-build-pico-sdk.yml new file mode 100644 index 0000000000..49b6584970 --- /dev/null +++ b/.github/workflows/test-build-pico-sdk.yml @@ -0,0 +1,63 @@ +name: Wolfboot Reusable Build Workflow for Raspberry Pi Pico2 (rp2350) + +on: + + workflow_call: + inputs: + arch: + required: true + type: string + config-file: + required: true + type: string + make-args: + required: false + type: string + +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - uses: actions/checkout@main + with: + repository: raspberrypi/pico-sdk + path: pico-sdk + + - name: Workaround for sources.list + run: sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/sources.list + + - name: Update repository + run: sudo apt-get update + + - name: Install cross compilers + run: | + sudo apt-get install -y gcc-arm-none-eabi + + - name: make distclean + run: | + make distclean + + - name: Select config + run: | + cp ${{inputs.config-file}} .config && make include/target.h + + - name: Build tools + run: | + make -C tools/keytools && make -C tools/bin-assemble + + - name: pre-build wolfboot + run: | + make + - name: build wolfboot with pico-sdk + run: | + cd IDE/pico-sdk/${{inputs.target}}/wolfboot + mkdir build + cd build + cmake ../ -DPICO_SDK_PATH="$GITHUB_WORKSPACE/pico-sdk" + make diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 69209c4575..d3d822e8af 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -439,3 +439,10 @@ jobs: with: arch: host config-file: ./config/examples/sim-wolfHSM.config + + rp2350_test: + uses: ./.github/workflows/test-build-pico-sdk.yml + with: + arch: arm + config-file: ./config/examples/rp2350.config + target: rp2350 diff --git a/IDE/pico-sdk/rp2350/test-app/runtime.c b/IDE/pico-sdk/rp2350/test-app/runtime.c index 37e91e3b8a..037e0f38b0 100644 --- a/IDE/pico-sdk/rp2350/test-app/runtime.c +++ b/IDE/pico-sdk/rp2350/test-app/runtime.c @@ -7,5 +7,5 @@ void runtime_init_cpasr(void) *cpasr_ns |= 0xFF; } -preinit_fn_t __attribute__((section(".nonsecure_preinit_array"))) *((*nonsecure_preinit)(void)) = +preinit_fn_t __attribute__((section(".nonsecure_preinit_array"))) nonsecure_preinit[] = { &runtime_init_cpasr }; From a844392bb77127b71963fbd4c51a5d9f822090d4 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 17:07:13 +0100 Subject: [PATCH 14/18] Added arg 'target' to pico-sdk build test --- .github/workflows/test-build-pico-sdk.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-build-pico-sdk.yml b/.github/workflows/test-build-pico-sdk.yml index 49b6584970..b817633a5e 100644 --- a/.github/workflows/test-build-pico-sdk.yml +++ b/.github/workflows/test-build-pico-sdk.yml @@ -13,6 +13,9 @@ on: make-args: required: false type: string + target: + required: true + type: string jobs: From 8b9fc5a32a02a99d6ddd08fbdddf250135b391eb Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 17:13:57 +0100 Subject: [PATCH 15/18] Fixed PICO_PLATFORM in pico-sdk test --- .github/workflows/test-build-pico-sdk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-build-pico-sdk.yml b/.github/workflows/test-build-pico-sdk.yml index b817633a5e..7c7668ae90 100644 --- a/.github/workflows/test-build-pico-sdk.yml +++ b/.github/workflows/test-build-pico-sdk.yml @@ -62,5 +62,5 @@ jobs: cd IDE/pico-sdk/${{inputs.target}}/wolfboot mkdir build cd build - cmake ../ -DPICO_SDK_PATH="$GITHUB_WORKSPACE/pico-sdk" + cmake ../ -DPICO_SDK_PATH="$GITHUB_WORKSPACE/pico-sdk" -DPICO_PLATFORM=${{inputs.target}} make From d120000a63cbbaa08cb34a60d3762f9ce3eb6691 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 17:33:45 +0100 Subject: [PATCH 16/18] rp2350: Added flash driver --- hal/rp2350.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hal/rp2350.c b/hal/rp2350.c index cbc0b6ff5a..c2b4a4d4a0 100644 --- a/hal/rp2350.c +++ b/hal/rp2350.c @@ -26,6 +26,9 @@ #include #include "image.h" #include "printf.h" + +#include "hardware/flash.h" + #ifdef TZEN #include "armv8m_tz.h" #include "pico/bootrom.h" @@ -221,7 +224,8 @@ void hal_prepare_boot(void) int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) { - return 0; /* on success. */ + flash_range_program(address - XIP_BASE, data, len); + return 0; } void RAMFUNCTION hal_flash_unlock(void) @@ -234,6 +238,7 @@ void RAMFUNCTION hal_flash_lock(void) int RAMFUNCTION hal_flash_erase(uint32_t address, int len) { - return 0; /* on success. */ + flash_range_erase(address - XIP_BASE, len); + return 0; } From 48252aa891bcbae36019716b9cbdd5ca7c073f43 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 27 Jan 2025 17:36:59 +0100 Subject: [PATCH 17/18] Updated copyright in rp2350 test-app --- IDE/pico-sdk/rp2350/test-app/runtime.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/IDE/pico-sdk/rp2350/test-app/runtime.c b/IDE/pico-sdk/rp2350/test-app/runtime.c index 037e0f38b0..f114e98928 100644 --- a/IDE/pico-sdk/rp2350/test-app/runtime.c +++ b/IDE/pico-sdk/rp2350/test-app/runtime.c @@ -1,3 +1,26 @@ +/* runtime.c + * + * Custom pre-init for non-secure application, staged by wolfBoot. + * Wolfboot test application for raspberry-pi pico2 (rp2350) + * + * Copyright (C) 2025 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 typedef void (*preinit_fn_t)(void); From 6f350ffc635ff55bdf19169fe9bbdb5ee147be44 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 28 Jan 2025 12:05:03 +0000 Subject: [PATCH 18/18] Update RP2350 README Add additional instructions on how to use the `picotool` instead of a JLink. --- IDE/pico-sdk/rp2350/README.md | 49 +++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/IDE/pico-sdk/rp2350/README.md b/IDE/pico-sdk/rp2350/README.md index 8d0c2ce565..cb74b77ea2 100644 --- a/IDE/pico-sdk/rp2350/README.md +++ b/IDE/pico-sdk/rp2350/README.md @@ -20,16 +20,22 @@ The SRAM bank0 is assigned to the Secure domain, and enforced using both SAU and - Non-secure SRAM4-7: 0x20040000 - 0x2007FFFF, 256 KB - Non-secure stack for application SRAM8-9: 0x20080000 - 0x20081FFF, 8 KB -``` -### Requirements +### Requirements #### External debugger As the two images (bootloader + application) are stored in different areas in -the flash memory, a SWD connector is required to upload the binary images into -the flash, as opposed to the default bootloader, allowing to upload non-signed -applications into a storage device +the flash memory, a SWD connector is recommended to upload the binary images +into the flash, as opposed to the default bootloader, allowing to upload +non-signed applications into a storage device. + +The scripts used in this example expect a JLink to be connected to the SWD port +as documented [here](https://kb.segger.com/Raspberry_Pi_Pico). + +There is documentation below on how to do this with `picotool` instead, the +scripts to error that it cannot file the JLink if you wish to use `picotool` +instead, but this can be ignored. #### PicoSDK @@ -71,7 +77,7 @@ The environment has now been prepared to build and flash the two images ### Building and uploading wolfBoot.bin After preparing the configuration and creating the keypair, -return to this directory and run: +return to the `IDE/pico-sdk/rp2350/` directory and run: ``` cd wolfboot @@ -84,13 +90,20 @@ This version of wolfboot incorporates the `.boot2` sequence needed to enable the QSPI device, provided by the pico-sdk and always embedded in all applications. -wolfboot.bin contains the bootloader, and can be loaded into the RP2350, starting at address 0x10000000. -The script will automatically upload the binary if a JLink debugger is connected. +wolfboot.bin contains the bootloader, and can be loaded into the RP2350, +starting at address 0x10000000. The script will automatically upload the binary +if a JLink debugger is connected. + +If you do not have a JLink you can install the binary using: + +``` +picotool load build/wolfboot.uf2 +``` ### Building and uploading the application ``` -cd test-app +cd ../test-app ./build-signed-app.sh ``` The script above will compile the test application and sign it with the @@ -104,10 +117,19 @@ taking into account the wolfBoot header size. The application is signed with the wolfBoot private key, and the signature is stored in the manifest header of the application binary. -The output file `build/blink_v1_signed.bin` is automatically uploaded to the RP2350 if a JLink debugger is connected. -The application image is stored in the boot partition, starting at address 0x10040000. -The entry point of the application (0x10040400), set in the linker script `hal/rp2350-app.ld`, is the start of the application code, taking into account the wolfBoot header size. +The output file `build/blink_v1_signed.bin` is automatically uploaded to the +RP2350 if a JLink debugger is connected. +The application image is stored in the boot partition, starting at address +0x10040000. +The entry point of the application (0x10040400), set in the linker script +`hal/rp2350-app.ld`, is the start of the application code, taking into account +the wolfBoot header size. + +To use `picotool` instead run: +``` +picotool load build/blink_v1_signed.bin -o 0x10040000 +``` ### Testing the application @@ -116,5 +138,6 @@ every 500ms. If the above steps are successful, the LED on the board should start blinking. -The code has been tested on a Seeed studio XIAO RP2350 board. +The code has been tested on a Seeed studio XIAO RP2350 board and a Raspberry Pi +Pico 2 (non-WiFi version).