Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion test/bench/bench_components_mlkem.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@

static int cmp_uint64_t(const void *a, const void *b)
{
return (int)((*((const uint64_t *)a)) - (*((const uint64_t *)b)));
const uint64_t va = *((const uint64_t *)a);
const uint64_t vb = *((const uint64_t *)b);

return (va > vb) - (va < vb);
Comment on lines -35 to +38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this change made? Some comment would be useful.

}

#define CHECK(x) \
Expand Down
11 changes: 7 additions & 4 deletions test/bench/bench_mlkem.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@

static int cmp_uint64_t(const void *a, const void *b)
{
return (int)((*((const uint64_t *)a)) - (*((const uint64_t *)b)));
const uint64_t va = *((const uint64_t *)a);
const uint64_t vb = *((const uint64_t *)b);

return (va > vb) - (va < vb);
}

static void print_median(const char *txt, uint64_t cyc[MLK_BENCHMARK_NTESTS])
Expand All @@ -54,7 +57,7 @@ static void print_percentile_legend(void)
printf("%21s", "percentile");
for (i = 0; i < sizeof(percentiles) / sizeof(percentiles[0]); i++)
{
printf("%9d", percentiles[i]);
printf("%12d", percentiles[i]);
}
printf("\n");
}
Expand All @@ -66,8 +69,8 @@ static void print_percentiles(const char *txt,
printf("%10s percentiles:", txt);
for (i = 0; i < sizeof(percentiles) / sizeof(percentiles[0]); i++)
{
printf("%9" PRIu64, (cyc)[MLK_BENCHMARK_NTESTS * percentiles[i] / 100] /
MLK_BENCHMARK_NITERATIONS);
printf("%12" PRIu64, (cyc)[MLK_BENCHMARK_NTESTS * percentiles[i] / 100] /
MLK_BENCHMARK_NITERATIONS);
}
printf("\n");
}
Expand Down
2 changes: 1 addition & 1 deletion test/hal/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

void enable_cyclecounter(void) {}
void disable_cyclecounter(void) {}
uint64_t get_cyclecounter(void) { return k_cycle_get_32(); }
uint64_t get_cyclecounter(void) { return k_cycle_get_64(); }

#elif defined(PMU_CYCLES)

Expand Down
8 changes: 8 additions & 0 deletions test/zephyr/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ target_include_directories(app PRIVATE
# emulator with the test's exit code; the NUCLEO-N657X0-Q hardware target needs
# its own shim plus libc wrappers that route stdio over ITM/SWO.
if(ZEPHYR_NUCLEO_N657X0_Q)
# The STM32N6 SystemInit() fallback derives VTOR from &g_pfnVectors. With
# Zephyr data in DTCM that symbol lives in RAM, so force VTOR to the ITCM
# vector table instead.
zephyr_compile_definitions(
USER_VECT_TAB_ADDRESS
VECT_TAB_BASE_ADDRESS=0x10000000
VECT_TAB_OFFSET=0x0
)
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/shim_nucleo_n657x0_q.c)
target_compile_definitions(app PRIVATE
printf=__wrap_printf
Expand Down
16 changes: 10 additions & 6 deletions test/zephyr/app/nucleo_n657x0_q.conf
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Copyright (c) The mlkem-native project authors
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT

# The board default exposes a 2 MiB SRAM window at 0x34000000; its first
# 400 KiB is FLEXRAM. The NUCLEO runner repurposes FLEXMEM to expand the TCMs
# to 256 KiB ITCM + 256 KiB DTCM, so keep the Zephyr image above that low
# window and leave fixed host buffers after the linked image.
CONFIG_SRAM_BASE_ADDRESS=0x34080000
CONFIG_SRAM_SIZE=192
# The NUCLEO runner repurposes FLEXMEM before loading the ELF, expanding the
# Cortex-M55 TCMs to 256 KiB ITCM + 256 KiB DTCM. Link the RAM-loaded Zephyr
# image as XIP from ITCM and keep runtime data/stacks in DTCM. The fixed
# bootargs handoff block remains in AXISRAM at 0x340b0000.
CONFIG_XIP=y
CONFIG_FLASH_BASE_ADDRESS=0x10000000
CONFIG_FLASH_SIZE=256
CONFIG_SRAM_BASE_ADDRESS=0x30000000
CONFIG_SRAM_SIZE=256
CONFIG_SOC_EARLY_RESET_HOOK=y

# The component benchmark app keeps five 8 KiB scratch buffers on the main
# stack; measured max static stack depth is about 49.5 KiB, so 32 KiB is not
Expand Down
15 changes: 14 additions & 1 deletion test/zephyr/app/nucleo_n657x0_q.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,26 @@
*/

/ {
mlk_itcm: memory@10000000 {
compatible = "zephyr,memory-region", "arm,itcm";
reg = <0x10000000 0x00040000>;
zephyr,memory-region = "ITCM";
};

mlk_dtcm: memory@30000000 {
compatible = "zephyr,memory-region", "arm,dtcm";
reg = <0x30000000 0x00040000>;
zephyr,memory-region = "DTCM";
};

mlk_axisram: memory@34080000 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still needed?

compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x34080000 0x00030000>;
zephyr,memory-region = "NUCLEO_AXISRAM";
};

chosen {
zephyr,sram = &mlk_axisram;
zephyr,flash = &mlk_itcm;
zephyr,sram = &mlk_dtcm;
};
};
22 changes: 22 additions & 0 deletions test/zephyr/app/shim_nucleo_n657x0_q.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@ static char nucleo_stdout_buf[8192];
static size_t nucleo_stdout_len;
static bool nucleo_swo_enabled;

