Skip to content

Commit 282a924

Browse files
committed
Drive the Athena F5200 from the mpfs250 test-app
1 parent cedaf81 commit 282a924

11 files changed

Lines changed: 267 additions & 20 deletions

File tree

‎docs/PolarFire.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,31 @@ The AES offload is worth about 4.2x on the decrypt. **The hash offload is about
12401240

12411241
Athena also does not fit eNVM alongside the full feature set: with the manifest linked it needs both `GZIP` and `MPFS_SBI_SC_FLASH` dropped. Dropping `GZIP` costs nothing when the FIT's kernel is stored uncompressed.
12421242

1243+
The port also serves AES-ECB, which is how AES-XTS reaches the engine: wolfCrypt's XTS masks the whole buffer with the tweak chain and issues one bulk ECB call per XTS call (`HAVE_AES_ECB` required, distinct in/out buffers), while the tweak math stays in software. wolfBoot itself encrypts images with CTR and has no XTS use; the ECB path is for an application. Requests under `WC_MPFS_ATHENA_AES_MIN_SZ` (32 bytes) are declined to software, which keeps the XTS tweak and ciphertext-stealing blocks off the engine. Beyond what wolfBoot uses, the port offloads the rest of SHA-2, AES-CBC, AES-GCM, AES-CMAC and AES key wrap at every key size, the NRBG as a seed source, ECDSA, ECDH and EC key generation, and RSA. See `wolfcrypt/src/port/microchip/README.md` in wolfSSL.
1244+
1245+
#### Measuring the offload bare-metal
1246+
1247+
The test application doubles as a bare-metal wolfCrypt test and benchmark harness for the engine, in the same M-mode environment wolfBoot uses, so its figures compare with the software build of the same app and not with a Linux userspace benchmark:
1248+
1249+
```sh
1250+
cp config/examples/polarfire_mpfs250_m_qspi.config .config
1251+
make clean
1252+
make MPFS_ATHENA=1 MPFS_ATHENA_CAL_DIR=/path/to/hart-software-services/services/crypto \
1253+
WOLFCRYPT_BENCHMARK=1 WOLFBOOT_L2SCRATCH_SIZE=512k
1254+
```
1255+
1256+
Load `test-app/image_v1_signed.bin` with `mpfs_qspi_prog.py` as for any M-mode test app. The benchmark app is about 240 KB and is loaded at `0x0A020200`, so the bootloader's stack has to sit at the top of all four scratchpad ways rather than the default 256 KB, which is what `WOLFBOOT_L2SCRATCH_SIZE=512k` does; `test-app/RISCV64-mpfs250.ld` reserves 64 KB for the app's own stack above that, sized for the benchmark's SP math frames. The `WOLFCRYPT_TEST=1` app is about 370 KB and does not fit the scratchpad beside the bootloader: build it on `polarfire_mpfs250_m_qspi_ddr.config` with its `-DWOLFBOOT_MMODE_SMODE_BOOT` line removed, which loads the signed app into DDR and enters it with the M-mode direct jump, and with `NO_ASM=1`, since the test-app's RISC-V SHA assembly does not assemble against the test configuration. `MPFS_ATHENA=1` makes the app bring the engine up itself, so the bootloader it runs under may be built with or without the offload. With `MPFS_ATHENA=1` the test and benchmark build also turns on SHA-224, AES key wrap and CMAC, and seeds wolfCrypt's DRBG from the engine's NRBG, so every offload is exercised; RSA is covered when the configuration signs with RSA. The app registers the port, runs its known-answer self-test and prints `Athena: self-test passed, engine served N call(s)`, or the failing test followed by `Athena: halted`, in which case it stops there; the stock `wolfcrypt_test()` and `benchmark_test()` then drive the engine through `WC_USE_DEVID`, with the benchmark labelling offloaded results `HW`. The benchmark runs once per call size in `MPFS_BENCH_SIZES` (default 1 KiB, 512 B and 4 KiB; each needs twice that from `WOLFSSL_STATIC_MEMORY_TEST_SZ`), since one engine transfer per call amortises very differently at sector size and in bulk. The app ends with the total engine call count: a passing test or a plausible rate proves nothing about offload on its own, because every case the port declines runs in software. The same app built without `MPFS_ATHENA` is the software baseline. Object files are configuration-specific, so `make clean` between the two builds.
1257+
1258+
Measured on the Video Kit with the DDR configuration (E51 at 600 MHz), the software column being wolfCrypt's default C AES for RISC-V:
1259+
1260+
| Call size | AES-256-XTS software | AES-256-XTS Athena | AES-256-CTR Athena | SHA-384 software | SHA-384 Athena |
1261+
|---|---|---|---|---|---|
1262+
| 512 B | 48 KiB/s | 1.23 MiB/s | 12.9 MiB/s | 5.7 MiB/s | 11.4 MiB/s |
1263+
| 1 KiB | 49 KiB/s | 2.06 MiB/s | 14.6 MiB/s | 5.8 MiB/s | 13.2 MiB/s |
1264+
| 4 KiB | 49 KiB/s | 4.2 MiB/s | 16.1 MiB/s | 5.8 MiB/s | 14.8 MiB/s |
1265+
1266+
The app keeps the five MSS watchdogs refreshed from a machine timer interrupt every 5 s, since a test or benchmark pass runs far longer than their window, and its M-mode trap handler prints the cause and halts instead of resuming at the faulting instruction. The RISC-V harts trap on misaligned accesses, so `user_settings.h` defines `WOLFSSL_USE_ALIGN` for `ARCH_RISCV64`; the AES-GCM tests and benchmark also need the wolfSSL change that takes the byte-wise GCM table multiply under that define on 64-bit builds.
1267+
12431268
## Source files
12441269

