diff --git a/arch.mk b/arch.mk index 2292a90084..f85089667f 100644 --- a/arch.mk +++ b/arch.mk @@ -330,6 +330,61 @@ ifeq ($(ARCH),ARM) CFLAGS+=-I$(PICO_SDK_PATH)/src/common/pico_stdlib_headers/include endif + ifeq ($(TARGET),rtl8735b) + # RealTek RTL8735B SoC (Cortex-M33), e.g. the AmebaPro2 EVB. wolfBoot is + # staged into SRAM by the RealTek bootloader and copies the verified app + # from external SPI NOR into DDR before jumping (src/update_ram.c RAMBOOT). + CORTEX_M33=1 + CFLAGS+=-Ihal + # ASDK 10.3.0 toolchain (system arm-none-eabi-gcc clashes on newlib/lwip). + CROSS_COMPILE:=$(ASDK_PATH)/arm-none-eabi- + UPDATE_OBJS:=src/update_ram.o + CFLAGS+=-DWOLFBOOT_DUALBOOT + CFLAGS+=-ffunction-sections -fdata-sections + LDFLAGS+=-Wl,--gc-sections + # Flash/UART/cache backend: "sdk" (default, RealTek SDK drivers) or "bare" + # (smaller, no SDK dependency -- not yet implemented). See hal/rtl8735b.c. + HAL_BACKEND?=sdk + ifeq ($(HAL_BACKEND),sdk) + CFLAGS+=-DHAL_BACKEND_SDK + # The SDK backend folds the RealTek SDK driver chain into hal/rtl8735b.o. + # Its objects.h pulls the SDK's "hal.h" (defines flash_t, + # hal_audio_adapter_t, ...); wolfBoot also ships "hal.h". hal/rtl8735b.c + # does not include wolfBoot's hal.h, and the SDK dirs are passed with + # -iquote (searched before the global -I for quoted includes) so the SDK + # objects.h "hal.h" resolves to the SDK one for THIS object only. sdk-shim + # supplies a stub cmsis_os.h so the chain does not pull CMSIS-OS/FreeRTOS + # (wolfBoot never calls it). The CONFIG_* defines mirror the bare-metal + # bootloader build; -mcmse satisfies the SDK cache header (SCB_NS). The + # rest of wolfBoot stays plain M33. + HAL_SDK_IQUOTE=-iquote $(WOLFBOOT_ROOT)/hal/rtl8735b/sdk-shim \ + -iquote $(AMEBA_SDK)/component/mbed/hal_ext \ + -iquote $(AMEBA_SDK)/component/mbed/hal \ + -iquote $(AMEBA_SDK)/component/mbed/api \ + -iquote $(AMEBA_SDK)/component/mbed/targets/hal/rtl8735b \ + -iquote $(AMEBA_SDK)/component/soc/8735b/fwlib/rtl8735b/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/fwlib/rtl8735b/lib/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/cmsis/rtl8735b/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/cmsis/rtl8735b/lib/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/cmsis/cmsis-core/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/app/rtl_printf/include \ + -iquote $(AMEBA_SDK)/component/soc/8735b/app/stdio_port \ + -iquote $(AMEBA_SDK)/component/soc/8735b/misc/utilities/include \ + -iquote $(AMEBA_SDK)/component/os/os_dep/include + # The same dirs as plain -I too, so angle-bracket includes (e.g. some + # CMSIS-Core headers) resolve; -iquote only covers quoted includes. + HAL_SDK_INC=$(patsubst -iquote,-I,$(HAL_SDK_IQUOTE)) + HAL_SDK_DEFS=-DCONFIG_PLATFORM_8735B -DCONFIG_RTL8735B_PLATFORM=1 \ + -DCONFIG_BUILD_RAM=1 + hal/rtl8735b.o: CFLAGS += $(HAL_SDK_IQUOTE) $(HAL_SDK_INC) $(HAL_SDK_DEFS) -mcmse -Wno-error + # Final link also needs the SDK fwlib + ROM symbol table; point at the + # prebuilt SDK lib/objects and ROM symbol linker file during bring-up: + # make TARGET=rtl8735b LIBS+=... LDFLAGS_EXTRA="-T" + else + CFLAGS+=-DHAL_BACKEND_BARE + endif + endif + ifeq ($(TARGET),sama5d3) CORTEX_A5=1 UPDATE_OBJS:=src/update_ram.o diff --git a/config/examples/rtl8735b.config b/config/examples/rtl8735b.config new file mode 100644 index 0000000000..508b36f810 --- /dev/null +++ b/config/examples/rtl8735b.config @@ -0,0 +1,58 @@ +ARCH?=ARM +TARGET?=rtl8735b +SIGN?=ECC256 +HASH?=SHA256 + +# ECC256 + SHA256 header fits in 256 bytes +IMAGE_HEADER_SIZE?=256 + +# Cortex-M33 (single, non-TrustZone secure world for Model A) +CORTEX_M33?=1 +TZEN?=0 +VTOR?=1 +NO_MPU?=1 + +# wolfBoot is staged into SRAM by the RealTek bootloader (not XIP). It reads the +# BOOT/UPDATE/SWAP partitions from external SPI NOR and copies the verified +# application into DDR before jumping (src/update_ram.c RAMBOOT path). +NO_XIP?=1 +EXT_FLASH?=1 +SPI_FLASH?=0 +WOLFBOOT_DUALBOOT?=1 + +# wolfBoot runs entirely from SRAM, so RAM_CODE relocation is unnecessary. +RAM_CODE?=0 + +DEBUG?=0 +DEBUG_UART?=1 +V?=0 +SPMATH?=1 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE?=0 + +WOLFBOOT_VERSION?=1 + +# 4 KB SPI NOR sector (flash_erase_sector granularity) +WOLFBOOT_SECTOR_SIZE?=0x1000 + +# DDR base the verified application is copied to and launched from. Must match +# the application's vector-table link address (Risk: confirm valid DDR base). +WOLFBOOT_LOAD_ADDRESS?=0x70000000 + +# External SPI NOR partition layout. These are raw NOR byte offsets addressed +# only by ext_flash_*; they must not overlap the RealTek partition table +# (PARTBL/cert/boot/PT_FW1=wolfBoot/ISP/VOE). PT_FW1 holds wolfBoot itself. +# NOTE: placeholders -- confirm against the EVB amebapro2_partitiontable.json +# before flashing so they land in genuinely free NOR. +WOLFBOOT_PARTITION_SIZE?=0x180000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x1000000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x1180000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x1300000 + +# Flash/UART/cache backend: "sdk" (default, RealTek SDK drivers) or "bare" +# (smaller, no SDK dependency -- not yet implemented). +HAL_BACKEND?=sdk + +# RealTek SDK + ASDK toolchain locations (override on the command line). +AMEBA_SDK?=$(HOME)/GitHub/ameba-rtos-pro2 +ASDK_PATH?=$(HOME)/ameba-pro2-workspace/asdk/asdk-10.3.0/linux/newlib/bin diff --git a/hal/rtl8735b.c b/hal/rtl8735b.c new file mode 100644 index 0000000000..f82c55175a --- /dev/null +++ b/hal/rtl8735b.c @@ -0,0 +1,348 @@ +/* rtl8735b.c + * + * HAL for the RealTek RTL8735B SoC (Cortex-M33), as used on the AmebaPro2 EVB + * and compatible boards. + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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-1301, USA + * + * + * Model A (non-TrustZone): the RealTek bootloader stages wolfBoot into SRAM via + * the RealTek RAM_FUNCTION_START_TABLE below. wolfBoot then reads the + * BOOT/UPDATE/SWAP partitions from external SPI NOR (ext_flash_*), verifies the + * application, copies it into DDR (src/update_ram.c RAMBOOT path) and jumps. + * + * Flash/UART/cache backend, selected at build time with HAL_BACKEND (arch.mk): + * HAL_BACKEND=sdk (default) - use the RealTek SDK drivers (flash_api / + * rt_printf / hal_cache). Compiled with the SDK include + * dirs via -iquote, a stub cmsis_os.h (so the chain does not + * pull FreeRTOS), the bootloader CONFIG_* defines, and + * -mcmse. See hal/rtl8735b/README. + * HAL_BACKEND=bare - a smaller backend with no SDK dependency (direct + * register / ROM access). Not yet implemented. + * + * NOTE: wolfBoot's own "hal.h" is intentionally NOT included here. The RealTek + * SDK also ships a "hal.h" (pulled by its objects.h), and in the SDK backend the + * SDK include dirs are passed via -iquote so that header resolves to the SDK + * one. Including wolfBoot's hal.h in the same translation unit would clash, so + * the HAL entry points this file implements are declared locally below. + */ + +#include +#include + +#include "target.h" +#include "wolfboot/wolfboot.h" +#include "printf.h" /* wolfBoot_printf, uart_init, uart_write */ + +/* HAL entry points implemented in this file (see note above re: hal.h). */ +void hal_init(void); +void hal_flash_unlock(void); +void hal_flash_lock(void); +int hal_flash_write(uint32_t address, const uint8_t *data, int len); +int hal_flash_erase(uint32_t address, int len); +void hal_prepare_boot(void); +int ext_flash_read(uintptr_t address, uint8_t *data, int len); +int ext_flash_write(uintptr_t address, const uint8_t *data, int len); +int ext_flash_erase(uintptr_t address, int len); +void ext_flash_lock(void); +void ext_flash_unlock(void); + +#ifdef HAL_BACKEND_SDK + /* The SDK's basic_types.h defines likely()/unlikely() too; drop wolfBoot's + * so the SDK definitions apply without a redefinition warning. */ + #undef likely + #undef unlikely + + /* RealTek SDK drivers. log_uart_api.h is Ameba1-only (CONFIG_PLATFORM_8195A) + * and empty on the 8735B; the console is the ROM-backed rt_printf writing to + * the LOGUART the bootloader already configured. */ + #include "flash_api.h" + #include "hal_cache.h" + #include "rt_printf.h" + + /* Set by the SDK flash driver; seeded from the bootloader-provided adaptor. */ + extern hal_spic_adaptor_t *pglob_spic_adaptor; + /* flash_init() is an SDK symbol not declared in flash_api.h. */ + extern void flash_init(flash_t *obj); + + static flash_t hal_flash_obj; +#endif /* HAL_BACKEND_SDK */ + +/* =========================================================================== + * RealTek RAM start-table: launched by the RealTek bootloader (backend common). + * + * Field order/types mirror the SDK rtl8735b_ramstart.h so the bootloader reads + * each field at the right offset. RamStartFun points at the trampoline below, + * which sets MSP and branches to wolfBoot's isr_reset. Embedding the table here + * makes wolfboot.elf directly launchable (no separate shim). + * =========================================================================== + */ + +extern void wolfboot_ram_entry(void); + +/* Scratch SRAM the bootloader may write through the table's buffer pointers + * (including the SPIC adaptor it initialized). */ +static uint8_t hal_bl_scratch[2048] + __attribute__((section(".ram.bss"), aligned(32))); + +/* Exactly the 10 bytes "AmebaPro2\xff" (the trailing 0xff matters; a NUL pad + * fails as "Invalid FW Image Signature"). */ +const unsigned char hal_ram_img_sig[10] + __attribute__((section(".ram.img.signature"), aligned(4))) = { + 'A', 'm', 'e', 'b', 'a', 'P', 'r', 'o', '2', 0xff +}; + +typedef struct { + void *Signature; + void (*RamStartFun)(void); + void (*RamWakeupFun)(void); + void (*RamPatchFun0)(void); + void (*RamPatchFun1)(void); + void *sys_cp_fw_info; + void *pbl_peri_buf; + void *pxip_sce_restore; + uint32_t entry_start; + uint32_t entry_end; + uint8_t *hash_data; + uint32_t ddr_hash_start1; + uint32_t ddr_hash_end1; + uint32_t ddr_hash_start2; + uint32_t ddr_hash_end2; + uint8_t *ddr_hash_data; + uint32_t boot_cfg_w; + uint32_t msp_start; + uint32_t msp_limit; + uint32_t start_tbl_size; + void *phal_spic_adaptor; + uint32_t flash_user_data_offset; + uint32_t flash_user_data_len; + void *pbl_shared_buf; + uint32_t init_flags; + uint32_t boot_status; + uint8_t reserved1; + uint8_t sys_tmr_id; + uint16_t pad; + void *pfw_image_info; + void *pbl_ld_voe_info; + void *pSnand_layout_info; + uint32_t reserved2[2]; +} ram_start_table_t; + +const ram_start_table_t ram_start_table + __attribute__((section(".ram.func.table"), used)) = { + .Signature = (void *)hal_ram_img_sig, + .RamStartFun = wolfboot_ram_entry, + .msp_start = 0x20120000u, /* valid early SRAM stack */ + .msp_limit = 0x2011f000u, + .start_tbl_size = sizeof(ram_start_table_t), + .pbl_peri_buf = &hal_bl_scratch[0], + .pbl_shared_buf = &hal_bl_scratch[256], + .pfw_image_info = &hal_bl_scratch[512], + .pbl_ld_voe_info = &hal_bl_scratch[768], + .pSnand_layout_info = &hal_bl_scratch[1024], + .sys_cp_fw_info = &hal_bl_scratch[1280], + .phal_spic_adaptor = &hal_bl_scratch[1536], +}; + +/* Trampoline the bootloader jumps to: set MSP to the top of wolfBoot's SRAM + * region and branch into wolfBoot's normal reset path (src/boot_arm.c). This + * removes any dependency on the loader honoring the ARM vector table's word0. */ +__attribute__((naked, used, section(".ram.code_text"))) +void wolfboot_ram_entry(void) +{ + __asm__ volatile( + "ldr r0, =END_STACK\n\t" + "msr msp, r0\n\t" + "ldr r0, =isr_reset\n\t" + "bx r0\n\t" + ); +} + +/* =========================================================================== + * Debug UART (wolfBoot banner / logs). + * =========================================================================== + */ +#ifdef DEBUG_UART +void uart_init(void) +{ + /* SDK: the bootloader already configured the LOGUART, nothing to do. + * bare: TODO bring up the log UART via direct registers / ROM. */ +} + +void uart_write(const char *buf, unsigned int sz) +{ + unsigned int i; + + for (i = 0; i < sz; i++) { +#ifdef HAL_BACKEND_SDK + /* rt_printf is the 8735B console macro routing through the ROM + * stdio_printf_stubs to the LOGUART. */ + if (buf[i] == '\n') { + rt_printf("%c", (int)'\r'); + } + rt_printf("%c", (int)buf[i]); +#else + (void)buf; + (void)i; +#endif + } +} +#endif /* DEBUG_UART */ + +/* =========================================================================== + * HAL init / boot handoff. + * =========================================================================== + */ +void hal_init(void) +{ +#ifdef DEBUG_UART + uart_init(); +#endif + +#ifdef HAL_BACKEND_SDK + /* Reuse the SPIC adaptor the bootloader handed us through the RAM + * start-table so flash_init() does not re-train the controller. If it is + * NULL, flash_init() re-initializes (safe: the flash is already up). */ + if (ram_start_table.phal_spic_adaptor != NULL) { + pglob_spic_adaptor = + (hal_spic_adaptor_t *)ram_start_table.phal_spic_adaptor; + } + memset(&hal_flash_obj, 0, sizeof(hal_flash_obj)); + flash_init(&hal_flash_obj); +#endif + + wolfBoot_printf("wolfBoot HAL: RTL8735B (AmebaPro2) init\n"); +} + +void hal_prepare_boot(void) +{ + /* The application was written into DDR via ext_flash_read()/memcpy. The + * RTL8735B has its own I/D cache (not Arm SCB): clean+invalidate D-cache so + * the writes hit DDR, then invalidate I-cache so stale lines do not shadow + * the new app, before do_boot() jumps. */ +#ifdef HAL_BACKEND_SDK + dcache_clean_invalidate(); + icache_invalidate(); +#endif + __asm__ volatile("dsb\n\tisb\n\t"); +} + +/* =========================================================================== + * Internal flash: unused. wolfBoot runs from SRAM and keeps its partitions in + * external SPI NOR, so these are no-ops (BOOT/UPDATE/SWAP are all PART_*_EXT). + * =========================================================================== + */ +void hal_flash_unlock(void) +{ +} + +void hal_flash_lock(void) +{ +} + +int hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + (void)address; + (void)data; + (void)len; + return 0; +} + +int hal_flash_erase(uint32_t address, int len) +{ + (void)address; + (void)len; + return 0; +} + +/* =========================================================================== + * External SPI NOR (raw byte offsets). + * =========================================================================== + */ +void ext_flash_unlock(void) +{ +#ifdef HAL_BACKEND_SDK + flash_global_unlock(); +#endif +} + +void ext_flash_lock(void) +{ +#ifdef HAL_BACKEND_SDK + flash_global_lock(); +#endif +} + +int ext_flash_read(uintptr_t address, uint8_t *data, int len) +{ + if (len <= 0) { + return -1; + } +#ifdef HAL_BACKEND_SDK + (void)flash_stream_read(&hal_flash_obj, (uint32_t)address, (uint32_t)len, + data); + return len; +#else + /* TODO(bare): implement via direct SPIC / ROM hal_flash_stream_read. */ + (void)address; + (void)data; + return -1; +#endif +} + +int ext_flash_write(uintptr_t address, const uint8_t *data, int len) +{ + if (len <= 0) { + return -1; + } +#ifdef HAL_BACKEND_SDK + (void)flash_stream_write(&hal_flash_obj, (uint32_t)address, (uint32_t)len, + (uint8_t *)data); + return 0; +#else + /* TODO(bare): implement via direct SPIC / ROM hal_flash_burst_write. */ + (void)address; + (void)data; + return -1; +#endif +} + +int ext_flash_erase(uintptr_t address, int len) +{ + uint32_t sector_addr; + uint32_t end_addr; + + if (len <= 0 || (uint32_t)len > UINT32_MAX - (uint32_t)address) { + return -1; + } + + /* Erase every WOLFBOOT_SECTOR_SIZE sector spanning [address, address+len). */ + sector_addr = (uint32_t)address & ~((uint32_t)WOLFBOOT_SECTOR_SIZE - 1); + end_addr = (uint32_t)address + (uint32_t)len; + while (sector_addr < end_addr) { +#ifdef HAL_BACKEND_SDK + flash_erase_sector(&hal_flash_obj, sector_addr); +#else + /* TODO(bare): implement via direct SPIC / ROM hal_flash_sector_erase. */ + return -1; +#endif + sector_addr += WOLFBOOT_SECTOR_SIZE; + } + return 0; +} diff --git a/hal/rtl8735b.ld b/hal/rtl8735b.ld new file mode 100644 index 0000000000..2ae3406e32 --- /dev/null +++ b/hal/rtl8735b.ld @@ -0,0 +1,94 @@ +/* wolfBoot linker script for the RealTek RTL8735B (e.g. AmebaPro2 EVB). + * + * wolfBoot is staged into SRAM by the RealTek bootloader through a RealTek + * RAM_FUNCTION_START_TABLE. This script places that table, its image + * signature, and wolfBoot's text/data/bss at the fixed SRAM addresses the + * bootloader expects (cribbed from the proven zephyr_shim/shim.ld), and + * exports the wolfBoot partition symbols templated by the Makefile. + * + * The image is loaded (not XIP) into SRAM, so .data is placed in SRAM and + * _stored_data == _start_data; isr_reset's flash->RAM .data copy is then a + * no-op while BSS zeroing still runs. + */ + +MEMORY +{ + SRAM (rwx) : ORIGIN = 0x20106200, LENGTH = 0x39E00 /* up to ~0x20140000 */ +} + +ENTRY(isr_reset) + +SECTIONS +{ + /* RealTek RAM start-table at the fixed address the bootloader reads. */ + .ram.func.table 0x20106200 : + { + __ram_start_table_start__ = .; + KEEP(*(.ram.func.table)) + __ram_start_table_end__ = .; + } > SRAM + + /* 10-byte "AmebaPro2\xff" image signature at its fixed address. */ + .ram.img.signature 0x201062f0 : + { + KEEP(*(.ram.img.signature)) + } > SRAM + + .ram.code_text 0x20106300 : + { + _start_text = .; + KEEP(*(.ram.code_text)) /* RamStartFun trampoline */ + KEEP(*(.isr_vector)) /* wolfBoot ARM vector table */ + *(.text*) + *(.rodata*) + *(.keystore*) + *(.init*) + *(.fini*) + . = ALIGN(4); + _end_text = .; + } > SRAM + + .edidx : + { + . = ALIGN(4); + *(.ARM.exidx*) + } > SRAM + + _stored_data = .; + .data : + { + _start_data = .; + KEEP(*(.ramcode*)) + KEEP(*(.data*)) + . = ALIGN(4); + _end_data = .; + } > SRAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(.ram.bss) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + __bss_end__ = .; + _end = .; + } > SRAM + + /DISCARD/ : + { + *(.ARM.attributes) + *(.comment) + *(.eh_frame*) + } +} + +END_STACK = 0x20140000; + +/* Partition symbols templated by the Makefile (raw external SPI NOR offsets). */ +_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; +_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; +_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; +_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; diff --git a/hal/rtl8735b/README b/hal/rtl8735b/README new file mode 100644 index 0000000000..1d964154d0 --- /dev/null +++ b/hal/rtl8735b/README @@ -0,0 +1,72 @@ +RealTek RTL8735B HAL +==================== + +wolfBoot's HAL for the RTL8735B SoC (AmebaPro2 EVB and compatible boards) lives +entirely in hal/rtl8735b.c, with two interchangeable flash/UART/cache backends +selected at build time by HAL_BACKEND (see the .config and arch.mk): + + HAL_BACKEND=sdk (default) - use the RealTek SDK drivers. + HAL_BACKEND=bare - a smaller backend with no SDK dependency + (direct register / ROM access). Stubbed; not + yet implemented. + + hal/rtl8735b.c - the whole HAL: hal_init, ext_flash_*, + hal_prepare_boot, the RealTek RAM start-table + + trampoline, and BOTH backends (gated on + HAL_BACKEND_SDK). + hal/rtl8735b.ld - SRAM layout + RealTek RAM start-table sections. + hal/rtl8735b/sdk-shim/cmsis_os.h - stub CMSIS-OS header (see below). + config/examples/rtl8735b.config - example config (TARGET=rtl8735b). + +The bare backend builds standalone and links a complete wolfboot.elf. The sdk +backend compiles the RealTek SDK driver chain into hal/rtl8735b.o; its final link +references the SDK fwlib + ROM symbol table (see "Building / linking"). + +Two header tricks make the SDK chain build inside wolfBoot's tree +----------------------------------------------------------------- +1. hal.h name clash. The RealTek SDK and wolfBoot BOTH ship a header named + "hal.h". The SDK's objects.h does #include "hal.h" expecting the SDK + aggregation (flash_t, hal_audio_adapter_t via hal_api.h), but wolfBoot's + include/hal.h would shadow it. So hal/rtl8735b.c does NOT include wolfBoot's + hal.h (it declares the HAL entry points it implements directly), and arch.mk + passes the SDK dirs with -iquote so the SDK's hal.h wins for that quoted + include without disturbing the rest of the tree. + +2. No FreeRTOS. The SDK's cmsis.h unconditionally includes "cmsis_os.h" + (CONFIG_CMSIS_FREERTOS_EN is hardcoded), which cascades into FreeRTOS. + wolfBoot never calls CMSIS-OS, so sdk-shim/cmsis_os.h provides a stub with + just the few CMSIS-OS typedefs the SDK headers reference while parsing (e.g. + diag.h's osMutexId), placed ahead of the real one -- pulling zero FreeRTOS. + arch.mk also mirrors the bootloader's CONFIG_* defines and adds -mcmse (the + SDK cache header needs SCB_NS). + +Console: log_uart_api.h is Ameba1-only (CONFIG_PLATFORM_8195A) and empty on the +8735B; the console is the ROM-backed rt_printf (stdio_printf_stubs) writing to +the LOGUART the bootloader already configured. + +Building / linking +------------------ +1. wolfBoot: make TARGET=rtl8735b (sdk backend, default) + make TARGET=rtl8735b HAL_BACKEND=bare (standalone) + +2. The sdk backend's remaining undefined symbols are genuine SDK/ROM symbols: + flash_init, flash_stream_read/write, flash_erase_sector, flash_global_*, + pglob_spic_adaptor (from the SDK mbed flash_api.c), and hal_cache_stubs, + stdio_printf_stubs (ROM symbol tables). Link against the SDK fwlib object/lib + and the SDK ROM symbol linker file, e.g.: + make TARGET=rtl8735b LIBS+= \ + LDFLAGS_EXTRA="-T" + Resolve the exact lib/ROM linker file in the SDK build during bring-up. + +3. Package: tools/scripts/amebapro2_package.sh wolfboot.elf + (board-level: uses the AmebaPro2 EVB partition table + elf2bin). + +SPIC adaptor reuse +------------------ +The RealTek bootloader initializes the SPIC controller before launching wolfBoot +and hands the adaptor through the RAM start-table field phal_spic_adaptor +(hal/rtl8735b.c). hal_init() seeds pglob_spic_adaptor with it so flash_init() +reuses it instead of re-training the flash. If it is NULL the controller is +re-initialized (safe: the flash is already up). + +Do not relicense or reformat vendored RealTek code; preserve its copyright. diff --git a/hal/rtl8735b/sdk-shim/cmsis_os.h b/hal/rtl8735b/sdk-shim/cmsis_os.h new file mode 100644 index 0000000000..a1df5b3acb --- /dev/null +++ b/hal/rtl8735b/sdk-shim/cmsis_os.h @@ -0,0 +1,46 @@ +/* cmsis_os.h (wolfBoot AmebaPro2 SDK shim) + * + * The RealTek SDK header chain (cmsis.h) unconditionally includes "cmsis_os.h", + * which in the SDK is the CMSIS-OS wrapper over FreeRTOS. wolfBoot's use of the + * SDK flash / log-UART / cache drivers is bare-metal and never calls any + * CMSIS-OS API, but a few SDK headers (e.g. diag.h: "extern osMutexId + * PrintLock_id;") reference CMSIS-OS types while being parsed. + * + * This stub satisfies those references with opaque types so the SDK headers + * compile WITHOUT pulling FreeRTOS into wolfBoot's standalone build. It is + * placed on the include path ahead of the SDK's real cmsis_os.h, and is used + * only for hal/rtl8735b.o when HAL_BACKEND=sdk. + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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-1301, USA + */ +#ifndef WOLFBOOT_AMEBAPRO2_CMSIS_OS_SHIM_H +#define WOLFBOOT_AMEBAPRO2_CMSIS_OS_SHIM_H + +#include + +typedef void *osMutexId; +typedef void *osSemaphoreId; +typedef void *osThreadId; +typedef void *osMessageQId; +typedef void *osMailQId; +typedef void *osTimerId; +typedef void *osPoolId; +typedef int32_t osStatus; + +#endif /* WOLFBOOT_AMEBAPRO2_CMSIS_OS_SHIM_H */ diff --git a/tools/scripts/amebapro2_package.sh b/tools/scripts/amebapro2_package.sh new file mode 100755 index 0000000000..988c9a2701 --- /dev/null +++ b/tools/scripts/amebapro2_package.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Package wolfboot.elf into a RealTek RTL8735B (AmebaPro2) flash image. +# +# wolfboot.elf already embeds the RealTek RAM start-table (hal/amebapro2.c), so +# unlike the zephyr_shim flow there is no separate shim.elf and no DDR blob: +# wolfBoot is SRAM-only and loads the application from external SPI NOR itself. +# This runs RealTek's elf2bin convert (wolfBoot -> PT_FW1 firmware.bin) and +# combine (reusing the vendor PARTBL/certs/boot.bin) to produce flash_ntz.bin. +# +# Usage: amebapro2_package.sh [wolfboot.elf] +# +# Override via environment: +# AMEBA_SDK RealTek ameba-rtos-pro2 checkout +# ASDK_PATH ASDK 10.3.0 toolchain bin dir +# OUTDIR work/output dir (default /tmp/wolfboot_amebapro2_pkg) +set -e + +WOLFBOOT_ELF="${1:-wolfboot.elf}" +AMEBA_SDK="${AMEBA_SDK:-$HOME/GitHub/ameba-rtos-pro2}" +ASDK_PATH="${ASDK_PATH:-$HOME/ameba-pro2-workspace/asdk/asdk-10.3.0/linux/newlib/bin}" +OUTDIR="${OUTDIR:-/tmp/wolfboot_amebapro2_pkg}" + +SDK="$AMEBA_SDK/project/realtek_amebapro2_v0_example" +MP="$SDK/GCC-RELEASE/mp" +B="$SDK/GCC-RELEASE/build" + +if [ ! -r "$WOLFBOOT_ELF" ]; then + echo "error: cannot read $WOLFBOOT_ELF" >&2 + exit 1 +fi +if [ ! -d "$MP" ]; then + echo "error: RealTek SDK MP dir not found: $MP" >&2 + echo " set AMEBA_SDK to your ameba-rtos-pro2 checkout" >&2 + exit 1 +fi + +WOLFBOOT_ELF_ABS="$(readlink -f "$WOLFBOOT_ELF")" + +rm -rf "$OUTDIR" +mkdir -p "$OUTDIR" +cd "$OUTDIR" + +# Tooling + vendor partition/cert/boot artifacts (reused as-is). +cp "$MP/elf2bin.linux" "$MP/checksum.linux" . +cp "$MP"/*.json . +cp "$WOLFBOOT_ELF_ABS" wolfboot.elf +cp "$B/partition.bin" "$B/certable.bin" "$B/certificate.bin" \ + "$B/boot.bin" "$B/boot_fcs.bin" . +chmod +x elf2bin.linux checksum.linux + +# Build the firmware json: wolfBoot SRAM-only image, entry at the start-table. +python3 - <<'PY' +import json +j = json.load(open('amebapro2_firmware_ntz.json')) +j['FW'] = { + "source": "wolfboot.elf", + "header": {"type": "IMG_FWHS_S", "entry": "__ram_start_table_start__"}, + "blocks": ["sram"], + "sram": { + "type": "SIMG_SRAM", + "sections": [ + ".ram.img.signature", + ".ram.func.table", + ".ram.code_text", + ".data" + ] + } +} +# wolfBoot does not ship the ISP/VOE blobs; package FW only. +j['FIRMWARE']['images'] = ["FW"] +json.dump(j, open('wolfboot_fw.json', 'w'), indent=2) +PY + +./elf2bin.linux convert wolfboot_fw.json FIRMWARE firmware.bin \ + > "$OUTDIR/convert.log" 2>&1 + +./elf2bin.linux combine amebapro2_partitiontable.json flash_ntz.bin \ + PT_PT=partition.bin,CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FW1=firmware.bin,PT_FCSDATA=boot_fcs.bin \ + > "$OUTDIR/combine.log" 2>&1 + +echo "built: $OUTDIR/flash_ntz.bin ($(stat -c %s flash_ntz.bin) bytes)" +echo "note: flash the signed app separately into the BOOT partition offset" +echo " (WOLFBOOT_PARTITION_BOOT_ADDRESS) via uartfwburn."