diff --git a/CORTEX_M85_MPU_PXN_PACBTI_FVP_ARMCLANG_IAR/main.c b/CORTEX_M85_MPU_PXN_PACBTI_FVP_ARMCLANG_IAR/main.c index 2329c57..0303480 100644 --- a/CORTEX_M85_MPU_PXN_PACBTI_FVP_ARMCLANG_IAR/main.c +++ b/CORTEX_M85_MPU_PXN_PACBTI_FVP_ARMCLANG_IAR/main.c @@ -5,6 +5,7 @@ #include #include +#include /* Kernel includes. */ #include "FreeRTOS.h" @@ -511,3 +512,20 @@ void MemManage_Handler( void ) " bx r2 \n" ); } + +#if( configENABLE_PAC == 1 ) + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < 4; i++ ) + { + pulTaskPacKey[i] = rand(); + } + } +#endif /* configENABLE_PAC == 1 */ diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c index 3dcae60..77ab2ce 100644 --- a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c @@ -5,6 +5,7 @@ #include #include +#include /* Kernel includes. */ #include "FreeRTOS.h" @@ -323,3 +324,20 @@ void UsageFault_Handler( void ) " bx r2 \n" ); } + +#if( configENABLE_PAC == 1 ) + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < 4; i++ ) + { + pulTaskPacKey[i] = rand(); + } + } +#endif /* configENABLE_PAC == 1 */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/CMakeLists.txt b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/CMakeLists.txt new file mode 100644 index 0000000..399aa68 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set(arm_corstone_platform_bsp_SOURCE_DIR + ${CMAKE_CURRENT_LIST_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp + CACHE INTERNAL + "Path to Arm Corstone-3xx Platform CMSIS-Driver Based Board Support Package source code" +) + +set(ARM_CORSTONE_BSP_TARGET_PLATFORM "corstone315" CACHE STRING "") + +add_subdirectory(${arm_corstone_platform_bsp_SOURCE_DIR} build) + +if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=standard + ) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=bti+pac-ret+leaf + ) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=pac-ret + ) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=pac-ret+leaf + ) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_BTI") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=bti + ) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=none + ) +else() + message(FATAL_ERROR "Invalid FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option chosen, the supported configurations are + ARM_V_8_1_M_PACBTI_CONFIG_STANDARD, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF, + ARM_V_8_1_M_PACBTI_CONFIG_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_NONE" + ) +endif() + +target_compile_definitions(arm-corstone-platform-bsp + INTERFACE + __DOMAIN_NS=1 +) + +set(S_IMAGE_LOAD_ADDRESS 0x11000000 CACHE STRING "Secure firmware loading address") +set(NS_IMAGE_LOAD_ADDRESS 0x01020000 CACHE STRING "Non-secure user application loading address") + +target_include_directories(arm-corstone-platform-bsp + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/corstone315/include +) diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.c b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.c new file mode 100644 index 0000000..4d3906b --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.c @@ -0,0 +1,56 @@ +/* Copyright 2017-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "device_cfg.h" +#include "Driver_USART.h" +#include "bsp_serial.h" + +extern ARM_DRIVER_USART Driver_USART0; + +void bsp_serial_init( void ) +{ + Driver_USART0.Initialize( NULL ); + + Driver_USART0.PowerControl( ARM_POWER_FULL ); + + Driver_USART0.Control( ARM_USART_MODE_ASYNCHRONOUS, DEFAULT_UART_BAUDRATE ); + + Driver_USART0.Control( ARM_USART_CONTROL_TX, 1 ); + + Driver_USART0.Control( ARM_USART_CONTROL_RX, 1 ); +} + +#if defined( __ARMCOMPILER_VERSION ) + + int stdio_output_string(const unsigned char *str, uint32_t len) + { + int32_t ret; + + /* Add a busy wait before sending. */ + while (Driver_USART0.GetStatus().tx_busy); + ret = Driver_USART0.Send(str, len); + if (ret != ARM_DRIVER_OK) { + return 0; + } + /* Add a busy wait after sending. */ + while (Driver_USART0.GetStatus().tx_busy); + + return Driver_USART0.GetTxCount(); + } + + int fputc(int ch, FILE *f) + { + (void)f; + + /* Send byte to USART */ + (void)stdio_output_string((const unsigned char *)&ch, 1); + + /* Return character written */ + return ch; + } + +#endif /* if defined( __ARMCOMPILER_VERSION ) */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.h new file mode 100644 index 0000000..229b6ff --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/common/bsp_serial.h @@ -0,0 +1,17 @@ +/* Copyright 2017-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + + +#include + +/** + * \brief Initializes default UART device + */ +void bsp_serial_init( void ); + +#endif /* __SERIAL_H__ */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/RTE_Components.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/RTE_Components.h new file mode 100644 index 0000000..a21add0 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/RTE_Components.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019-2024, Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- */ + +#ifndef __RTE_COMPONENTS_H +#define __RTE_COMPONENTS_H + +/* USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] */ +/* Configuration settings for Driver_USART0 in component ::Drivers:USART */ +#define RTE_USART0 1 +#define RTE_SRAM_MPC 1 +#define RTE_ISRAM0_MPC 1 +#define RTE_PERIPH_EXP2_PPC_CORSTONE315 1 +#endif /* __RTE_COMPONENTS_H */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/device_cfg.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/device_cfg.h new file mode 100644 index 0000000..506300c --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMSIS/corstone315/include/device_cfg.h @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2020-2024 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +#include "RTE_Components.h" + +/** + * \file device_cfg.h + * \brief Configuration file native driver re-targeting + * + * \details This file can be used to add native driver specific macro + * definitions to select which peripherals are available in the build. + * + * This is a default device configuration file with all peripherals enabled. + */ + +/* Secure only peripheral configuration */ + +/* ARM MPS3 IO SCC */ +#ifdef RTE_MPS3_IO + #define MPS3_IO_S + #define MPS3_IO_DEV MPS3_IO_DEV_S +#endif + +/* I2C_SBCon */ +#ifdef RTE_I2C0 + #define I2C0_SBCON_S + #define I2C0_SBCON_DEV I2C0_SBCON_DEV_S +#endif +#ifdef RTE_I2C1 + #define I2C1_SBCON_S + #define I2C1_SBCON_DEV I2C1_SBCON_DEV_S +#endif +#ifdef RTE_I2C2 + #define I2C2_SBCON_S + #define I2C2_SBCON_DEV I2C2_SBCON_DEV_S +#endif + +/* I2S */ +#ifdef RTE_I2S + #define MPS3_I2S_S + #define MPS3_I2S_DEV MPS3_I2S_DEV_S +#endif + +/* ARM UART Controller CMSDK */ +#ifdef RTE_USART0 + #define UART0_CMSDK_NS + #define UART0_CMSDK_DEV UART0_CMSDK_DEV_NS +#endif +#ifdef RTE_USART1 + #define UART1_CMSDK_S + #define UART1_CMSDK_DEV UART1_CMSDK_DEV_S +#endif +#ifdef RTE_USART2 + #define UART2_CMSDK_S + #define UART2_CMSDK_DEV UART2_CMSDK_DEV_S +#endif +#ifdef RTE_USART3 + #define UART3_CMSDK_S + #define UART3_CMSDK_DEV UART3_CMSDK_DEV_S +#endif +#ifdef RTE_USART4 + #define UART4_CMSDK_S + #define UART4_CMSDK_DEV UART4_CMSDK_DEV_S +#endif +#ifdef RTE_USART5 + #define UART5_CMSDK_S + #define UART5_CMSDK_DEV UART5_CMSDK_DEV_S +#endif + +#define DEFAULT_UART_BAUDRATE 115200U + +/* To be used as CODE and DATA sram */ +#ifdef RTE_ISRAM0_MPC + #define MPC_ISRAM0_S + #define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S +#endif + +#ifdef RTE_ISRAM1_MPC + #define MPC_ISRAM1_S + #define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S +#endif + +#ifdef RTE_SRAM_MPC + #define MPC_SRAM_S + #define MPC_SRAM_DEV MPC_SRAM_DEV_S +#endif + +#ifdef RTE_QSPI_MPC + #define MPC_QSPI_S + #define MPC_QSPI_DEV MPC_QSPI_DEV_S +#endif + +/** System Counter Armv8-M */ +#ifdef RTE_SYSCOUNTER + #define SYSCOUNTER_CNTRL_ARMV8_M_S + #define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + + #define SYSCOUNTER_READ_ARMV8_M_S + #define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S + +/** + * Arbitrary scaling values for test purposes + */ + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u +#endif /* ifdef RTE_SYSCOUNTER */ + +/* System timer */ +#ifdef RTE_TIMEOUT + #define SYSTIMER0_ARMV8_M_S + #define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S + #define SYSTIMER1_ARMV8_M_S + #define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S + #define SYSTIMER2_ARMV8_M_S + #define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S + #define SYSTIMER3_ARMV8_M_S + #define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S + + #define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) +#endif /* ifdef RTE_TIMEOUT */ + +/* CMSDK GPIO driver structures */ +#ifdef RTE_GPIO + #define GPIO0_CMSDK_S + #define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S + #define GPIO1_CMSDK_S + #define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S + #define GPIO2_CMSDK_S + #define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S + #define GPIO3_CMSDK_S + #define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S +#endif + +/* System Watchdogs */ +#ifdef RTE_WATCHDOG + #define SYSWDOG_ARMV8_M_S + #define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S +#endif + +/* ARM MPC SIE 315 driver structures */ +#ifdef RTE_VM0_MPC + #define MPC_VM0_S + #define MPC_VM0_DEV MPC_VM0_DEV_S +#endif +#ifdef RTE_VM1_MPC + #define MPC_VM1_S + #define MPC_VM1_DEV MPC_VM1_DEV_S +#endif +#ifdef RTE_SSRAM2_MPC + #define MPC_SSRAM2_S + #define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#endif +#ifdef RTE_SSRAM3_MPC + #define MPC_SSRAM3_S + #define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S +#endif + +/* ARM PPC driver structures */ +#ifdef RTE_MAIN0_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN0_S + #define PPC_CORSTONE315_MAIN0_DEV PPC_CORSTONE315_MAIN0_DEV_S +#endif +#ifdef RTE_MAIN_EXP0_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP0_S + #define PPC_CORSTONE315_MAIN_EXP0_DEV PPC_CORSTONE315_MAIN_EXP0_DEV_S +#endif +#ifdef RTE_MAIN_EXP1_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP1_S + #define PPC_CORSTONE315_MAIN_EXP1_DEV PPC_CORSTONE315_MAIN_EXP1_DEV_S +#endif +#ifdef RTE_MAIN_EXP2_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP2_S + #define PPC_CORSTONE315_MAIN_EXP2_DEV PPC_CORSTONE315_MAIN_EXP2_DEV_S +#endif +#ifdef RTE_MAIN_EXP3_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP3_S + #define PPC_CORSTONE315_MAIN_EXP3_DEV PPC_CORSTONE315_MAIN_EXP3_DEV_S +#endif +#ifdef RTE_PERIPH0_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH0_S + #define PPC_CORSTONE315_PERIPH0_DEV PPC_CORSTONE315_PERIPH0_DEV_S +#endif +#ifdef RTE_PERIPH1_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH1_S + #define PPC_CORSTONE315_PERIPH1_DEV PPC_CORSTONE315_PERIPH1_DEV_S +#endif +#ifdef RTE_PERIPH_EXP0_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP0_S + #define PPC_CORSTONE315_PERIPH_EXP0_DEV PPC_CORSTONE315_PERIPH_EXP0_DEV_S +#endif +#ifdef RTE_PERIPH_EXP1_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP1_S + #define PPC_CORSTONE315_PERIPH_EXP1_DEV PPC_CORSTONE315_PERIPH_EXP1_DEV_S +#endif +#ifdef RTE_PERIPH_EXP2_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP2_S + #define PPC_CORSTONE315_PERIPH_EXP2_DEV PPC_CORSTONE315_PERIPH_EXP2_DEV_S +#endif +#ifdef RTE_PERIPH_EXP3_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP3_S + #define PPC_CORSTONE315_PERIPH_EXP3_DEV PPC_CORSTONE315_PERIPH_EXP3_DEV_S +#endif + +/* DMA350 */ +#ifdef RTE_DMA350 + #define DMA350_DMA0_S + #define DMA350_DMA0_DEV DMA350_DMA0_DEV_S + + #define DMA350_CH0_S + #define DMA350_DMA0_CH0_S + #define DMA350_CH1_S + #define DMA350_DMA0_CH1_S +#endif + +/* Key Management Unit */ +#ifdef RTE_KMU + #define KMU_S + #define KMU_DEV KMU_DEV_S +#endif + +/* Lifecycle Manager */ +#ifdef RTE_LCM + #define LCM_S + #define LCM_DEV LCM_DEV_S +#endif + +/* Security Alarm Manager */ +#ifdef RTE_SAM + #define SAM_S + #define SAM_DEV SAM_DEV_S +#endif + +/* HDLCD Video */ +#ifdef RTE_HDLCD + #define HDLCD_NS + #define HDLCD_DEV HDLCD_DEV_NS +#endif + +/* ARM SPI PL022 */ +/* Invalid device stubs are not defined */ +#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */ +#ifdef RTE_SPI0 + #define SPI0_PL022_S + #define SPI0_PL022_DEV SPI0_PL022_DEV_S +#endif +#ifdef RTE_SPI1 + #define SPI1_PL022_S + #define SPI1_PL022_DEV SPI1_PL022_DEV_S +#endif +#ifdef RTE_SPI2 + #define SPI2_PL022_S + #define SPI2_PL022_DEV SPI2_PL022_DEV_S +#endif + +#define DEFAULT_UART_BAUDRATE 115200U +#define DEFAULT_UART_CONTROL 0 + +#endif /* __DEVICE_CFG_H__ */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMakeLists.txt b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMakeLists.txt new file mode 100644 index 0000000..b8dd234 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/CMakeLists.txt @@ -0,0 +1,87 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.15) + +project( + dedicated-pac-key-example + VERSION 0.1 + LANGUAGES C ASM) + +set (CMAKE_BUILD_TYPE Release) + +set(CMAKE_EXECUTABLE_SUFFIX ".axf") + +add_executable(cortex_m85_task_dedicated_pac_key_fvp_example) + +set(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG "ARM_V_8_1_M_PACBTI_CONFIG_PACRET" CACHE STRING "" FORCE) + +# Select the native compile PORT +set(FREERTOS_PORT "GCC_ARM_CM85_NONSECURE" CACHE STRING "" FORCE) + +set(FREERTOS_HEAP "4" CACHE STRING "" FORCE) + +add_library(freertos_config INTERFACE) + +target_include_directories(freertos_config + INTERFACE + config +) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../../../Source freertos_kernel) + +target_sources(cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/../Demos_Dependencies/arm_corstone_platform_bsp/corstone315/Device/Source/startup_SSE315.c +) + +target_link_options(cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + --scatter=${CMAKE_CURRENT_SOURCE_DIR}/armclang.sct + --entry=Reset_Handler + --map +) + +# BSP serial library + +add_library(cmsis_bsp STATIC) + +target_sources(cmsis_bsp + PUBLIC + CMSIS/common/bsp_serial.c +) + +target_include_directories(cmsis_bsp + PUBLIC + CMSIS/common +) + +target_link_libraries(cmsis_bsp + PUBLIC + arm-corstone-platform-bsp +) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/secure) + +add_dependencies( + cortex_m85_task_dedicated_pac_key_fvp_example + secure_cortex_m85_task_dedicated_pac_key_fvp_example +) + +target_link_libraries(cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + freertos_kernel + freertos_config + cmsis_bsp + ${CMAKE_BINARY_DIR}/veneers.o +) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) +include(ConvertElfToBin) +include(MergeImages) + +target_axf_to_bin(cortex_m85_task_dedicated_pac_key_fvp_example flash_ns) + +merge_images(cortex_m85_task_dedicated_pac_key_fvp_example) diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/README.md b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/README.md new file mode 100644 index 0000000..aae9f75 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/README.md @@ -0,0 +1,188 @@ +# Task Dedicated PAC Key example on Armv8.1-M Cortex-M85 Fixed Virtual Platform + +# Introduction + +The Armv8.1-M architecture extension introduced **Pointer Authentication** to harden the security against Return-Oriented Programming (ROP) security exploit attacks. In return-oriented programming, instructions before a function return are used build gadgets in the executable code region. Please refer to the [document](https://developer.arm.com/documentation/102433/0200/Stack-smashing-and-execution-permissions) to find out more about stack smashing and return-oriented programming. The [blog](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension) talks in depth about Armv8.1-M Pointer Authentication Code. + +To harden the security, each task is assigned with a dedicated PAC key, so that attackers needs to get the all the PAC keys right to exploit the system using Return Oriented Programming. The kernel is updated to support the following: + +* A PAC key set with a user defined random number generator is generated and is pushed onto the task's stack when a task is created. +* As part of scheduling, the task's PAC key is stacked/unstacked to/from the task's stack when a task is unscheduled/scheduled from/to run. + +This example demonstrates the soundness of the procedure used to stack/unstack the tasks' dedicated PAC key. The example is based on Corstone-315 Ecosystem Fixed Virtual Platform (Arm Cortex-M85 CPU and Ethos-U65 NPU). Follow the [link](https://www.arm.com/products/development-tools/simulation/fixed-virtual-platforms) to learn more about Arm fixed virtual platforms. + +Please refer to the Security related enhancements section in the [Introduction to Armv8.1-M architecture white paper document](https://www.arm.com/resources/white-paper/intro-armv8-1-m-architecture) for more information. + +# Prerequisites + +## Downloading and installing Corstone-315 Ecosystem Fixed Virtual Platform + +Follow the instructions on the [page](https://developer.arm.com/downloads/-/arm-ecosystem-fvps) to download Corstone-315 Ecosystem FVP based on your operating system. Ensure that requirements mentioned in the [page](https://developer.arm.com/documentation/100966/1126/Getting-Started-with-Fixed-Virtual-Platforms/Requirements-for-FVPs?lang=en) are met. + +Then, follow these instructions to install the Corstone-315 Ecosystem FVP +```bash +cd FVP_Corstone_SSE_315_11.xx_yy_64 + +./FVP_Corstone_SSE-315.sh + +Do you want to proceed with the installation? [default: yes] +Yes. + +Do you agree to the above terms and conditions? +Yes. + +Where would you like to install to? [default: /home//FVP_Corstone_SSE-315] +Press Enter for the default installation location or specify the absolute path for the required location. + +Installation completed successfully +``` + +Add the path to `FVP_Corstone_SSE-315` executable to the environment variable `PATH` (if the default installation location was used, the executable path would be something like `/home//FVP_Corstone_SSE-315/models/64__GCC-9.3/`). + +Execute the following command to ensure that the Fixed Virtual Platform for Corstone-315 was installed successfully +```bash +FVP_Corstone_SSE-315 --version + +Fast Models [11.xx.yy (month day year)] +Copyright 2000-2024 ARM Limited. +All Rights Reserved. +``` + +## Build tools + +* [CMake](https://cmake.org/download/) + * The Task Dedicated Pac Key example uses `CMake` as the build system. +* [Arm Compiler for Embedded Toolchain](https://developer.arm.com/Tools%20and%20Software/Arm%20Compiler%20for%20Embedded) + * To use Arm Compiler For Embedded Toolchain, login is required for the download, and you will need a license in order to +run the toolchain once installed. + +# Supported toolchains + +The example is supported and tested on the following toolchain: + + * Arm Compiler for Embedded v6.22 (armclang). + +# Configuration + +The FreeRTOS-Kernel provides a CMake variable `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` to configure the Armv8.1-M PACBTI security feature. The following values are supported: + +`ARM_V_8_1_M_PACBTI_CONFIG_STANDARD`: PACBTI Security Feature Standard Configuration (PAC enabled without leaf functions support, and BTI enabled ). + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI`: PACBTI Security Feature Standard + Leaf Configuration (PAC with leaf functions support, and BTI enabled). + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET`: PACBTI Security Feature with only PAC enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF`: PACBTI Security Feature with PAC and PAC for leaf functions support enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_BTI`: PACBTI Security Feature with only BTI enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_NONE`: PACBTI Security Feature disabled. + +It is recommend to set the intended value of `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` in the example's top level `CMakeLists.txt`. In this example, `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` is set to `ARM_V_8_1_M_PACBTI_CONFIG_PACRET` to enable Pointer Authentication Code. + +All the CMake targets defined to construct the example shall have the respective compiler options based on the configured value of the `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` variable. This is handled as part of `CMSIS/CMakeLists.txt` where the respective compiler options are added for the `arm-corstone-platform-bsp` target which is later linked to the example's target (i.e `cortex_m85_task_dedicated_pac_key_fvp_example`). These options are added for the `arm-corstone-platform-bsp` target, rather than being directly added for the example's target, to avoid duplicating the compiler options and definitions handling code for multiple targets. + +# Implementation + +The example consists of two main tasks (**prvFirstTask** and **prvSecondTask**). These tasks' job is to make sure that the task's randomly generated PAC keys are stacked/unstacked robustly without being altered. + +* These tasks perform the following sequence: + 1. Fetch the randomly generated dedicated PAC key for each task once they start running. + 2. Move the task to blocked state by calling `vTaskDelay()` function. + 3. As part of the context switching handler, the task's PAC key is unstacked after the task is unblocked, where the value of the PAC key before and after the blockage should be the same to prove the soundess of the task's dedicated PAC key stacking/unstacking procedure. + 4. If the task's PAC key before and after the blockage are not the same, a `configASSERT()` statement would be triggered. + +## Building and running examples + +First, run the following command to clone FreeRTOS repository: + +```bash +git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules +``` + +Run the following commands to build the Task Dedicated Pac Key example: + +```bash +cd FreeRTOS/FreeRTOS/Demo/ThirdParty/Partner-Supported-Demos/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG +rm -rf build && cmake -B build --toolchain=armclang_toolchain.cmake . && cmake --build build +``` + +### Running the example + +Execute the following script to run the Task Dedicated Pac Key example: +```bash +./run.sh +``` + +### Expected output + +```bash +$ ./run.sh +telnetterminal0: Listening for serial connection on port 5000 +telnetterminal1: Listening for serial connection on port 5001 +telnetterminal2: Listening for serial connection on port 5002 +telnetterminal5: Listening for serial connection on port 5003 +WARNING: ISAR5.PACBTI parameter is deprecated, use parameter CFGPACBTI +WARNING: ISAR5.PACBTI parameter is deprecated, use parameter CFGPACBTI + + Ethos-U rev 136b7d75 --- Apr 12 2023 13:47:17 + (C) COPYRIGHT 2019-2023 Arm Limited + ALL RIGHTS RESERVED + + +Info: Corstone_SSE_315_Main: Loading MaliC55Model + +Info: Corstone_SSE_315_Main: MaliC55Model build info: +*** +Version: C55-F5M9R1 +Git id: unknown +Host OS: Linux-4.11.0-44.el7a.aarch64 aarch64 +Compiler: GNU 9.3.0 /arm/devsys-tools/collections/gcc/9.3.0/1/linux_4.11-redhat_10.7-armv8l_64/gcc-4.8.5-SYSTEM/bin/c++ +Build tool: /usr/bin/gmake (+ CMake 3.14.3) +Build type: Release +BUILD_SHARED_LIBS: OFF +Build timestamp: Sep 15 2023 12:41:43 +RTL Version: r0p0-00eac0 +Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved. +*** +In secure world main ... +In non-secure world main ... + +PAC_KEY_P_0 for first Task is = 0x37f41ae + +PAC_KEY_P_1 for first Task is = 0x52e87011 + +PAC_KEY_P_2 for first Task is = 0x709a7ea6 + +PAC_KEY_P_3 for first Task is = 0x11c04236 + +PAC_KEY_P_0 for second Task is = 0x4b86ce0e + +PAC_KEY_P_1 for second Task is = 0x6516132 + +PAC_KEY_P_2 for second Task is = 0xde4b81 + +PAC_KEY_P_3 for second Task is = 0x94a10b8 + +Restored PAC_KEY_P_0 for the first Task is = 0x37f41ae + +Restored PAC_KEY_P_1 for the first Task is = 0x52e87011 + +Restored PAC_KEY_P_2 for the first Task is = 0x709a7ea6 + +Restored PAC_KEY_P_3 for the first Task is = 0x11c04236 + +First task's PAC keys matched successfully. Hence, deleteing the task. + +Restored PAC_KEY_P_0 for the second Task is = 0x4b86ce0e + +Restored PAC_KEY_P_1 for the second Task is = 0x6516132 + +Restored PAC_KEY_P_2 for the second Task is = 0xde4b81 + +Restored PAC_KEY_P_3 for the second Task is = 0x94a10b8 + +Second task's PAC keys matched successfully. Hence, deleteing the task. +^C +Stopping simulation... +``` diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang.sct b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang.sct new file mode 100644 index 0000000..af52fbd --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang.sct @@ -0,0 +1,46 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+fp.dp -E -x c +/* + * Copyright (c) 2021-2024 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define NS_ROM_START 0x01020000 +#define NS_ROM_SIZE 0x00020000 +#define NS_RAM_START 0x21040000 +#define NS_RAM_SIZE 0x00040000 +#define STACK_SIZE 0x00001000 +#define HEAP_SIZE 0x0000F000 +#define __STACKSEAL_SIZE 0x8 + +LOAD_REGION_0 NS_ROM_START NS_ROM_SIZE +{ + ER_CODE NS_ROM_START NS_ROM_SIZE { + *.o (RESET +First) + *(InRoot$$Sections) + * (+RO) + } + + ER_DATA NS_RAM_START NS_RAM_SIZE { + * (+ZI +RW) + } + + ARM_LIB_STACK +0 ALIGN 32 EMPTY STACK_SIZE - __STACKSEAL_SIZE { + } + + STACKSEAL +0 EMPTY __STACKSEAL_SIZE { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SIZE { + } +} diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang_toolchain.cmake b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang_toolchain.cmake new file mode 100644 index 0000000..26e0b28 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/armclang_toolchain.cmake @@ -0,0 +1,15 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR cortex-m85) + +set(CMAKE_C_COMPILER armclang) +set(CMAKE_CXX_COMPILER armclang) +set(CMAKE_ASM_COMPILER armclang) + +set(CMAKE_C_STANDARD 11) + +set(CMAKE_C_FLAGS "-march=armv8.1-m.main+pacbti+fp.dp+mve.fp -mfloat-abi=hard -mthumb -fdata-sections -g") +set(CMAKE_ASM_FLAGS "-march=armv8.1-m.main+pacbti+fp.dp+mve.fp+ -mfloat-abi=hard -mthumb -masm=auto --target=arm-arm-none-eabi -g") diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/ConvertElfToBin.cmake b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/ConvertElfToBin.cmake new file mode 100644 index 0000000..68b3da6 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/ConvertElfToBin.cmake @@ -0,0 +1,37 @@ +# Copyright 2021-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +function(target_axf_to_bin target output_binary_name) + set(SECTORS_BIN_DIR ${CMAKE_BINARY_DIR}/application_sectors CACHE INTERNAL "Output sectors binaries directory") + file(MAKE_DIRECTORY ${SECTORS_BIN_DIR}) + if(CMAKE_C_COMPILER_ID STREQUAL "IAR") + find_program(objcopy NAMES arm-none-eabi-objcopy objcopy REQUIRED) + set(elf_to_bin + ${objcopy} -O binary + $ + ${SECTORS_BIN_DIR}/${output_binary_name}.bin + ) + elseif(CMAKE_C_COMPILER_ID STREQUAL "ARMClang") + find_program(fromelf NAMES fromelf REQUIRED) + set(elf_to_bin + ${fromelf} --bin + --output ${SECTORS_BIN_DIR}/${output_binary_name}.bin + $ + ) + else() + message(FATAL_ERROR "Unsupported compiler: ${CMAKE_C_COMPILER_ID}") + endif() + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $ + COMMAND + ${elf_to_bin} + COMMAND + ${CMAKE_COMMAND} -E echo "-- built: $/${output_binary_name}.bin" + VERBATIM + ) +endfunction() diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/MergeImages.cmake b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/MergeImages.cmake new file mode 100644 index 0000000..a0a7d3d --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/cmake/MergeImages.cmake @@ -0,0 +1,31 @@ +# Copyright 2023-2024, Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +# To merge the secure image and non-secure user application image into +# one image. +# Order: , . + +function(merge_images target) + find_program(srec_cat NAMES srec_cat REQUIRED) + find_program(objcopy NAMES arm-none-eabi-objcopy objcopy REQUIRED) + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $/${target}_signed.bin + COMMAND + ${srec_cat} + ${CMAKE_BINARY_DIR}/application_sectors/flash_s.bin -Binary -offset ${S_IMAGE_LOAD_ADDRESS} + ${CMAKE_BINARY_DIR}/application_sectors/flash_ns.bin -Binary -offset ${NS_IMAGE_LOAD_ADDRESS} + -o $/${target}_merged.hex + COMMAND + ${objcopy} -I ihex -O elf32-little + $/${target}_merged.hex + $/${target}_merged.elf + COMMAND + ${CMAKE_COMMAND} -E echo "-- merged: $/${target}_merged.elf" + VERBATIM + ) +endfunction() diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/config/FreeRTOSConfig.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/config/FreeRTOSConfig.h new file mode 100644 index 0000000..86e1bd1 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/config/FreeRTOSConfig.h @@ -0,0 +1,191 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* See http://www.freertos.org/a00110.html for an explanation of the +* definitions contained in this file. +******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* https://www.FreeRTOS.org/a00110.html +*----------------------------------------------------------*/ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + extern uint32_t SystemCoreClock; + void vAssertCalled( const char * pcFile, unsigned long ulLine ); +#endif + +/* See https://freertos.org/a00110.html#configPROTECTED_KERNEL_OBJECT_POOL_SIZE for details. */ +#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 150 +/* See https://freertos.org/a00110.html#configSYSTEM_CALL_STACK_SIZE for details. */ +#define configSYSTEM_CALL_STACK_SIZE 128 + +/* Cortex M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 1 +#define configENABLE_MVE 0 + +/* This part has 16 MPU regions. */ +#define configTOTAL_MPU_REGIONS 8 + +/* Run FreeRTOS on the secure side and never jump to the non-secure side. */ +#define configRUN_FREERTOS_SECURE_ONLY 0 + +/* Constants related to the behaviour or the scheduler. */ +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_PREEMPTION 1 +#define configUSE_TIME_SLICING 1 +#define configMAX_PRIORITIES ( 10 ) +#define configIDLE_SHOULD_YIELD 1 +#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS + +/* Constants that describe the hardware and memory usage. */ +#define configCPU_CLOCK_HZ SystemCoreClock +#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 512 ) +#define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configTOTAL_HEAP_SIZE ( 0xF000 ) + +/* Constants that build features in or out. */ +#define configUSE_MUTEXES 1 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_TRACE_FACILITY 1 +#define configNUM_TX_DESCRIPTORS 15 +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 2 + +/* Constants that define which hook (callback) functions should be used. */ +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_MALLOC_FAILED_HOOK 1 + +/* Constants provided for debugging and optimisation assistance. */ +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ); +#define configQUEUE_REGISTRY_SIZE 20 + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. NOTE: Setting an INCLUDE_ parameter to 0 is + * only necessary if the linker does not automatically remove functions that are + * not referenced anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to + * human readable ASCII form. See the notes in the implementation of vTaskList() + * within FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +/* Dimensions a buffer that can be used by the FreeRTOS+CLI command interpreter. + * See the FreeRTOS+CLI documentation for more information: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_CLI/ */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2048 + +/* Interrupt priority configuration follows...................... */ + +/* Use the system definition, if there is one. */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 3 /* 8 priority levels. */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x07 + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT + * CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A + * HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +* to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* Constants related to the generation of run time stats. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#define portGET_RUN_TIME_COUNTER_VALUE() 0 + +/* Adjust configTICK_RATE_HZ and pdMS_TO_TICKS to simulate a tick per ms on a fast model */ +#define configTICK_RATE_HZ ( ( TickType_t ) 100 ) +#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) xTimeInMs ) + + +/* Enable dynamic allocation. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/main.c b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/main.c new file mode 100644 index 0000000..0e9f2d4 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/main.c @@ -0,0 +1,262 @@ +/* Copyright 2023-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#include "bsp_serial.h" + +#define PAC_KEY_SIZE_IN_BYTES ( 4U ) + +TaskHandle_t xFirstTaskHandle = NULL; +TaskHandle_t xSecondTaskHandle = NULL; + +void vAssertCalled( const char * pcFile, + unsigned long ulLine ) +{ + printf( "ASSERT failed! file %s:%lu, \r\n", pcFile, ulLine ); + + taskENTER_CRITICAL(); + { + volatile unsigned long looping = 0; + + /* Use the debugger to set ul to a non-zero value in order to step out + * of this function to determine why it was called. */ + while( looping == 0LU ) + { + portNOP(); + } + } + taskEXIT_CRITICAL(); +} + +static void prvFirstTask( void * arg ) +{ + /* Prevent the compiler warning about the unused parameter. */ + ( void ) arg; + + #if( configENABLE_PAC == 1 ) + /* This task performs the following sequence: + * + * 1. Fetch the task's randomly generated dedicated PAC key once it starts running. + * 2. Move the task to blocked state by calling `vTaskDelay()` function. + * 3. As part of the context switching handler, the task's PAC key is unstacked after the task is unblocked, where the value of the PAC key before and after the blockage should be the same to prove the soundess of the task's dedicated PAC key stacking/unstacking procedure. + * 4. If the task's PAC key before and after the blockage are not the same, a `configASSERT()` statement would be triggered. + */ + uint32_t ulFirstTaskPacKey[PAC_KEY_SIZE_IN_BYTES]; + uint32_t ulRestoredFirstTaskPacKey[PAC_KEY_SIZE_IN_BYTES]; + + __asm volatile ( "mrs %0, PAC_KEY_P_0" : "=r" ( ulFirstTaskPacKey[0] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_1" : "=r" ( ulFirstTaskPacKey[1] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_2" : "=r" ( ulFirstTaskPacKey[2] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_3" : "=r" ( ulFirstTaskPacKey[3] ) ); + + for ( uint8_t i = 0; i < PAC_KEY_SIZE_IN_BYTES; i++ ) + { + printf( "\r\nPAC_KEY_P_%d for first Task is = 0x%x\r\n", i, ulFirstTaskPacKey[i] ); + } + + vTaskDelay(100); + + __asm volatile ( "mrs %0, PAC_KEY_P_0" : "=r" ( ulRestoredFirstTaskPacKey[0] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_1" : "=r" ( ulRestoredFirstTaskPacKey[1] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_2" : "=r" ( ulRestoredFirstTaskPacKey[2] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_3" : "=r" ( ulRestoredFirstTaskPacKey[3] ) ); + + for ( uint8_t i = 0; i < PAC_KEY_SIZE_IN_BYTES; i++ ) + { + printf( "\r\nRestored PAC_KEY_P_%d for the first Task is = 0x%x\r\n", i, ulRestoredFirstTaskPacKey[i] ); + configASSERT( ulFirstTaskPacKey[i] == ulRestoredFirstTaskPacKey[i] ); + } + printf( "\r\nFirst task's PAC keys matched successfully. Hence, deleteing the task.\r\n" ); + vTaskDelete( xFirstTaskHandle ); + #else + printf( "\r\nPAC is not enabled. Hence, deleteing the prvFirstTask.\r\n" ); + vTaskDelete( xFirstTaskHandle ); + #endif +} + +static void prvSecondTask( void * arg ) +{ + /* Prevent the compiler warning about the unused parameter. */ + ( void ) arg; + + #if( configENABLE_PAC == 1 ) + /* This task performs the following sequence: + * + * 1. Fetch the task's randomly generated dedicated PAC key once it starts running. + * 2. Move the task to blocked state by calling `vTaskDelay()` function. + * 3. As part of the context switching handler, the task's PAC key is unstacked after the task is unblocked, where the value of the PAC key before and after the blockage should be the same to prove the soundess of the task's dedicated PAC key stacking/unstacking procedure. + * 4. If the task's PAC key before and after the blockage are not the same, a `configASSERT()` statement would be triggered. + */ + uint32_t ulSecondTaskPacKey[PAC_KEY_SIZE_IN_BYTES]; + uint32_t ulRestoredSecondTaskPacKey[PAC_KEY_SIZE_IN_BYTES]; + + __asm volatile ( "mrs %0, PAC_KEY_P_0" : "=r" ( ulSecondTaskPacKey[0] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_1" : "=r" ( ulSecondTaskPacKey[1] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_2" : "=r" ( ulSecondTaskPacKey[2] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_3" : "=r" ( ulSecondTaskPacKey[3] ) ); + + for ( uint8_t i = 0; i < PAC_KEY_SIZE_IN_BYTES; i++ ) + { + printf( "\r\nPAC_KEY_P_%d for second Task is = 0x%x\r\n", i, ulSecondTaskPacKey[i] ); + } + + vTaskDelay(100); + + __asm volatile ( "mrs %0, PAC_KEY_P_0" : "=r" ( ulRestoredSecondTaskPacKey[0] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_1" : "=r" ( ulRestoredSecondTaskPacKey[1] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_2" : "=r" ( ulRestoredSecondTaskPacKey[2] ) ); + __asm volatile ( "mrs %0, PAC_KEY_P_3" : "=r" ( ulRestoredSecondTaskPacKey[3] ) ); + + for ( uint8_t i = 0; i < PAC_KEY_SIZE_IN_BYTES; i++ ) + { + printf( "\r\nRestored PAC_KEY_P_%d for the second Task is = 0x%x\r\n", i, ulRestoredSecondTaskPacKey[i] ); + configASSERT( ulSecondTaskPacKey[i] == ulRestoredSecondTaskPacKey[i] ); + } + printf( "\r\nSecond task's PAC keys matched successfully. Hence, deleteing the task.\r\n" ); + vTaskDelete( xSecondTaskHandle ); + #else + printf( "\r\nPAC is not enabled. Hence, deleteing the prvSecondTask.\r\n" ); + vTaskDelete( xSecondTaskHandle ); + #endif +} + +int main() +{ + bsp_serial_init(); + + printf( "In non-secure world main ...\n" ); + + if(xTaskCreate( prvFirstTask, + NULL, + configMINIMAL_STACK_SIZE, + NULL, + ( tskIDLE_PRIORITY + 2 ), + &xFirstTaskHandle ) == pdFAIL ) + { + return EXIT_FAILURE; + } + + if(xTaskCreate( prvSecondTask, + NULL, + configMINIMAL_STACK_SIZE, + NULL, + ( tskIDLE_PRIORITY + 1 ), + &xSecondTaskHandle ) == pdFAIL ) + { + return EXIT_FAILURE; + } + + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details. NOTE: This demo uses static allocation + * for the idle and timer tasks so this line should never execute. */ + for( ; ; ) + { + } +} + +/** + * Dummy implementation of the callback function vApplicationStackOverflowHook(). + */ +#if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) + void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ) + { + ( void ) xTask; + ( void ) pcTaskName; + + /* Assert when stack overflow is enabled but no application defined function exists */ + configASSERT( 0 ); + } +#endif + +/*---------------------------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* + * vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + * equals to 1 and is required for static memory allocation support. + */ + void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) + { + /* Idle task control block and stack */ + static StaticTask_t Idle_TCB; + static StackType_t Idle_Stack[ configMINIMAL_STACK_SIZE ]; + + *ppxIdleTaskTCBBuffer = &Idle_TCB; + *ppxIdleTaskStackBuffer = &Idle_Stack[ 0 ]; + *pulIdleTaskStackSize = ( uint32_t ) configMINIMAL_STACK_SIZE; + } + +/* + * vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + * equals to 1 and is required for static memory allocation support. + */ + void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) + { + /* Timer task control block and stack */ + static StaticTask_t Timer_TCB; + static StackType_t Timer_Stack[ configTIMER_TASK_STACK_DEPTH ]; + + *ppxTimerTaskTCBBuffer = &Timer_TCB; + *ppxTimerTaskStackBuffer = &Timer_Stack[ 0 ]; + *pulTimerTaskStackSize = ( uint32_t ) configTIMER_TASK_STACK_DEPTH; + } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + +void vApplicationTickHook( void ) +{ + /* Provide a stub for this function. */ +} + +void vApplicationIdleHook( void ) +{ + const TickType_t xKitHitCheckPeriod = pdMS_TO_TICKS( 1000UL ); + static TickType_t xTimeNow, xLastTimeCheck = 0; + + if( ( xTimeNow - xLastTimeCheck ) > xKitHitCheckPeriod ) + { + xLastTimeCheck = xTimeNow; + } + + /* Exit. Just a stub. */ +} + +void vApplicationMallocFailedHook( void ) +{ + /* Provide a stub for this function. */ +} + +#if( configENABLE_PAC == 1 ) + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < 4; i++ ) + { + pulTaskPacKey[i] = rand(); + } + } +#endif /* configENABLE_PAC == 1 */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/run.sh b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/run.sh new file mode 100755 index 0000000..6bf36dc --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Copyright 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +FVP_Corstone_SSE-315 -a ./build/cortex_m85_task_dedicated_pac_key_fvp_example_merged.elf -C mps4_board.visualisation.disable-visualisation=1 -C core_clk.mul=200000000 -C mps4_board.hostbridge.userNetworking=1 -C mps4_board.telnetterminal0.start_telnet=0 -C mps4_board.uart0.out_file="-" -C mps4_board.uart0.unbuffered_output=1 -C vis_hdlcd.disable_visualisation=1 --stat -C mps4_board.subsystem.cpu0.CFGPACBTI=1 -C mps4_board.subsystem.cpu0.ID_ISAR5.PACBTI=1 -C mps4_board.subsystem.cpu0.semihosting-enable=1 diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/CMakeLists.txt b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/CMakeLists.txt new file mode 100644 index 0000000..b529f61 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/CMakeLists.txt @@ -0,0 +1,111 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.15) + +project( + s-dedicated-pac-key-example + VERSION 0.1 + LANGUAGES C ASM +) + +set (CMAKE_BUILD_TYPE Release) + +set(CMAKE_EXECUTABLE_SUFFIX ".axf") + +get_filename_component(FREERTOS_DIR_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../../.. REALPATH) +message(DEBUG "FREERTOS_DIR_PATH is ${FREERTOS_DIR_PATH}") + +add_compile_options("-mcmse") + +function(CreateVeneer app_name target_name) + set(veneers_name "veneers") + add_library(${app_name}_${veneers_name} STATIC) + + target_sources(${app_name}_${veneers_name} + PRIVATE + ${CMAKE_BINARY_DIR}/${veneers_name}.o + ) + + # Since s_veneers.o doesn't exist when this is evaluated by cmake we need to + # explicity specify what language it will use. + set_target_properties(${app_name}_${veneers_name} + PROPERTIES + LINKER_LANGUAGE C + ) + + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${veneers_name}.o + COMMAND + DEPENDS ${app_name} + ) + + target_link_options(${app_name} + PRIVATE + --import_cmse_lib_out=${CMAKE_BINARY_DIR}/${veneers_name}.o + ) + set(${target_name} "${app_name}_${veneers_name}" CACHE PATH "Veneers target name" FORCE) +endfunction() + +add_subdirectory(../CMSIS CMSIS) + +add_executable(secure_cortex_m85_task_dedicated_pac_key_fvp_example) + +target_sources(secure_cortex_m85_task_dedicated_pac_key_fvp_example + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/main_s.c + ${CMAKE_CURRENT_SOURCE_DIR}/secure_config.c + ${CMAKE_CURRENT_SOURCE_DIR}/../CMSIS/common/bsp_serial.c +) + +add_library(secure_kernel_lib) + +target_sources(secure_kernel_lib + PUBLIC + ${FREERTOS_DIR_PATH}/Source/portable/GCC/ARM_CM85/secure/secure_context.c + ${FREERTOS_DIR_PATH}/Source/portable/GCC/ARM_CM85/secure/secure_context_port.c + ${FREERTOS_DIR_PATH}/Source/portable/GCC/ARM_CM85/secure/secure_init.c + ${FREERTOS_DIR_PATH}/Source/portable/GCC/ARM_CM85/secure/secure_heap.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp/corstone315/Device/Source/startup_SSE315.c +) + +target_include_directories(secure_kernel_lib + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp/corstone315/Device/Include + ${CMAKE_CURRENT_SOURCE_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp/corstone315/Board/Platform + ${CMAKE_CURRENT_SOURCE_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp/CMSIS/CMSIS_6/CMSIS/Core/Include/ +) + +target_link_libraries(secure_kernel_lib + freertos_config +) + +target_include_directories(freertos_kernel_port_headers + INTERFACE + ${FREERTOS_DIR_PATH}/Source/portable/GCC/ARM_CM85/secure +) + +target_include_directories(secure_cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../CMSIS/common + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(secure_cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + arm-corstone-platform-bsp + secure_kernel_lib +) + +target_link_options(secure_cortex_m85_task_dedicated_pac_key_fvp_example + PRIVATE + --scatter=${CMAKE_CURRENT_SOURCE_DIR}/armclang_s.sct + --map + --entry=Reset_Handler +) + +CreateVeneer(secure_cortex_m85_task_dedicated_pac_key_fvp_example VENEERS_TARGET_NAME) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake) +include(ConvertElfToBin) +target_axf_to_bin(secure_cortex_m85_task_dedicated_pac_key_fvp_example flash_s) diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/armclang_s.sct b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/armclang_s.sct new file mode 100644 index 0000000..01e198c --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/armclang_s.sct @@ -0,0 +1,49 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+fp.dp -E -x c +/* + * Copyright (c) 2021-2024 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define S_ROM_START 0x11000000 +#define S_ROM_SIZE 0x00020000 +#define S_RAM_START 0x31000000 +#define S_RAM_SIZE 0x00040000 +#define STACK_SIZE 0x00001000 +#define HEAP_SIZE 0x00001000 +#define __STACKSEAL_SIZE 0x8 + +LOAD_REGION_0 S_ROM_START S_ROM_SIZE +{ + ER_CODE S_ROM_START S_ROM_SIZE { + *.o(RESET + FIRST) + *(+RO) + } + + ER_CODE_CMSE_VENEER +0 ALIGN 32 { + *(Veneer$$CMSE) + } + + ER_DATA S_RAM_START S_RAM_SIZE { + *(+RW, +ZI) + } + + ARM_LIB_STACK +0 ALIGN 32 EMPTY STACK_SIZE - __STACKSEAL_SIZE { + } + + STACKSEAL +0 EMPTY __STACKSEAL_SIZE { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SIZE { + } +} diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/main_s.c b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/main_s.c new file mode 100644 index 0000000..dc73911 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/main_s.c @@ -0,0 +1,66 @@ +/* Copyright 2023-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: MIT + */ + +#include +#include "SSE315.h" +#include "system_SSE315.h" +#include "platform_irq.h" +#include "core_cm85.h" +#include "bsp_serial.h" +#include +#include "RTE_Components.h" +#include CMSIS_device_header +#include "region_defs.h" +#include "secure_config.h" + +/** + * @brief Boots into the non-secure code. + * + */ +static void prvBootNonSecure( void ); + +/* + * This function pointer is meant to only hold non-secure function pointers. + */ +typedef void (*nsfptr_t)(void) __attribute__((cmse_nonsecure_call)); + +int main() +{ + bsp_serial_init(); + printf( "In secure world main ...\n" ); + /* As part of secure platform init, configure uart0 to non-secure accessible. + */ + secure_platform_init(); + prvBootNonSecure(); + + /* Non-secure software does not return, this code is not executed. */ + for( ; ; ) + { + } +} + +static void prvBootNonSecure( void ) +{ + /* SCB_NS.VTOR points to the Non-secure vector table base address */ + SCB_NS->VTOR = (NS_CODE_START); + + /* Setup Main stack pointer of the non-secure code */ + uint32_t ns_msp = *(uint32_t *)(NS_CODE_START); + __TZ_set_MSP_NS(ns_msp); + + /* The entry contains adddress of the Reset_handler (CMSIS-CORE) function */ + uintptr_t entry_ptr = *(uint32_t *)(NS_CODE_START + 4); + + /* Clear LSB of the function address to indicate the function-call + will perform the switch from secure to non-secure */ + nsfptr_t ns_entry = (nsfptr_t)cmse_nsfptr_create(entry_ptr); + + /* All changes made to memory will be effective after this point */ + __DSB(); + __ISB(); + + /* Call the non-secure Reset_Handler to jump to the non-secure binary */ + ns_entry(); +} diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_defs.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_defs.h new file mode 100644 index 0000000..049f0cf --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_defs.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-2024 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "region_limits.h" + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure regions */ +#define S_CODE_START (S_ROM_ALIAS) +#define S_CODE_SIZE (TOTAL_S_ROM_SIZE) +#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1) + +#define S_DATA_START (S_RAM_ALIAS) +#define S_DATA_SIZE (TOTAL_S_RAM_SIZE) +#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1) + +/* Non-Secure regions */ +#define NS_CODE_START (NS_ROM_ALIAS) +#define NS_CODE_SIZE (TOTAL_NS_ROM_SIZE) +#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1) + +#define NS_DATA_START (NS_RAM_ALIAS) +#define NS_DATA_SIZE (TOTAL_NS_RAM_SIZE) +#define NS_DATA_LIMIT (NS_DATA_START + NS_DATA_SIZE - 1) + +#endif /* __REGION_DEFS_H__ */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_limits.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_limits.h new file mode 100644 index 0000000..d9c7c6d --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/region_limits.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2024 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_LIMITS_H__ +#define __REGION_LIMITS_H__ + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure Code */ +#define S_ROM_ALIAS (0x11000000) /* SRAM_BASE_S */ +#define TOTAL_S_ROM_SIZE (0x00020000) /* 128 kB */ + +/* Secure Data */ +#define S_RAM_ALIAS (0x31000000) /* ISRAM0_BASE_S */ +#define TOTAL_S_RAM_SIZE (0x00040000) /* 256 kB */ + +/* Non-Secure Code */ +#define NS_ROM_ALIAS (0x01000000 + 0x00020000) /* SRAM_BASE_NS */ +#define TOTAL_NS_ROM_SIZE (0x00020000) /* 128 kB */ + +/* Non-Secure Data */ +#define NS_RAM_ALIAS (0x21000000 + 0x00040000) /* ISRAM0_BASE_NS */ +#define TOTAL_NS_RAM_SIZE (0x00040000) /* 256 kB */ + +#endif /* __REGION_LIMITS_H__ */ diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.c b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.c new file mode 100644 index 0000000..90aff70 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2019-2024, Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SSE315.h" +#include "system_SSE315.h" +#include "platform_irq.h" +#include "core_cm85.h" +#include "secure_config.h" +#include "Driver_MPC.h" +#include "Driver_PPC.h" +#include "cmsis_armclang.h" +#include "device_cfg.h" +#include "region_defs.h" +#include "platform_base_address.h" +#include "platform_regs.h" + +#define REGION(a, b, c) a##b##c +#define REGION_NAME(a, b, c) REGION(a, b, c) +#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c) + +REGION_DECLARE(Image$$, ER_CODE_CMSE_VENEER, $$Base); +REGION_DECLARE(Image$$, ER_CODE_CMSE_VENEER, $$Limit); + +#define CMSE_VENEER_REGION_BASE ((uint32_t)®ION_NAME(Image$$, ER_CODE_CMSE_VENEER, $$Base)) +#define CMSE_VENEER_REGION_LIMIT ((uint32_t)®ION_NAME(Image$$, ER_CODE_CMSE_VENEER, $$Limit) - 1) + +extern ARM_DRIVER_MPC Driver_SRAM_MPC; +extern ARM_DRIVER_MPC Driver_ISRAM0_MPC; +extern ARM_DRIVER_PPC_CORSTONE315 Driver_PERIPH_EXP2_PPC_CORSTONE315; + +#define CHECK_ERROR(error_code) \ + do { \ + if ((error_code) != ARM_DRIVER_OK) { \ + __BKPT(0); \ + return error_code; \ + } \ + } while (0) + +static int32_t MPC_config(void) +{ + /* Initialize the MPC */ + CHECK_ERROR(Driver_SRAM_MPC.Initialize()); + CHECK_ERROR(Driver_ISRAM0_MPC.Initialize()); + + /* Configure the MPCs */ + /* SRAM holds NS Code */ + CHECK_ERROR(Driver_SRAM_MPC.ConfigRegion(NS_CODE_START, NS_CODE_LIMIT, ARM_MPC_ATTR_NONSECURE)); + + /* ISRAM0 holds NS Data */ + CHECK_ERROR(Driver_ISRAM0_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT, ARM_MPC_ATTR_NONSECURE)); + + /* Lock down the MPC configurations */ + CHECK_ERROR(Driver_SRAM_MPC.LockDown()); + CHECK_ERROR(Driver_ISRAM0_MPC.LockDown()); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_config(void) +{ + struct corstone315_sacfg_t *sactrl = (struct corstone315_sacfg_t *)CORSTONE315_SACFG_BASE_S; + + /* Set UART0 to Non-Secure + * After these settings, UART0 can be used only through + * the non-secure alias + */ + CHECK_ERROR(Driver_PERIPH_EXP2_PPC_CORSTONE315.Initialize()); + CHECK_ERROR(Driver_PERIPH_EXP2_PPC_CORSTONE315.ConfigSecurity(UART0_PERIPH_PPCEXP2_POS_MASK, + ARM_PPC_CORSTONE315_NONSECURE_CONFIG)); + + CHECK_ERROR(Driver_PERIPH_EXP2_PPC_CORSTONE315.ConfigPrivilege(UART0_PERIPH_PPCEXP2_POS_MASK, + ARM_PPC_CORSTONE315_NONSECURE_CONFIG, + ARM_PPC_CORSTONE315_PRIV_AND_NONPRIV_CONFIG)); + /* + * Configure the response to a security violation as a + * bus error instead of RAZ/WI + */ + sactrl->secrespcfg |= 1; + + return ARM_DRIVER_OK; +} + +static void SAU_config(void) +{ + uint32_t sau_idx = 0; + struct corstone315_sacfg_t *sactrl = (struct corstone315_sacfg_t *)CORSTONE315_SACFG_BASE_S; + /* Enable SAU */ + TZ_SAU_Enable(); + + SAU->RNR = sau_idx++; + SAU->RBAR = (NS_CODE_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = ((NS_CODE_LIMIT)&SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + SAU->RNR = sau_idx++; + SAU->RBAR = ((NS_DATA_START)&SAU_RBAR_BADDR_Msk); + SAU->RLAR = ((NS_DATA_LIMIT)&SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + SAU->RNR = sau_idx++; + SAU->RBAR = (CMSE_VENEER_REGION_BASE & SAU_RBAR_BADDR_Msk); + SAU->RLAR = ((CMSE_VENEER_REGION_LIMIT)&SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk; + + /* Set UART0 to Non-Secure */ + SAU->RNR = sau_idx; + SAU->RBAR = (UART0_BASE_NS & SAU_RBAR_BADDR_Msk); + SAU->RLAR = ((UART1_BASE_NS - 1) & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + +#ifdef SYSWDOG_ARMV8_M_DEV + sau_idx++; + /* Enable NS System Watchdog access in Non-Secure */ + SAU->RNR = sau_idx; + SAU->RBAR = (SYSWDOG_ARMV8_M_CNTRL_BASE_NS & SAU_RLAR_LADDR_Msk); + SAU->RLAR = ((SYSWDOG_ARMV8_M_CNTRL_BASE_NS + 0x1FFF) & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; +#endif + + /* Configures CODE region (0x1000_0000 to 0x1FFF_FFFF) + * to Non-secure Callable. */ + sactrl->nsccfg |= 1; +} + +/* + * \brief Configures the necessary security components + */ +void secure_platform_init(void) +{ + bool error = false; + + SAU_config(); + error = error || MPC_config(); + error = error || PPC_config(); + + if (error) { + while (1) + ; + } + + NVIC_EnableIRQ(MPC_IRQn); + NVIC_EnableIRQ(PPC_IRQn); + + /* Enables BUS, MEM, USG and Secure faults */ + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk + | SCB_SHCSR_SECUREFAULTENA_Msk; + + SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk; + + NVIC_SetTargetState(UARTTX0_IRQn); + NVIC_SetTargetState(UARTRX0_IRQn); +} diff --git a/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.h b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.h new file mode 100644 index 0000000..b1e3d70 --- /dev/null +++ b/CORTEX_M85_TASK_DEDICATED_PAC_KEY_FVP_ARMCLANG/secure/secure_config.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2024 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SECURE_CONFIG_H__ +#define __SECURE_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * \brief Configures the needed security components + */ +void secure_platform_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SECURE_CONFIG_H__ */