Add QorIQ SEC support to the T2080 and T1040 bare-metal test apps

pull/864/head
David Garske 2026-10-06 17:56:05 -07:00
parent 400bce6317
commit a98fba863f
7 changed files with 233 additions and 31 deletions

View File

@ -301,6 +301,24 @@ jobs:
config-file: ./config/examples/nxp-t2080.config
make-args: CFLAGS_EXTRA=-DBOARD_CW_VPX3152
# ELF=0 on both: the test app is a flat image linked at
# WOLFBOOT_LOAD_ADDRESS, and ELF=1 would sign test-app/image.elf instead,
# which elf_load then refuses because it is staged at its own link address.
nxp_t2080_sec_qoriq_test:
uses: ./.github/workflows/test-build-powerpc.yml
with:
arch: ppc
config-file: ./config/examples/nxp-t2080.config
# The board macro relocates CCSRBAR; the SEC base follows it.
make-args: SEC_QORIQ=1 CFLAGS_EXTRA=-DBOARD_CW_VPX3152 WOLFCRYPT_TEST=1 ELF=0
nxp_t1040_sec_qoriq_test:
uses: ./.github/workflows/test-build-powerpc.yml
with:
arch: ppc
config-file: ./config/examples/nxp-t1040.config
make-args: SEC_QORIQ=1 WOLFCRYPT_TEST=1 ELF=0
nxp_lpc54s0xx_test:
uses: ./.github/workflows/test-build.yml
with:

@ -1 +1 @@
Subproject commit 3c5eead44904df64e6a5a1f4ebdce377d35a849a
Subproject commit 57502e3ded5776ada0f3a15c4b0a6e0219007563

View File

@ -87,6 +87,15 @@ ifeq ($(TARGET),sim)
STACK_USAGE_LIMIT:=4608
endif
# SP_MATH_ALL with RSA-2048 puts ~18 KB frames in sp_int.c. The PowerPC test
# app runs from DDR with a 256 KB stack, so that is affordable here even
# though it would not be on a small target.
ifeq ($(ARCH),PPC)
ifneq ($(filter 1,$(WOLFCRYPT_TEST) $(WOLFCRYPT_BENCHMARK)),)
STACK_USAGE_LIMIT:=20480
endif
endif
ifeq ($(TARGET),ti_hercules)
APP_OBJS:=app_$(TARGET).o ../test-app/libwolfboot.o
CFLAGS+=-I"../include"
@ -216,6 +225,39 @@ ifeq ($(TARGET),max32666)
endif
endif
# NXP QorIQ SEC hardware crypto, selected through the crypto callback layer.
ifeq ($(SEC_QORIQ),1)
# The CCSR base has to be on the compile line, not a #define in the app: the
# sec_qoriq*.o driver objects are separate translation units and would
# otherwise fall through to the 0xFE000000 reset value in sec_qoriq.h while
# the app used the relocated one. Default it from the same board macro that
# selects the HAL's CCSRBAR so the two cannot disagree, and keep it
# overridable for a board whose SEC window sits elsewhere.
ifeq ($(SEC_QORIQ_CCSRBAR),)
ifneq ($(findstring BOARD_CW_VPX3152,$(CFLAGS_EXTRA)),)
SEC_QORIQ_CCSRBAR=0xEF000000UL
else
SEC_QORIQ_CCSRBAR=0xFE000000UL
endif
endif
CFLAGS+=-DWOLFSSL_SEC_QORIQ -DWOLFSSL_SEC_QORIQ_BAREMETAL
# The apps only bring the engine up under WOLFCRYPT_TEST/WOLFCRYPT_BENCHMARK,
# so SEC_QORIQ on its own links the driver without ever touching the device.
ifeq ($(WOLFCRYPT_TEST)$(WOLFCRYPT_BENCHMARK),)
$(warning SEC_QORIQ=1 has no effect without WOLFCRYPT_TEST or WOLFCRYPT_BENCHMARK)
endif
CFLAGS+=-DSEC_QORIQ_CCSRBAR=$(SEC_QORIQ_CCSRBAR)
WOLFCRYPT_SUPPORT=1
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_cb.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_hash.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_aes.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_rng.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_pkha.o
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_baremetal.o
endif
ifeq ($(WOLFCRYPT_TEST),1)
CFLAGS+=-DWOLFCRYPT_TEST
WOLFCRYPT_SUPPORT=1
@ -365,11 +407,21 @@ ifeq ($(WOLFCRYPT_SUPPORT),1)
# wolfcrypt C sources expect these asm symbols; provide the objects here.
ifeq ($(ARCH),RISCV64)
CFLAGS+=-DWOLFSSL_RISCV_ASM
APP_OBJS+= \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha256.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha512.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha3.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-aes.o
# Same pre/post-move layout probe as arch.mk, which is included above and
# has already set RISCV_ASM_DIR.
ifneq ($(wildcard $(RISCV_ASM_DIR)/riscv-64-sha256-asm.S),)
APP_OBJS+= \
$(RISCV_ASM_DIR)/riscv-64-sha256-asm.o \
$(RISCV_ASM_DIR)/riscv-64-sha512-asm.o \
$(RISCV_ASM_DIR)/riscv-64-sha3-asm.o \
$(RISCV_ASM_DIR)/riscv-64-aes-asm.o
else
APP_OBJS+= \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha256.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha512.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha3.o \
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-aes.o
endif
endif
endif

