Skip to content
14 changes: 12 additions & 2 deletions arch/arm64/core/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ void z_arm64_el3_init(void)
if (is_sve_implemented()) {
reg |= CPTR_EZ_BIT; /* Enable SVE access for lower ELs */
write_cptr_el3(reg);
barrier_isync_fence_full();

/* Initialize ZCR_EL3 for full SVE vector length */
/* ZCR_EL3.LEN = 0x1ff means full hardware vector length */
Expand Down Expand Up @@ -197,9 +198,17 @@ void z_arm64_el2_init(void)
#ifdef CONFIG_ARM64_SVE
/* Enable SVE for EL1 and EL0 if SVE is implemented */
if (is_sve_implemented()) {
reg &= ~CPTR_EL2_ZEN_MASK;
reg |= (CPTR_EL2_ZEN_EL1_EN | CPTR_EL2_ZEN_EL0_EN);
/*
* In non-VHE CPTR_EL2, SVE trapping is controlled by the TZ
* bit (bit 8) which was already cleared above. Bits [17:16]
* (ZEN) are RES0 in non-VHE mode and must not be set.
*
* Match the Linux kernel sequence (el2_setup.h): write
* CPTR_EL2 with TZ=0, ISB, then set ZCR_EL2 for full
* vector length.
*/
write_cptr_el2(reg);
barrier_isync_fence_full();

/* Initialize ZCR_EL2 for full SVE vector length */
/* ZCR_EL2.LEN = 0x1ff means full hardware vector length */
Expand Down Expand Up @@ -254,6 +263,7 @@ void z_arm64_el1_init(void)
if (is_sve_implemented()) {
reg |= CPACR_EL1_ZEN; /* Do not trap SVE initially */
write_cpacr_el1(reg);
barrier_isync_fence_full();

/* Initialize ZCR_EL1 SVE vector length */
write_zcr_el1(CONFIG_ARM64_SVE_VL_MAX/16 - 1);
Expand Down
9 changes: 9 additions & 0 deletions boards/arm/fvp_corstone1000/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0

if BOARD_FVP_CORSTONE1000

config BUILD_OUTPUT_BIN
default y

endif # BOARD_FVP_CORSTONE1000
6 changes: 6 additions & 0 deletions boards/arm/fvp_corstone1000/Kconfig.fvp_corstone1000
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0

config BOARD_FVP_CORSTONE1000
select SOC_A320 if BOARD_FVP_CORSTONE1000_A320
select SOC_A320 if BOARD_FVP_CORSTONE1000_A320_SMP
26 changes: 26 additions & 0 deletions boards/arm/fvp_corstone1000/Kconfig.sysbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0

if BOARD_FVP_CORSTONE1000

config CORSTONE1000_TFM_DEBUG
bool "Build TF-M in debug mode"
default y
help
Build TF-M with debug configuration.

config CORSTONE1000_TFM_LOG_LEVEL
int "TF-M log level (0=NONE, 1=ERROR, 2=WARNING, 3=INFO, 4=DEBUG)"
default 3
range 0 4
help
Set the log level for TF-M BL1 and MCUboot BL2.
DEBUG is very verbose and significantly slows boot.

config CORSTONE1000_TFA_DEBUG
bool "Build TF-A in debug mode"
default n
help
Build TF-A with debug configuration.

endif # BOARD_FVP_CORSTONE1000
123 changes: 123 additions & 0 deletions boards/arm/fvp_corstone1000/board.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright (c) 2026 BayLibre SAS
# SPDX-License-Identifier: Apache-2.0

set(SUPPORTED_EMU_PLATFORMS armfvp)
set(ARMFVP_BIN_NAME FVP_Corstone-1000-A320)

# Corstone-1000 handles firmware loading entirely in ARMFVP_FLAGS below.
# Skip the generic bp.secureflashloader / bp.flashloader0 / cluster0.cpu0
# arguments that armfvp.cmake would otherwise add for CONFIG_ARMV8_A_NS boards.
set(ARMFVP_SKIP_FW_ARGS TRUE)

# Find the FVP binary. Board-specific HINTS supplement the global ARMFVP_BIN_PATH.
find_program(ARMFVP
NAMES ${ARMFVP_BIN_NAME}
HINTS
${ARMFVP_BIN_PATH}
$ENV{ARMFVP_BIN_PATH}
)

# Set minimum FVP version for Corstone-1000-A320
set(ARMFVP_MIN_VERSION 11.27.31)
Comment on lines +12 to +21
Copy link
Contributor

Choose a reason for hiding this comment

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

The bottom variable seems unused, you might want to use https://github.com/zephyrproject-rtos/zephyr/blob/main/cmake/modules/python.cmake#L14 to find a minimum version

Copy link
Author

Choose a reason for hiding this comment

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

ARMFVP_MIN_VERSION is consumed by cmake/emu/armfvp.cmake — it queries the FVP binary version at configure time and warns if it is below the board-specified minimum. This is the existing mechanism used by other FVP boards (e.g. fvp_base_revc_2xaem).


# =============================================================================
# FVP Configuration
# =============================================================================

# With sysbuild, CMAKE_BINARY_DIR is the sub-build (e.g. build/hello_world).
# Firmware images are assembled in the parent build/firmware/ directory.
get_filename_component(_build_root "${CMAKE_BINARY_DIR}/.." ABSOLUTE)
set(_firmware_dir "${_build_root}/firmware")

# Allow environment overrides for pre-built firmware
if(DEFINED ENV{CORSTONE1000_BL1_FILE})
set(_bl1_file $ENV{CORSTONE1000_BL1_FILE})
else()
set(_bl1_file "${_firmware_dir}/bl1.bin")
endif()

if(DEFINED ENV{CORSTONE1000_FLASH_FILE})
set(_flash_file $ENV{CORSTONE1000_FLASH_FILE})
else()
set(_flash_file "${_firmware_dir}/cs1000.bin")
endif()

set(ARMFVP_FLAGS
# --- Firmware loading ---
-C se.trustedBootROMloader.fname=${_bl1_file}
--data board.flash0=${_flash_file}@0x68000000

# --- Terminal configuration ---
# mode=raw is required on all terminals, otherwise zero output appears
-C se.secenc_terminal.start_telnet=0
-C se.secenc_terminal.mode=raw
-C host.host_terminal_0.start_telnet=0
-C host.host_terminal_0.mode=raw
-C host.host_terminal_1.start_telnet=0
-C host.host_terminal_1.mode=raw

# --- UART output to console ---
-C se.uart0.out_file=-
-C se.uart0.unbuffered_output=1
-C host.uart0.out_file=-
-C host.uart0.unbuffered_output=1
-C host.uart0.uart_enable=1
-C host.uart1.out_file=-
-C host.uart1.unbuffered_output=1

# --- Hardware configuration ---
-C board.xnvm_size=64
-C se.trustedSRAM_config=6
-C se.BootROM_config=3
-C board.se_flash_size=8192
-C se.nvm.update_raw_image=0
-C se.cryptocell.USER_OTP_FILTERING_DISABLE=1
-C host.gic.ITS-count=0
-C board.smsc_91c111.enabled=0
-C disable_visualisation=true
)

# =============================================================================
# TF-A Configuration
# =============================================================================

if(CONFIG_BUILD_WITH_TFA)
# TF-A platform for Corstone-1000 with Cortex-A320
set(TFA_PLAT "corstone1000")

# Extra arguments for Cortex-A320 support
# Aligned with Yocto meta-arm CORSTONE1000-2025.12 reference build
set(TFA_EXTRA_ARGS
TARGET_PLATFORM=fvp
CORSTONE1000_CORTEX_A320=1
HW_ASSISTED_COHERENCY=1
USE_COHERENT_MEM=0
CTX_INCLUDE_AARCH32_REGS=0
NEED_BL32=no
ENABLE_PIE=1
RESET_TO_BL2=1
FVP_USE_GIC_DRIVER=FVP_GICV3
ENABLE_FEAT_HCX=1
ENABLE_FEAT_FGT=1
ENABLE_FEAT_ECV=1
ENABLE_FEAT_MTE2=1
ENABLE_FEAT_AMU=1
ENABLE_FEAT_CSV2_2=1
ENABLE_SVE_FOR_NS=1
ENABLE_SVE_FOR_SWD=1
ENABLE_STACK_PROTECTOR=strong
# Multi-core PSCI support for secondary CPU boot
ENABLE_MULTICORE=1
)

# Output paths depend on debug/release
if(CONFIG_TFA_MAKE_BUILD_TYPE_DEBUG)
set(TFA_OUTPUT_DIR ${TFA_BINARY_DIR}/corstone1000/debug)
else()
set(TFA_OUTPUT_DIR ${TFA_BINARY_DIR}/corstone1000/release)
endif()

# Note: Corstone-1000 TF-A doesn't build BL1 (Secure Enclave handles boot)
# The FIP contains BL2, BL31, and BL33 (Zephyr)
set(FVP_FIP_FILE ${TFA_OUTPUT_DIR}/fip.bin)
endif()
8 changes: 8 additions & 0 deletions boards/arm/fvp_corstone1000/board.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
board:
name: fvp_corstone1000
full_name: Arm Corstone-1000-A320 Fixed Virtual Platform
vendor: arm
socs:
- name: a320
variants:
- name: smp
Loading
Loading