/*
* Zephyr calls this before stack setup or normal RAM initialization. The
* NUCLEO runner has already expanded DTCM to 256 KiB, and the image now keeps
* runtime data/stacks there, so scrub the whole DTCM window before Zephyr's
* early stack, BSS, and MPU setup touch it.
*/
__attribute__((naked, used)) void soc_early_reset_hook(void)
{
__asm__ volatile(
"movs r2, #0\n"
"movs r3, #0\n"
"ldr r0, =0x30000000\n"
"ldr r1, =0x30040000\n"
"1:\n"
"strd r2, r3, [r0], #8\n"
"cmp r0, r1\n"
"blo 1b\n"
"dsb\n"
"isb\n"
"bx lr\n");
}

static void nucleo_swo_pin_setup(void)
{
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
Expand Down
21 changes: 9 additions & 12 deletions test/zephyr/nucleo_n657x0_q/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ Zephyr's default NUCLEO-N657X0-Q RAM region is a 2 MiB SRAM window starting at
`0x34000000`; its first 400 KiB is the STM32N657X0 FLEXRAM allocation. After
reset, the Cortex-M55 TCM layout is 64 KiB ITCM and 128 KiB DTCM. The NUCLEO
runner repurposes FLEXMEM to expand the TCMs to 256 KiB ITCM and 256 KiB DTCM
before each RAM-loaded Zephyr test, so the test image is linked above that low
AXISRAM/FLEXRAM window instead of using the board default:
before each RAM-loaded Zephyr test. The test image is then linked as XIP from
ITCM at `0x10000000`, with runtime data and stacks in DTCM at `0x30000000`;
the fixed bootargs handoff block remains in AXISRAM at `0x340b0000`.

1. OpenOCD attaches with `reset_config none`.
2. The script enables the SYSCFG clock by setting bit 0 in `RCC_APB4ENSR2` at
Expand All @@ -95,16 +96,12 @@ AXISRAM/FLEXRAM window instead of using the board default:
6. It runs `reset run` so the expanded layout is applied before the Zephyr ELF
is loaded.

The board is RAM-loaded, not flashed. Zephyr's default NUCLEO-N657X0-Q RAM
region is a 2 MiB SRAM window starting at `0x34000000`; its first 400 KiB is
the STM32N657X0 FLEXRAM allocation. The hardware benchmark setup is the reason
this target uses a board-specific memory layout: before each run, the hardware
wrapper repurposes FLEXMEM to expand the Cortex-M55 TCMs by setting the low
byte of `SYSCFG_CM55TCMCR` to `0x99`, selecting 256 KiB ITCM and 256 KiB DTCM,
then resets the target so that layout is active. Because this changes the low
AXISRAM/FLEXRAM window that the default Zephyr layout would use, the test image
is instead linked in a 192 KiB AXISRAM window at `0x34080000`; see
`nucleo_n657x0_q/README.md` for the exact register sequence.
The board is RAM-loaded, not flashed. The hardware benchmark setup is the
reason this target uses a board-specific memory layout: before each run, the
hardware wrapper repurposes FLEXMEM to expand the Cortex-M55 TCMs by setting
the low byte of `SYSCFG_CM55TCMCR` to `0x99`, selecting 256 KiB ITCM and
256 KiB DTCM, then resets the target so that layout is active. The Zephyr image
is linked as XIP from ITCM, while runtime data and stacks are placed in DTCM.

Test stdout is captured over ITM stimulus port 0 through SWO. This avoids using
semihosting for normal output: semihosting is blocking and each host operation
Expand Down
14 changes: 12 additions & 2 deletions test/zephyr/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ ZEPHYR_APP := $(PLATFORM_PATH)/app
ZEPHYR_BUILD_DIR := $(BUILD_DIR)/zephyr/$(ZEPHYR_TARGET)
ZEPHYR_ACTIVE_TARGET := $(BUILD_DIR)/zephyr/.active-target
ZEPHYR_APP_INPUTS := \
$(PLATFORM_PATH)/platform.mk \
$(ZEPHYR_APP)/CMakeLists.txt \
$(ZEPHYR_APP)/Kconfig \
$(ZEPHYR_APP)/prj.conf \
Expand Down Expand Up @@ -111,12 +112,20 @@ CFLAGS += -DNTESTS_FUNC=3 -DNTESTS_KAT=100 \
# adds must not reach the Zephyr toolchain, which selects the target arch itself.
ZEPHYR_TEST_CFLAGS = $(subst \",\\\",$(patsubst -Imlkem,-I$(abspath mlkem),$(CFLAGS)))
# Keep make-exported project flags out of Zephyr's own CMake build; the app
# sources get those flags explicitly via ZEPHYR_TEST_CFLAGS.
# sources get those flags explicitly via ZEPHYR_TEST_CFLAGS. Also overwrite
# cached CMake global flags, so a prior polluted build directory cannot keep
# applying project warning flags to Zephyr's generated/helper targets.
ZEPHYR_CMAKE_ENV := env -u CFLAGS -u CXXFLAGS -u CPPFLAGS -u LDFLAGS
ZEPHYR_CMAKE_CLEAR_FLAGS := \
-DCMAKE_ASM_FLAGS:STRING= \
-DCMAKE_C_FLAGS:STRING= \
-DCMAKE_CXX_FLAGS:STRING= \
-DCMAKE_EXE_LINKER_FLAGS:STRING=

CUSTOM_BUILD = \
echo " ZEPHYR $(ZEPHYR_TARGET): $(notdir $@)" && \
$(ZEPHYR_CMAKE_ENV) cmake -GNinja -S $(ZEPHYR_APP) -B $(ZEPHYR_OUT) \
$(ZEPHYR_CMAKE_CLEAR_FLAGS) \
-DBOARD=$(ZEPHYR_BOARD) \
-DZEPHYR_NATIVE_ROOT=$(CURDIR) \
-DZEPHYR_TEST_SRCS="$(strip $(TEST_SRCS))" \
Expand All @@ -126,7 +135,8 @@ CUSTOM_BUILD = \
$(ZEPHYR_TARGET_CMAKE_ARGS) \
-DUSER_CACHE_DIR=$(abspath $(ZEPHYR_OUT)/.cache) \
>/dev/null && \
$(ZEPHYR_CMAKE_ENV) cmake --build $(ZEPHYR_OUT) >/dev/null && \
$(ZEPHYR_CMAKE_ENV) cmake --build $(ZEPHYR_OUT) >$(ZEPHYR_OUT)/build.log 2>&1 || \
{ cat $(ZEPHYR_OUT)/build.log; exit 1; }; \
cp $(ZEPHYR_OUT)/zephyr/zephyr.elf $@

# A custom build links the test sources directly rather than from objects, so
Expand Down
Loading