12451270
`hal/mpfs250.c` - Hardware abstraction layer (UART, QSPI, SD/eMMC, multi-hart)

‎docs/Targets.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ Make variables, on the command line or in the `.config`. See [PolarFire.md](Pola
916916
| `MPFS_SD_EMMC_DEMUX_ADDR` | Fabric register that selects the SD slot or the eMMC on designs with the demux in the fabric (Icicle Kit: `0x4FFFFF00`); unset, the Video Kit's IOMUX override is used. |
917917
| `MPFS_SC_PROBE` | Read-only System Controller service survey at boot (device serial, TRNG nonce, PUF emulation): status and stability only, never a value. On by default for M-mode builds; `MPFS_SC_PROBE=0` disables it. |
918918
| `MPFS_DDR_MEMTEST` | `=1`: CPU pattern test over the DDR windows the design's SEG registers map, after training, reporting the error count per 64 MB chunk; independent of `DEBUG_DDR`. |
919-
| `MPFS_ATHENA` (+ `MPFS_ATHENA_CAL_DIR`) | SHA-384 and AES-256-CTR offload to the Athena F5200 (TeraFire), with a mandatory self-check. |
919+
| `MPFS_ATHENA` (+ `MPFS_ATHENA_CAL_DIR`) | SHA-384, AES-256-CTR and AES-256-ECB (AES-XTS) offload to the Athena F5200 (TeraFire), with a mandatory self-check. With `WOLFCRYPT_TEST=1` or `WOLFCRYPT_BENCHMARK=1` the test-app also drives the engine, across every algorithm the wolfSSL port offloads. |
920920
| `SNVM_KEYSTORE`, `SNVM_KEYSTORE_PROVISION`, `SNVM_KEYSTORE_REQUIRE_ROM` | Serve the verification keystore from secure NVM; the one-time writer; refuse to boot unless every keystore page is ROM-flagged. |
921921
| `SNVM_KEK`, `SNVM_ENCKEY_PROVISION` | PUF-derived KEK with RFC 3394 key-wrap for the sNVM-stored image-encryption key, and its one-time writer. |
922922
| `MPFS_SCB_SMODE_DENY` | Fence S-mode off the System Controller mailbox (PMP plus dtb node removal), so nothing after wolfBoot can reach the sNVM write service. |

‎hal/mpfs250.c‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@ extern uint8_t _main_hart_hls; /* linker-provided address symbol; typed as uint8
146146

147147
/* CLINT MSIP register for IPI delivery */
148148
#define CLINT_MSIP_REG(hart) (*(volatile uint32_t*)(CLINT_BASE + (hart) * 4))
149-
/* CLINT machine-timer comparator (per hart) and MTIME counter */
150-
#define CLINT_MTIMECMP_REG(hart) \
151-
(*(volatile uint64_t*)(CLINT_BASE + 0x4000UL + (hart) * 8UL))
152-
#define CLINT_MTIME_REG (*(volatile uint64_t*)(CLINT_BASE + 0xBFF8UL))
153149

154150
/* Signal secondary harts that E51 (main hart) is ready. */
155151
static void mpfs_signal_main_hart_started(void)
@@ -217,10 +213,10 @@ void secondary_hart_entry(unsigned long hartid, HLS_DATA* hls)
217213
}
218214
}
219215