View File

@ -67,9 +67,13 @@ SECTIONS
/* Heap for _sbrk (used by syscalls.c malloc) */
_Min_Heap_Size = 0x10000; /* 64KB */
/* Stack: 64KB, grows downward from _stack_top.
* wolfCrypt ECC384 operations need deep stack (~11KB per frame). */
_Min_Stack_Size = 0x10000; /* 64KB */
/* Stack: 256KB, grows downward from _stack_top.
* wolfCrypt ECC384 operations need deep stack (~11KB per frame), and an
* RSA-enabled wolfcrypt_test build needs far more again: SP_INT_BITS
* rises to the RSA key size, which enlarges every mp_int the PBKDF and
* PKCS#12 paths put on the stack. The app runs from DDR, so the space
* costs nothing. */
_Min_Stack_Size = 0x40000; /* 256KB */
_stack_end = _end + _Min_Heap_Size;
_stack_top = _stack_end + _Min_Stack_Size;
}

View File

@ -27,6 +27,23 @@
#include "target.h"
#include "wolfboot/wolfboot.h"
/* wolfCrypt test/benchmark support */
#ifdef WOLFCRYPT_TEST
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfcrypt/test/test.h>
int wolfcrypt_test(void *args);
#endif
#ifdef WOLFCRYPT_BENCHMARK
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfcrypt/benchmark/benchmark.h>
int benchmark_test(void *args);
#endif
#ifdef WOLFSSL_SEC_QORIQ
#include <wolfssl/wolfcrypt/port/nxp/sec_qoriq.h>
#endif
/* wait_ticks: spin for r3 ticks using PPC timebase.
* Required by udelay() in nxp_ppc.c (linked via HAL). */
__asm__ (
@ -47,9 +64,8 @@ __asm__ (
" blr\n"
);
/* Assembly entry: set SP (_stack_top, PPC ABI: 16-byte aligned, back-chain 0),
* enable the FPU (MSR[FP]) -- the variadic printf ABI saves FP regs via stfd
* and would otherwise fault -- then branch to main. */
/* Entry: set SP (PPC ABI, 16-byte aligned, back-chain 0), enable MSR[FP] so
* the variadic printf ABI can save FP regs with stfd, then branch to main. */
__asm__ (
".section .text._app_entry\n"
".global _app_entry\n"
@ -152,14 +168,17 @@ static int print_info(void)
void main(void)
{
/* Zero BSS - required for bare-metal since there's no crt0 startup.
* Without this, static variables contain DDR garbage. */
extern char _start_bss[], _end_bss[];
{
char *p = _start_bss;
while (p < _end_bss)
*p++ = 0;
}
char *p;
#if (defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)) && \
defined(WOLFSSL_SEC_QORIQ)
SecQoriqDev* d;
int secRet;
#endif
/* No crt0 on bare metal, so statics start as DDR garbage. */
for (p = _start_bss; p < _end_bss; p++)
*p = 0;
uart_init();
@ -175,6 +194,61 @@ void main(void)
wolfBoot_success();
wolfBoot_printf("\r\nBoot partition marked successful\r\n");
#if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)
wolfCrypt_Init();
#ifdef WOLFSSL_SEC_QORIQ
secRet = wc_SecQoriqInit();
if (secRet == 0) {
wolfBoot_printf("QorIQ SEC: enabled, devId 0x%x\r\n",
(unsigned int)WOLFSSL_SEC_QORIQ_DEVID);
}
else {
wolfBoot_printf("QorIQ SEC: init failed (%d), software only\r\n",
secRet);
}
#endif
#ifdef WOLFCRYPT_TEST
wolfBoot_printf("\r\nRunning wolfCrypt tests...\r\n");
wolfcrypt_test(NULL);
wolfBoot_printf("Tests complete.\r\n\r\n");
#endif
#ifdef WOLFCRYPT_BENCHMARK
wolfBoot_printf("Running wolfCrypt benchmarks...\r\n");
benchmark_test(NULL);
wolfBoot_printf("Benchmarks complete.\r\n\r\n");
#endif
#ifdef WOLFSSL_SEC_QORIQ
/* Report what actually reached the engine: a passing test proves nothing
* about offload, since every unhandled case falls back to software. */
d = wc_SecQoriqGetDev();
if (d != NULL) {
wolfBoot_printf("SEC offload counters:\r\n");
wolfBoot_printf(" jobs submitted : %u\r\n",
(unsigned int)d->jobCount);
wolfBoot_printf(" hash seen %u offloaded %u\r\n",
(unsigned int)d->cbHashCount, (unsigned int)d->cbHashOffload);
wolfBoot_printf(" cipher seen %u offloaded %u\r\n",
(unsigned int)d->cbCipherCount, (unsigned int)d->cbCipherOffload);
wolfBoot_printf(" pk seen %u offloaded %u\r\n",
(unsigned int)d->cbPkCount, (unsigned int)d->cbPkOffload);
wolfBoot_printf(" seed seen %u\r\n",
(unsigned int)d->cbSeedCount);
}
#endif
#ifdef WOLFSSL_SEC_QORIQ
if (secRet == 0) {
wc_SecQoriqFree();
}
#endif
wolfCrypt_Cleanup();
#endif
#ifdef ENABLE_WOLFIP
wolfip_tftp_test_report();
#endif

View File

@ -68,6 +68,10 @@ int wolfcrypt_test(void *args);
int benchmark_test(void *args);
#endif
#ifdef WOLFSSL_SEC_QORIQ
#include <wolfssl/wolfcrypt/port/nxp/sec_qoriq.h>
#endif
static uint8_t boot_part_state = IMG_STATE_NEW;
static uint8_t update_part_state = IMG_STATE_NEW;
@ -143,14 +147,19 @@ static int print_info(void)
void main(void)
{
/* Zero BSS (no crt0 on bare metal): the wolfCrypt static-memory pools
* (gTestMemory/HEAP_HINT) must start zeroed or wc_LoadStaticMemory crashes. */
extern char _start_bss[], _end_bss[];
{
char *p = _start_bss;
while (p < _end_bss)
*p++ = 0;
}
char *p;
#if (defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)) && \
defined(WOLFSSL_SEC_QORIQ)
SecQoriqDev* d;
int secRet;
#endif
/* No crt0 on bare metal, and the wolfCrypt static-memory pools
* (gTestMemory/HEAP_HINT) must start zeroed or wc_LoadStaticMemory
* crashes. */
for (p = _start_bss; p < _end_bss; p++)
*p = 0;
uart_init();
@ -165,6 +174,21 @@ void main(void)
#if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)
wolfCrypt_Init();
#ifdef WOLFSSL_SEC_QORIQ
/* test.c and benchmark.c take their devId from WC_USE_DEVID, which
* wolfcrypt/settings.h maps to WOLFSSL_SEC_QORIQ_DEVID when the port
* is enabled. */
secRet = wc_SecQoriqInit();
if (secRet == 0) {
wolfBoot_printf("QorIQ SEC: enabled, devId 0x%x\r\n",
(unsigned int)WOLFSSL_SEC_QORIQ_DEVID);
}
else {
wolfBoot_printf("QorIQ SEC: init failed (%d), software only\r\n",
secRet);
}
#endif
#ifdef WOLFCRYPT_TEST
wolfBoot_printf("\r\nRunning wolfCrypt tests...\r\n");
wolfcrypt_test(NULL);
@ -177,6 +201,31 @@ void main(void)
wolfBoot_printf("Benchmarks complete.\r\n\r\n");
#endif
#ifdef WOLFSSL_SEC_QORIQ
/* Report what actually reached the engine: a passing test proves nothing
* about offload, since every unhandled case falls back to software. */
d = wc_SecQoriqGetDev();
if (d != NULL) {
wolfBoot_printf("SEC offload counters:\r\n");
wolfBoot_printf(" jobs submitted : %u\r\n",
(unsigned int)d->jobCount);
wolfBoot_printf(" hash seen %u offloaded %u\r\n",
(unsigned int)d->cbHashCount, (unsigned int)d->cbHashOffload);
wolfBoot_printf(" cipher seen %u offloaded %u\r\n",
(unsigned int)d->cbCipherCount, (unsigned int)d->cbCipherOffload);
wolfBoot_printf(" pk seen %u offloaded %u\r\n",
(unsigned int)d->cbPkCount, (unsigned int)d->cbPkOffload);
wolfBoot_printf(" seed seen %u\r\n",
(unsigned int)d->cbSeedCount);
}
#endif
#ifdef WOLFSSL_SEC_QORIQ
if (secRet == 0) {
wc_SecQoriqFree();
}
#endif
wolfCrypt_Cleanup();
#endif

View File

@ -105,8 +105,9 @@
{
(void)m7_get_ticks();
}
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024)
/* PPC time base register for accurate timing (e6500). */
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \
defined(TARGET_nxp_t1040)
/* PPC time base register for accurate timing (e6500/e5500). */
static uint32_t ppc_tb_hz = 0;
static unsigned long long ppc_start_ticks = 0;
@ -138,7 +139,9 @@
#endif
volatile uint32_t *rcwsr0 = (volatile uint32_t *)(ccsr + 0xE0100UL);
uint32_t plat_ratio = ((*rcwsr0) >> 25) & 0x1FU;
#if defined(BOARD_NAII_68PPC2) || defined(TARGET_nxp_t1024)
#if defined(BOARD_NAII_68PPC2) || defined(TARGET_nxp_t1024) || \
defined(TARGET_nxp_t1040)
/* T10xx boards run a 100 MHz SYSCLK; see SYS_CLK in hal/nxp_t10xx.c */
uint32_t sys_clk = 100000000; /* 100 MHz */
#else
uint32_t sys_clk = 66666667; /* 66.66 MHz */
@ -214,7 +217,8 @@ unsigned long my_time(unsigned long* timer)
if (timer) *timer = t;
return t;
}
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024)
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \
defined(TARGET_nxp_t1040)
if (ppc_tb_hz == 0)
ppc_tb_hz = ppc_get_timebase_hz();
{
@ -265,7 +269,8 @@ double current_time(int reset)
if (reset)
m7_start_ticks = m7_get_ticks();
return (double)(m7_get_ticks() - m7_start_ticks) / (double)IMX95_M7_HZ;
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024)
#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \
defined(TARGET_nxp_t1040)
if (ppc_tb_hz == 0)
ppc_tb_hz = ppc_get_timebase_hz();
if (reset)