Skip to content

Commit 13b3bf5

Browse files
committed
imx95_a55: add the Cortex-A55 target and a stage 1 replacing U-Boot SPL
1 parent 4d7dca7 commit 13b3bf5

22 files changed

Lines changed: 4603 additions & 67 deletions

‎.github/workflows/test-configs.yml‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,33 @@ jobs:
454454
config-file: ./config/examples/imx95-m7.config
455455
make-args: wolfboot.bin test-app/image_v1_signed.bin
456456

457+
imx95_a55_test:
458+
uses: ./.github/workflows/test-build.yml
459+
with:
460+
arch: aarch64
461+
# i.MX95 Cortex-A55 as BL33. The payload is a Linux FIT on the boot
462+
# medium, so there is no test app and no contiguous factory.bin.
463+
config-file: ./config/examples/imx95-a55.config
464+
make-args: wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-
465+
466+
imx95_a55_stage1_emmc_test:
467+
uses: ./.github/workflows/test-build.yml
468+
with:
469+
arch: aarch64
470+
# The stage 1 that replaces U-Boot SPL, reading the containers from the
471+
# eMMC boot partition. Nothing else compiles the AHAB parser or the
472+
# OCRAM link, so this keeps both from rotting.
473+
config-file: ./config/examples/imx95-a55.config
474+
make-args: -C stage1 DISK_EMMC=1 DISK_SDCARD=0 loader_stage1.bin CROSS_COMPILE=aarch64-linux-gnu-
475+
476+
imx95_a55_stage1_sd_test:
477+
uses: ./.github/workflows/test-build.yml
478+
with:
479+
arch: aarch64
480+
# Same stage 1 against the SD controller rather than the eMMC one.
481+
config-file: ./config/examples/imx95-a55.config
482+
make-args: -C stage1 DISK_SDCARD=1 DISK_EMMC=0 loader_stage1.bin CROSS_COMPILE=aarch64-linux-gnu-
483+
457484
tegra234_test:
458485
uses: ./.github/workflows/test-build.yml
459486
with:

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ tools/unit-tests/unit-va416x0-fram
258258
tools/unit-tests/unit-wolfhsm_flash_hal
259259
tools/unit-tests/unit-ubootenv
260260
tools/unit-tests/unit-cm4-sdhci
261+
tools/unit-tests/unit-imx95-ahab
261262
tools/unit-tests/unit-cm4-rauc-slot
262263
tools/unit-tests/__pycache__/*
263264

‎Makefile‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ ifeq ($(TARGET),tegra234)
431431
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
432432
endif
433433

434+
# i.MX95 A55 is a RAM-resident BL33 loaded by SPL inside an AHAB container, so
435+
# there is no contiguous flash image to assemble into a factory.bin.
436+
ifeq ($(TARGET),imx95_a55)
437+
MAIN_TARGET:=wolfboot.bin
438+
endif
439+
434440
ifeq ($(TARGET),cm4)
435441
MAIN_TARGET:=wolfboot.bin
436442
endif

‎arch.mk‎

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ifeq ($(ARCH),AARCH64)
7575
# Skip the bare-metal reset (boot_aarch64_start.S) and EL2/GIC glue.
7676
OBJS+=src/boot_aarch64_efi.o
7777
else
78-
OBJS+=src/boot_aarch64.o src/boot_aarch64_start.o
78+
OBJS+=src/boot_aarch64.o src/boot_aarch64_start.o src/boot_aarch64_cache.o
7979
endif
8080

8181
ifeq ($(TARGET),zynq)
@@ -308,6 +308,56 @@ ifeq ($(ARCH),AARCH64)
308308
endif
309309
endif
310310

311+
ifeq ($(TARGET),imx95_a55)
312+
# NXP i.MX95 Cortex-A55 cluster, running as BL33 in AHAB container 2.
313+
# -mstrict-align because this stage runs with the MMU off, so every access
314+
# is Device-nGnRnE and unaligned ones fault.
315+
ARCH_FLAGS=-mcpu=cortex-a55+crypto -march=armv8.2-a+crypto -mstrict-align
316+
CFLAGS+=$(ARCH_FLAGS) -DCORTEX_A55
317+
LDFLAGS+=$(ARCH_FLAGS)
318+
# BL31 loads and enters this image here; must match ORIGIN in
319+
# hal/imx95_a55.ld and IMX95_BL33_BASE in hal/imx95_a55.h.
320+
WOLFBOOT_ORIGIN=0x90200000
321+
# Console, SCMI client and uSDHC driver all live in hal/imx95_a55.c, so none
322+
# needs its own object; the switches below pick which paths compile in.
323+
# Bring-up aid: print the entry EL, SCTLR and handoff x0 that BL31 passed.
324+
ifeq ($(IMX95_HANDOFF_DUMP),1)
325+
CFLAGS+=-DIMX95_HANDOFF_DUMP
326+
endif
327+
# i.MX95 is GICv3 and BL31 already configured it. EL2_HYPERVISOR is not a
328+
# generic options.mk variable, so it is emitted here as tegra234 does.
329+
ifeq ($(EL2_HYPERVISOR),1)
330+
CFLAGS+=-DEL2_HYPERVISOR=1
331+
endif
332+
# i.MX uSDHC is not SDHCI-compatible: skip src/sdhci.c, use our driver.
333+
ifneq ($(filter 1,$(DISK_SDCARD) $(DISK_EMMC)),)
334+
DISK_DRIVER=usdhc
335+
# SCMI cold-init of uSDHC2 (clock+pinmux) when no prior stage did it.
336+
ifeq ($(IMX95_SCMI_COLD_INIT),1)
337+
CFLAGS+=-DIMX95_SCMI_COLD_INIT
338+
endif
339+
endif
340+
# SCMI M7 power-on + TCM ECC scrub (U-Boot's power_on_m7 equivalent) for a
341+
# Cortex-M7 that Linux launches later. Independent of the disk driver.
342+
ifeq ($(IMX95_INIT_M7),1)
343+
CFLAGS+=-DIMX95_INIT_M7
344+
endif
345+
# One-shot diagnostic: read the AHAB container out of the eMMC boot
346+
# partitions and report it, from inside an image that boots from SD.
347+
ifeq ($(IMX95_EMMC_PROBE),1)
348+
CFLAGS+=-DIMX95_EMMC_PROBE
349+
OBJS+=hal/imx95_ahab.o
350+
endif
351+
# Mirror the console into a DDR ring that survives the handoff to Linux.
352+
ifeq ($(IMX95_LOG_RING),1)
353+
CFLAGS+=-DIMX95_LOG_RING
354+
endif
355+
# Verbose per-step trace of the SCMI cold-init and SD bring-up.
356+
ifeq ($(IMX95_SCMI_DEBUG),1)
357+
CFLAGS+=-DIMX95_SCMI_DEBUG
358+
endif
359+
endif
360+
311361
ifeq ($(TARGET),cm4)
312362
# Raspberry Pi Compute Module 4 - Broadcom BCM2711, Cortex-A72
313363
ARCH_FLAGS=-mcpu=cortex-a72+crypto -march=armv8-a+crypto -mtune=cortex-a72
@@ -334,7 +384,7 @@ ifeq ($(ARCH),AARCH64)
334384
# asm (sp_arm64.c / WOLFSSL_SP_ARM64_ASM); that is enabled independently on
335385
# __aarch64__ in include/user_settings.h, so a non-FIPS cm4 build still links
336386
# sp_arm64 asm.
337-
ifeq ($(filter zynq versal nxp_ls1028a,$(TARGET)),)
387+
ifeq ($(filter zynq versal nxp_ls1028a imx95_a55,$(TARGET)),)
338388
NO_ARM_ASM?=1
339389
endif
340390

‎config/examples/imx95-a55.config‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# NXP i.MX95 Cortex-A55 - wolfBoot as BL33 (replaces U-Boot proper):
2+
# ROM -> ELE -> SM -> OEI -> SPL [c1] -> BL31 -> OP-TEE -> wolfBoot -> Linux
3+
# wolfBoot takes U-Boot's slot in AHAB container 2 at 0x90200000; the other
4+
# container images are the vendor's, reused verbatim.
5+
#
6+
# `make stage1` from this same config also replaces SPL, and then the chain is
7+
# ROM -> ELE -> SM -> OEI -> wolfBoot [c1] -> BL31 -> OP-TEE -> wolfBoot
8+
# with stage 1 making the ELE call that authenticates container 2 that SPL used
9+
# to make (IMX95_AHAB_AUTH, on by default). See docs/Targets.md.
10+
11+
ARCH?=AARCH64
12+
TARGET?=imx95_a55
13+
14+
# ML-DSA-87, matching the imx95_m7 port. Header fits sig (4627) + pubkey.
15+
SIGN?=ML_DSA
16+
ML_DSA_LEVEL?=5
17+
HASH?=SHA256
18+
# Required: unset, ML_DSA_IMAGE_SIGNATURE_SIZE expands empty -> image.c errors.
19+
IMAGE_SIGNATURE_SIZE?=4627
20+
IMAGE_HEADER_SIZE?=12288
21+
22+
DEBUG?=0
23+
DEBUG_SYMBOLS=1
24+
DEBUG_UART?=1
25+
# Print entry EL, SCTLR, MPIDR, CNTFRQ and the handoff x0 pointer.
26+
IMX95_HANDOFF_DUMP?=1
27+
# Report how long each boot step takes, in ms, from the generic timer.
28+
BOOT_BENCHMARK?=1
29+
# Also mirror the console into a DDR ring, so the verified-boot log can be read
30+
# from Linux (and shown on a display) long after the UART output has scrolled.
31+
IMX95_LOG_RING?=1
32+
33+
V?=0
34+
SPMATH?=1
35+
NO_ASM?=0
36+
37+
# RAM-resident: BL31 loads and enters this image, so there is nothing to copy
38+
# from a stored .data and no XIP flash behind it.
39+
NO_XIP?=1
40+
41+
# GICv3, configured by BL31; gicv2_init_secure() would abort on an unmapped
42+
# ZynqMP address.
43+
SKIP_GIC_INIT?=1
44+
45+
# Stay at EL2 (Linux wants it for KVM). Do NOT set BOOT_EL1: el2_to_el1_boot
46+
# skips cache/MMU cleanup and would hand Linux stale DRAM.
47+
EL2_HYPERVISOR=1
48+
49+
# No flash: boot/update addresses come from the HAL.
50+
WOLFBOOT_NO_PARTITIONS=1
51+
52+
# Must match ORIGIN in hal/imx95_a55.ld and IMX95_BL33_BASE in hal/imx95_a55.h.
53+
WOLFBOOT_ORIGIN=0x90200000
54+
55+
# RAM staging at 0xA1000000: clear of the M7/BL31/OP-TEE/ELE/vpu carveouts;
56+
# hal_init() asserts this via imx95_check_load_ranges().
57+
WOLFBOOT_LOAD_ADDRESS?=0xA1000000
58+
WOLFBOOT_LOAD_DTS_ADDRESS?=0xA0800000
59+
60+
# Bounds the image before authentication; required without fixed partitions.
61+
WOLFBOOT_RAMBOOT_MAX_SIZE=0x10000000
62+
63+
# Required for the test-app link even with WOLFBOOT_NO_PARTITIONS=1.
64+
WOLFBOOT_SECTOR_SIZE?=0x4000
65+
WOLFBOOT_PARTITION_SIZE?=0x4000000
66+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xA1000000
67+
68+
# Toolchain
69+
USE_GCC=1
70+
CROSS_COMPILE?=aarch64-none-elf-
71+
72+
# Storage: carrier SD on uSDHC2 (uSDHC driver in hal/imx95_a55.c; i.MX uSDHC, not SDHCI).
73+
# Boot containers stay on eMMC.
74+
DISK_SDCARD?=1
75+
# Cold start: with no U-Boot ahead of wolfBoot the uSDHC2 clock and pinmux are
76+
# still owned by the System Manager and must be requested over SCMI.
77+
IMX95_SCMI_COLD_INIT?=1
78+
# Power the Cortex-M7 mix and scrub its TCM, as U-Boot's board init does, for
79+
# boards that launch an M7 image from Linux.
80+
IMX95_INIT_M7?=1
81+
# A/B slots by 0-based index into the parsed partition table.
82+
CFLAGS_EXTRA+=-DBOOT_PART_A=1 -DBOOT_PART_B=2
83+
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x10000
84+
85+
# Linux FIT boot: kernel at 0xB2000000, ramdisk at 0xBA000000 - both above
86+
# the staging window so the copies cannot overlap the staged FIT.
87+
FIT_RAMDISK?=1
88+
WOLFBOOT_LOAD_RAMDISK_ADDRESS?=0xBA000000
89+
# OS cmdline plus serial console; ostree= pins the deployment. audit=0 because
90+
# the audit subsystem interleaves records with anything else on this console.
91+
CFLAGS_EXTRA+=-DLINUX_BOOTARGS='"earlycon console=ttyLP1,115200 audit=0 root=LABEL=otaroot rootfstype=ext4 logo.nologo ostree=/ostree/boot.1/torizon/d976a72bdc954405cfbe989bae393ad9da0b14b5dc0c1328c9b19e88201745a6/0"'
92+
93+
# --- Later phases (not yet implemented) -------------------------------------
94+
#ELF?=1
95+
#GZIP?=1

‎docs/Targets.md‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This README describes configuration of supported targets.
2323
* [Nordic nRF54L15](#nordic-nrf54l15)
2424
* [NXP i.MX 8QuadMax](#nxp-imx-8quadmax)
2525
* [NXP i.MX95 Cortex-M7](#nxp-imx95-cortex-m7)
26+
* [NXP i.MX95 Cortex-A55 (BL33)](#nxp-imx95-cortex-a55-bl33)
2627
* [NXP iMX-RT](#nxp-imx-rt)
2728
* [NXP i.MX RT700](#nxp-imx-rt700)
2829
* [NXP Kinetis](#nxp-kinetis)
@@ -9856,6 +9857,73 @@ The difference between the two timestamps is the cost of everything wolfBoot doe
98569857

98579858
Both caches are enabled by `hal_init()`, which matters because verifying an image means hashing megabytes resident in DDR. The ARMv7-M default memory map marks `0x80000000-0x9FFFFFFF` as Normal write-through, so no MPU region is needed and M7 stores to the shared window still reach DDR; the HAL nevertheless cleans the affected lines explicitly so that behaviour is not left depending on an inherited attribute.
98589859

9860+
## NXP i.MX95 Cortex-A55 (BL33)
9861+
9862+
wolfBoot replaces U-Boot proper on the i.MX95's Cortex-A55 cluster: it is the third image in AHAB container 2 (after BL31 and OP-TEE), entered by BL31 at `0x90200000` in NS-EL2, where it verifies a Linux FIT (kernel + DTB + initramfs) with ML-DSA-87 and boots it at EL2. NXP also documents an OEM PQC SRK hybrid (ML-DSA) AHAB flow, so the container half of the chain can be post-quantum as well.
9863+
9864+
Which component authenticates the containers depends on which slot wolfBoot occupies, and the two cases are not the same:
9865+
9866+
- **wolfBoot as BL33 only** (this section). U-Boot SPL is still in container 0 and still calls the ELE to authenticate container 2 before BL31 runs, so the chain is ROM -> ELE -> SPL -> BL31 -> wolfBoot -> Linux once SRK fuses are programmed.
9867+
- **wolfBoot as stage 1 as well** (next section). SPL is gone, so wolfBoot performs that ELE call itself. `IMX95_AHAB_AUTH` is what does it, and it is on by default; the chain becomes ROM -> ELE -> wolfBoot stage 1 -> BL31 -> wolfBoot BL33 -> Linux.
9868+
9869+
In both cases the ROM and the ELE authenticate container 0 before any A55 code runs, so whichever image sits in the SPL slot is itself verified.
9870+
9871+
Validated on a Toradex SMARC iMX95 with `TARGET=imx95_a55` (`config/examples/imx95-a55.config`): full boot to Linux userspace with the FIT on the carrier SD (uSDHC2, the uSDHC driver in `hal/imx95_a55.c` - i.MX uSDHC, not SDHCI-compatible).
9872+
9873+
Notes:
9874+
- The FIT DTB gets `/chosen` bootargs, initrd properties and a `/memory` node from `hal_dts_fixup()`; deployment DTBs commonly ship without `/memory` (the bootloader is expected to add it) and the kernel hangs silently without one.
9875+
- The EL2 exit is a fused asm routine (flush, DAIF mask, TLB invalidate, jump) that touches no memory after the D-cache goes off; set/way cleaning does not reach the A55 cluster's DSU system cache, so payload ranges are also cleaned by VA.
9876+
- Use plain `earlycon` (DTB-derived); an explicit `earlycon=lpuart32,mmio32,<addr>` uses the wrong register layout on i.MX and silences all console output.
9877+
- uSDHC2's clock, pinmux and card power are owned by the M33 System Manager, and its pad registers data-abort on direct access from BL33. `IMX95_SCMI_COLD_INIT=1` brings them up over SCMI (the SCMI client in `hal/imx95_a55.c`), which is what lets wolfBoot boot from SD on a cold power-on rather than only after a stage that already initialized the controller.
9878+
- `IMX95_INIT_M7=1` powers the Cortex-M7 mix and scrubs its TCM for ECC, matching what U-Boot's board init does, for boards that launch an M7 image from Linux later.
9879+
9880+
### Stage 1: replacing U-Boot SPL
9881+
9882+
The boot device holds a set of AHAB containers. The first one is what the boot ROM reads: it carries the ELE firmware, the M33 System Manager, the OEI that trains DDR, and one A55 image loaded into OCRAM at `0x20480000`. That last image is U-Boot SPL, and its whole job is to find the next container and load BL31, OP-TEE and BL33 out of it. wolfBoot can take that slot instead:
9883+
9884+
```
9885+
cp config/examples/imx95-a55.config .config
9886+
make # BL33, loaded into DRAM by BL31
9887+
make stage1 DISK_EMMC=1 # stage1/loader_stage1.bin, the SPL slot
9888+
```
9889+
9890+
DDR is up before stage 1 runs, because the OEI did it, so stage 1 only needs the boot device and the container walk. Nothing records where the next container starts: it is derived by taking the end of the first container - the furthest of its header, its images and its signature block - and rounding up to 1 KiB. `hal/imx95_ahab.c` is that walk, and `hal/imx95_a55_stage1.c` is the rest: the watchdog, GPIO and SMMU state a warm reset out of Linux leaves behind, the SCMI calls for the console clock and the A55 performance level, and the ELE call that starts its random generator.
9891+
9892+
Two things differ from the BL33 build. The console is programmed rather than inherited, since nothing has configured LPUART1 yet. And on eMMC the containers live in a boot partition, not the user area: `imx95_emmc_boot_partition()` reads back the same `PARTITION_CONFIG` field that told the ROM which one to load from, and reads follow it.
9893+
9894+
#### What stage 1 authenticates
9895+
9896+
Taking SPL's slot means taking over the step SPL performed. The boot ROM and the ELE authenticate container 0, so stage 1 is verified code, but the container it goes on to load BL31, OP-TEE and BL33 out of is a separate one that nothing has checked yet. `IMX95_AHAB_AUTH=1` (the default) makes stage 1 ask the ELE to check it, the same three calls U-Boot's SPL makes:
9897+
9898+
1. The container's header, image table and signature block are staged into DDR at `0x90000000` - NXP's own `IMG_CONTAINER_BASE` for this SoC - because the ELE reads the address it is given over its own master port and requires DDR. Every value stage 1 then acts on comes from those staged bytes; the medium is not consulted for the table again.
9899+
2. `ELE_OEM_CNTN_AUTH_REQ` authenticates the header.
9900+
3. Each image is loaded to its destination and then checked in place with `ELE_VERIFY_IMAGE_REQ`, one at a time so a failure names the image. `ELE_RELEASE_CONTAINER_REQ` follows, before the jump.
9901+
9902+
Any failure stops the boot. `IMX95_AHAB_AUTH=0` builds without it, for bring-up on a part whose containers are not signed; it cannot be combined with `IMX95_STAGE1_PASSTHROUGH` or `IMX95_STAGE1_ALLOW_SELF_OVERLAP`, both of which would carry on past a refusal, and the build fails if you try.
9903+
9904+
Separately, and regardless of that flag, stage 1 bounds every destination *before* writing any of them. An image is streamed straight from the boot device into the address the container names, so a check made afterwards would come too late to matter: by then the bytes have landed. Destinations must lie inside DDR, must not overlap the staging window, this loader, the M7 carveout, the ELE shared-memory region or the VPU boot area, must not overlap each other once rounded up to the block size, and image 0 must be an A55 executable whose entry point lies inside its own bytes.
9905+
9906+
Two limits are worth stating plainly:
9907+
9908+
- **On an open part AHAB reports success without enforcing a signature.** That is why an unsigned container boots at all. What authentication buys there is an ELE-checked hash of each image against a table nobody signed - integrity, not authenticity. Build with `IMX95_AHAB_LIFECYCLE=1` to have stage 1 print the lifecycle, so the difference is visible rather than implied; it is off by default because nothing else on this platform reads the fuse shadow block from the slot SPL occupies. Enforcement begins when the SRK hash is fused; see the i.MX8QuadMax AHAB section above for what that costs and why it is irreversible.
9909+
- **Authenticating the container does not prevent rollback.** The offset of the next container is derived by walking container 0, which stage 1 reads off the medium and nothing re-authenticates, so a different but validly signed older container set would authenticate happily. That needs `sw_version`/`fuse_version` policy or the AHAB monotonic counter, neither of which is implemented here.
9910+
9911+
#### Stage 1 build options
9912+
9913+
Stage 1 is built by `make -C stage1` and takes its own options, separately from the BL33 build. Pass them on the command line.
9914+
9915+
| Option | Default | Effect |
9916+
|---|---|---|
9917+
| `IMX95_AHAB_AUTH` | `1` | Ask the ELE to authenticate the container set stage 1 loads BL31, OP-TEE and BL33 from, as described above. Setting it to `0` builds without those calls, for bring-up on a part whose containers are not signed. |
9918+
| `IMX95_AHAB_LIFECYCLE` | `0` | Read and print the part's lifecycle from the fuse shadow block. Off by default: U-Boot reads that block only from U-Boot proper and only under `CONFIG_AHAB_BOOT`, so whether it answers the A55 this early is untested per part, and a diagnostic must not be able to cost a boot. |
9919+
| `IMX95_STAGE1_PASSTHROUGH` | unset | Bring-up only. Enter BL31 even when the container load failed, for a board where some other loader has already staged the whole set and stage 1 only needs to be invisible when it cannot help. Refused at compile time together with `IMX95_AHAB_AUTH`, because returning an error is then indistinguishable from the jump. |
9920+
| `IMX95_STAGE1_ALLOW_SELF_OVERLAP` | unset | Bring-up only. Skip an image whose destination lands on the running loader instead of refusing the boot, which a stage 1 linked into DRAM needs in order to skip its own entry. Refused at compile time together with `IMX95_AHAB_AUTH`. |
9921+
| `IMX95_LOG_RING` | `0` | Mirror the console into a DDR ring that survives the handoff, so stage 1's output can be read back from Linux with `memtool con`. Stage 1 starts the ring and BL33 appends to it, so one address holds both. |
9922+
| `IMX95_LOG_RING_BASE` | `0x80F20000` | Where that ring lives. Change it only to move the ring out of the way of something else; stage 1 and BL33 must agree on it. |
9923+
| `IMX95_EMMC_PROBE` | `0` | One-shot diagnostic that walks the eMMC boot partitions and reports the AHAB containers it finds, from an image booting off SD. |
9924+
9925+
The two bring-up options exist to get a new board talking; neither belongs in a shipped configuration, and the build refuses to combine either with authentication rather than letting a boot continue past a refusal.
9926+
98599927
## TI C2000 C28x (LAUNCHXL-F28P55X)
98609928

98619929
wolfBoot runs on the Texas Instruments C2000 C28x DSP (TMS320F28P550SJ, 150 MHz) as a secure execute-in-place (XIP) bootloader. The C28x is word-addressed with `CHAR_BIT == 16` (no 8-bit type -- each octet occupies one 16-bit cell), built with the TI `cl2000` toolchain against wolfSSL's wide-byte (`CHAR_BIT != 8`) support.

0 commit comments

Comments
 (0)