220-
#if defined(MPFS_DDR_INIT) && defined(WOLFBOOT_MMODE_SMODE_BOOT)
216+
#ifdef WOLFBOOT_RISCV_MMODE
221217
/* Enable the CLINT MTIME counter via the SYSREG RTC clock divider. Without it
222218
* MTIME never advances and an S-mode OS has no scheduler tick. */
223-
static void mpfs_enable_mtime(void)
219+
void mpfs_enable_mtime(void)
224220
{
225221
volatile uint32_t *rtc_cr = (volatile uint32_t *)(SYSREG_BASE + 0x0CUL);
226222
uint32_t div;
@@ -233,7 +229,9 @@ static void mpfs_enable_mtime(void)
233229
*rtc_cr |= (1UL << 16); /* enable RTC/time-base clock */
234230
__asm__ volatile("fence iorw, iorw" ::: "memory");
235231
}
232+
#endif /* WOLFBOOT_RISCV_MMODE */
236233

234+
#if defined(MPFS_DDR_INIT) && defined(WOLFBOOT_MMODE_SMODE_BOOT)
237235
/* SBI HSM hart_start backend: stage the target hart's mailbox and ring its
238236
* MSIP; it enters S-mode at saddr with a0=hartid, a1=opaque. */
239237
int sbi_hal_hart_start(unsigned long hartid, unsigned long saddr,

‎hal/mpfs250.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,10 @@ int mpfs_nonce(uint8_t *nonce);
392392
#ifndef CLINT_BASE
393393
#define CLINT_BASE 0x02000000UL
394394
#endif
395+
/* Machine-timer comparator (per hart) and the MTIME counter. */
396+
#define CLINT_MTIMECMP_REG(hart) \
397+
(*(volatile uint64_t*)(CLINT_BASE + 0x4000UL + (hart) * 8UL))
398+
#define CLINT_MTIME_REG (*(volatile uint64_t*)(CLINT_BASE + 0xBFF8UL))
395399

396400
/* RTC Clock Frequency (1 MHz after divisor) */
397401
#define RTC_CLOCK_FREQ 1000000UL
@@ -476,6 +480,7 @@ void uart_write(const char* buf, unsigned int sz);
476480
#endif
477481
#ifdef WOLFBOOT_RISCV_MMODE
478482
void secondary_hart_entry(unsigned long hartid, HLS_DATA* hls);
483+
void mpfs_enable_mtime(void);
479484
#endif
480485
#endif /* __ASSEMBLER__ */
481486

‎include/user_settings.h‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,14 @@ extern int tolower(int c);
596596
# endif
597597
#endif
598598

599+
/* The RISC-V harts trap on a misaligned load or store with nothing to emulate
600+
* it bare-metal, so make wolfCrypt's ALIGN* attributes real: without this the
601+
* word-sized casts it makes on struct members (the AES-GCM table, for one)
602+
* fault. */
603+
#ifdef ARCH_RISCV64
604+
# define WOLFSSL_USE_ALIGN
605+
#endif
606+
599607
#if defined(EXT_ENCRYPTED)
600608
# define HAVE_PWDBASED
601609
#endif
@@ -745,6 +753,25 @@ extern int tolower(int c);
745753
#define WOLFSSL_SHA256
746754
#define WOLFSSL_SHA384
747755
#define WOLFSSL_SHA512
756+
#elif defined(TARGET_mpfs250) && defined(MPFS_ATHENA)
757+
/* wolfCrypt's DRBG seeded from the Athena NRBG, so the test also
758+
* covers the engine's entropy source, and every algorithm the
759+
* wolfSSL port offloads. */
760+
#define HAVE_HASHDRBG
761+
#define CUSTOM_RAND_GENERATE_SEED wc_MpfsAthena_GenerateSeed
762+
#ifndef __ASSEMBLER__
763+
extern int wc_MpfsAthena_GenerateSeed(unsigned char* output,
764+
unsigned int sz);
765+
#endif
766+
#define WOLFSSL_AES_COUNTER
767+
#define HAVE_AES_ECB
768+
#define WOLFSSL_AES_XTS
769+
#define WOLFSSL_AES_DIRECT
770+
#define HAVE_AES_KEYWRAP
771+
#define WOLFSSL_AES_KEYWRAP_PADDING
772+
#define WOLFSSL_CMAC
773+
#define WOLFSSL_SHA224
774+
#define WOLFSSL_SHA3
748775
#elif defined(TARGET_ti_am64x_r5)
749776
#ifndef WOLFSSL_TI_AM64X_R5
750777
#define WC_NO_RNG
@@ -764,7 +791,9 @@ extern int tolower(int c);
764791
#define WC_NO_HASHDRBG
765792
#define CUSTOM_RAND_GENERATE_SEED my_rng_seed_gen
766793
#define CUSTOM_RAND_GENERATE_BLOCK my_rng_seed_gen
794+
#ifndef __ASSEMBLER__
767795
extern int my_rng_seed_gen(unsigned char* output, unsigned int sz);
796+
#endif
768797

769798
/* Full test/benchmark algo set: AES ECB/CBC/CTR/GCM/XTS,
770799
* SHA-256/384/512, SHA-3. (AES-CBC/GCM added below; SHA-384/512
@@ -919,7 +948,17 @@ extern int tolower(int c);
919948
#define WOLFSSL_STATIC_MEMORY
920949
#endif
921950
#ifndef WOLFSSL_STATIC_MEMORY_TEST_SZ
922-
#define WOLFSSL_STATIC_MEMORY_TEST_SZ (10 * 1024)
951+
#if defined(TARGET_mpfs250) && defined(MPFS_DDR_INIT)
952+
/* Every default bucket, including the two above 4 KB that the
953+
* benchmark's 4 KB buffers and the test's larger contexts need;
954+
* a pool without them hands out something else. Only with DDR:
955+
* the L2 scratchpad app has no room for it. */
956+
#define WOLFSSL_STATIC_MEMORY_TEST_SZ (128 * 1024)
957+
#elif defined(TARGET_mpfs250)
958+
#define WOLFSSL_STATIC_MEMORY_TEST_SZ (64 * 1024)
959+
#else
960+
#define WOLFSSL_STATIC_MEMORY_TEST_SZ (10 * 1024)
961+
#endif
923962
#endif
924963
#define WOLFSSL_STATIC_MEMORY_LEAN
925964

@@ -929,7 +968,9 @@ extern int tolower(int c);
929968
/* User time functions provided */
930969
#define WOLFSSL_USER_CURRTIME
931970
#define XTIME my_time
971+
#ifndef __ASSEMBLER__
932972
extern unsigned long my_time(unsigned long* timer);
973+
#endif
933974
#endif
934975

935976
#if !defined(WOLFCRYPT_TEST) && !defined(WOLFCRYPT_BENCHMARK)
@@ -941,6 +982,26 @@ extern int tolower(int c);
941982
#undef NO_KDF
942983
#endif
943984

985+
#if (defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)) && \
986+
defined(TARGET_mpfs250) && defined(MPFS_ATHENA)
987+
#undef NO_CMAC
988+
#endif
989+
990+
/* The bootloader offloads only its image hash and cipher: keep the rest of the
991+
* wolfSSL Athena port out of the image, which has little room to spare. */
992+
#if defined(MPFS_ATHENA) && !defined(WOLFCRYPT_TEST) && \
993+
!defined(WOLFCRYPT_BENCHMARK)
994+
# define WC_MPFS_ATHENA_NO_SHA256
995+
# define WC_MPFS_ATHENA_NO_SHA512
996+
# define WC_MPFS_ATHENA_NO_CBC
997+
# define WC_MPFS_ATHENA_NO_GCM
998+
# define WC_MPFS_ATHENA_NO_KEYWRAP
999+
# define WC_MPFS_ATHENA_NO_CMAC
1000+
# define WC_MPFS_ATHENA_NO_RNG
1001+
# define WC_MPFS_ATHENA_NO_ECC
1002+
# define WC_MPFS_ATHENA_NO_RSA
1003+
#endif
1004+
9441005
#if defined(WOLFBOOT_TZ_FWTPM)
9451006
#undef NO_CMAC
9461007
#undef NO_KDF

‎test-app/Makefile‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,18 @@ ifeq ($(SEC_QORIQ),1)
268268
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_baremetal.o
269269
endif
270270

271+
# PolarFire SoC Athena F5200. options.mk already supplies the defines, the CAL
272+
# include path and the archive in LIBS; the port objects are added here because
273+
# the apps build their own wolfCrypt object list.
274+
ifeq ($(MPFS_ATHENA),1)
275+
ifeq ($(WOLFCRYPT_TEST)$(WOLFCRYPT_BENCHMARK),)
276+
$(warning MPFS_ATHENA=1 without WOLFCRYPT_TEST or WOLFCRYPT_BENCHMARK only runs the engine self-test in the test-app)
277+
endif
278+
WOLFCRYPT_SUPPORT=1
279+
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o
280+
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/microchip/mpfs_athena.o
281+
endif
282+
271283
ifeq ($(WOLFCRYPT_TEST),1)
272284
CFLAGS+=-DWOLFCRYPT_TEST
273285
WOLFCRYPT_SUPPORT=1
@@ -1530,6 +1542,13 @@ endif
15301542
ifeq ($(TARGET),mpfs250)
15311543
LSCRIPT_TEMPLATE:=RISCV64-mpfs250.ld
15321544
CFLAGS+=-DRAMFUNCTION='__attribute__((used,section(".ramcode")))'
1545+
# The wolfCrypt test and benchmark need far more stack than the plain app,
1546+
# which the L2 scratchpad configurations have no room to reserve.
1547+
ifneq ($(filter 1,$(WOLFCRYPT_TEST) $(WOLFCRYPT_BENCHMARK)),)
1548+
TEST_APP_STACK_SIZE?=0x00010000
1549+
else
1550+
TEST_APP_STACK_SIZE?=0x00002000
1551+
endif
15331552
endif
15341553

15351554
# $(CYPRESS_PDL)/devices/templates/COMPONENT_MTB/COMPONENT_CM0P/system_psoc6_cm0plus.o
@@ -2011,7 +2030,8 @@ endif
20112030
sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \
20122031
sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \
20132032
sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \
2014-
sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" \
2033+
sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \
2034+
sed -e "s/@TEST_APP_STACK_SIZE@/$(TEST_APP_STACK_SIZE)/g" \
20152035
> $(@)
20162036
$(Q)rm -f .app-size .entry-point .wolfboot-offset .partition-size .header-size
20172037

‎test-app/RISCV64-mpfs250.ld‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/* TODO: Update with actual memory map for MPFS250 */
55

66
_Min_Heap_Size = 0x00002000; /* required amount of heap */
7-
_Min_Stack_Size = 0x00002000; /* required amount of stack */
7+
_Min_Stack_Size = @TEST_APP_STACK_SIZE@; /* required amount of stack */
88

99
OUTPUT_ARCH( "riscv" )
1010

‎test-app/app_mpfs250.c‎

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,94 @@ int wolfcrypt_test(void *args);
4646
int benchmark_test(void *args);
4747
#endif
4848

49+
#ifdef WOLFCRYPT_BENCHMARK
50+
/* Buffer sizes the whole benchmark is run at, in turn: the Athena F5200 does
51+
* one engine transfer per call, so a sector-sized call and a bulk one amortise
52+
* the setup very differently, and the software build runs the same set as the
53+
* baseline. Each needs twice the size from the static pool
54+
* (WOLFSSL_STATIC_MEMORY_TEST_SZ). */
55+
#ifndef MPFS_BENCH_SIZES
56+
#define MPFS_BENCH_SIZES { 1024, 512, 4096 }
57+
#endif
58+
#endif /* WOLFCRYPT_BENCHMARK */
59+
60+
#ifdef MPFS_ATHENA
61+
#include <wolfssl/wolfcrypt/settings.h>
62+
#include <wolfssl/wolfcrypt/port/microchip/mpfs_athena.h>
63+
64+
/* Nothing after a failed bring-up or self-test can be trusted to the engine,
65+
* so stop here, as the bootloader's own self-check does. */
66+
static void mpfs_athena_app_halt(void)
67+
{
68+
wolfBoot_printf("Athena: halted\r\n");
69+
while (1) {
70+
/* halt */
71+
}
72+
}
73+
74+
static void mpfs_athena_app_init(void)
75+
{
76+
int ret;
77+
78+
/* The engine is brought up here, not by the bootloader: a wolfBoot built
79+
* without MPFS_ATHENA never touched it, and the port's own init handles
80+
* one that did. wolfcrypt_test and benchmark_test register the device
81+
* again, which the port accepts. */
82+
ret = wolfCrypt_Init();
83+
if (ret != 0) {
84+
wolfBoot_printf("Athena: wolfCrypt_Init failed (%d)\r\n", ret);
85+
mpfs_athena_app_halt();
86+
}
87+
ret = wc_MpfsAthena_RegisterDevice(WC_MPFS_ATHENA_DEVID);
88+
if (ret != 0) {
89+
wolfBoot_printf("Athena: RegisterDevice failed (%d)\r\n", ret);
90+
mpfs_athena_app_halt();
91+
}
92+
ret = wc_MpfsAthena_SelfTest();
93+
if (ret != 0) {
94+
wolfBoot_printf("Athena: self-test failed: %s (rc %d)\r\n",
95+
wc_MpfsAthena_SelfTestDesc(), ret);
96+
mpfs_athena_app_halt();
97+
}
98+
wolfBoot_printf("Athena: self-test passed, engine served %u call(s)\r\n",
99+
(unsigned int)wc_MpfsAthena_GetCbCount());
100+
}
101+
102+
#endif /* MPFS_ATHENA */
103+
104+
105+
#ifdef WOLFBOOT_RISCV_MMODE
106+
#include "../hal/riscv.h"
107+
/* MTIME is not running in an M-mode boot: start it, then let the machine
108+
* timer interrupt refresh the watchdogs every 5 s for as long as the app
109+
* runs. */
110+
#define MPFS_WDT_PET_TICKS (5ULL * RTC_CLOCK_FREQ)
111+
112+
/* The vector saved the caller's registers, so plain C: refresh the five MSS
113+
* watchdogs, which the bitstream arms and which reset the chip well inside a
114+
* test run, then rearm. */
115+
void isr_mtimer(void)
116+
{
117+
mpfs_wdt_pet_all();
118+
CLINT_MTIMECMP_REG(0) = CLINT_MTIME_REG + MPFS_WDT_PET_TICKS;
119+
}
120+
121+
static void mpfs_wdt_timer_start(void)
122+
{
123+
mpfs_enable_mtime();
124+
CLINT_MTIMECMP_REG(0) = CLINT_MTIME_REG + MPFS_WDT_PET_TICKS;
125+
csr_set(mie, MIE_MTIE);
126+
csr_set(mstatus, MSTATUS_MIE);
127+
#ifdef MPFS_DDR_INIT
128+
/* The bootloader raised the E51 to the Libero PLL rate; this copy of the
129+
* HAL's clock variable, which times the benchmark, still holds the reset
130+
* rate. Without DDR init the clock is never raised and that reset rate is
131+
* the right one. */
132+
mpfs_cpu_freq_mhz =
133+
(uint32_t)(LIBERO_SETTING_MSS_COREPLEX_CPU_CLK / 1000000UL);
134+
#endif
135+
}
136+
#endif
49137

50138
void main(void)
51139
{
@@ -61,6 +149,14 @@ void main(void)
61149
wolfBoot_printf("GPL v3\r\n");
62150
wolfBoot_printf("========================\r\n");
63151

152+
#ifdef WOLFBOOT_RISCV_MMODE
153+
mpfs_wdt_timer_start();
154+
#endif
155+
156+
#ifdef MPFS_ATHENA
157+
mpfs_athena_app_init();
158+
#endif
159+
64160
#ifdef WOLFCRYPT_TEST
65161
wolfBoot_printf("\r\nRunning wolfCrypt tests...\r\n");
66162
wolfCrypt_Init();
@@ -72,11 +168,30 @@ void main(void)
72168
#ifdef WOLFCRYPT_BENCHMARK
73169
wolfBoot_printf("Running wolfCrypt benchmarks...\r\n");
74170
wolfCrypt_Init();
75-
benchmark_test(NULL);
171+
{
172+
static const unsigned int sizes[] = MPFS_BENCH_SIZES;
173+
unsigned int i;
174+
/* benchmark_test() puts the block size back to its default on its
175+
* first run, so take that run's setup first and configure after. */
176+
benchmark_init();
177+
benchmark_free();
178+
for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++) {
179+
wolfBoot_printf("\r\n--- %u-byte calls ---\r\n", sizes[i]);
180+
benchmark_configure(sizes[i]);
181+
benchmark_test(NULL);
182+
}
183+
}
76184
wolfCrypt_Cleanup();
77185
wolfBoot_printf("Benchmarks complete.\r\n\r\n");
78186
#endif
79187

188+
#ifdef MPFS_ATHENA
189+
/* A passing test or a plausible figure proves nothing about offload on
190+
* its own: every case the port declines runs in software. */
191+
wolfBoot_printf("Athena: engine served %u call(s) in total\r\n",
192+
(unsigned int)wc_MpfsAthena_GetCbCount());
193+
#endif
194+
80195
while(1) {
81196
/* Main application loop */
82197
/* TODO: Add watchdog feed if needed */

0 commit comments

Comments
 (0)