diff options
author | Marton Berke <marton.berke@arm.com> | 2020-07-28 14:52:29 +0200 |
---|---|---|
committer | Tamas Ban <tamas.ban@arm.com> | 2020-11-04 10:09:44 +0000 |
commit | 8c2f524067093681896cd69474813488ac59e022 (patch) | |
tree | 99f452548eaa10bad6a0064bcff7a45e57b85800 /platform/ext/target/mps3 | |
parent | 8d973dab667ddbe45cf130a36cca497eb38f81d0 (diff) | |
download | trusted-firmware-m-8c2f524067093681896cd69474813488ac59e022.tar.gz |
Platform: Add mps3/fvp_sse300 target
Add support for Corstone-300 Ethos-U55 FVP as mps3/fvp_sse300 platform
Change-Id: I41a3fd07665a0bc16be5a251b3789dfbadfe7e45
Signed-off-by: Marton Berke <marton.berke@arm.com>
Diffstat (limited to 'platform/ext/target/mps3')
48 files changed, 12874 insertions, 0 deletions
diff --git a/platform/ext/target/mps3/fvp_sse300/CMakeLists.txt b/platform/ext/target/mps3/fvp_sse300/CMakeLists.txt new file mode 100644 index 0000000000..139b17cc00 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/CMakeLists.txt @@ -0,0 +1,186 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +#========================= Platform region defs ===============================# + +target_include_directories(platform_region_defs + INTERFACE + partition +) + +#========================= Platform common defs ===============================# + +if (${CMAKE_C_COMPILER_ID} STREQUAL GNU) + message(FATAL_ERROR "GCC is currently not supported on the mps3/fvp_sse300_mps3 because TFM build system does not support the Coretex-M55 with GNUARM") +endif() + +if (${CMAKE_C_COMPILER_ID} STREQUAL IAR) + message(FATAL_ERROR "IAR is currently not supported on the mps3/fvp_sse300_mps3 due to a lack of scatter files") +endif() + +if (${CMAKE_C_COMPILER_ID} STREQUAL ARMClang) + if (${CMAKE_C_COMPILER_VERSION} VERSION_LESS "6.14") + message(FATAL_ERROR "CPU (Cortex-M55) is only supported in ARMCLANG version 6.14 or newer.") + endif() +endif() + +# Specify the location of platform specific build dependencies. +target_sources(tfm_s + PRIVATE + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_fvp_sse300_mps3_s.c> +) +target_add_scatter_file(tfm_s + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_common_s.sct> +) + +if(NS) + target_sources(tfm_ns + PRIVATE + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_fvp_sse300_mps3_ns.c> + ) + target_add_scatter_file(tfm_ns + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/fvp_sse300_mps3_ns.sct> + ) + target_link_libraries(CMSIS_5_tfm_ns + INTERFACE + CMSIS_5_RTX_V8MMN + ) +endif() + +if(BL2) + target_sources(bl2 + PRIVATE + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_fvp_sse300_mps3_bl2.c> + ) + target_add_scatter_file(bl2 + $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/fvp_sse300_mps3_bl2.sct> + ) +endif() + +#========================= Platform Secure ====================================# + +target_include_directories(platform_s + PUBLIC + . + ../common + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + services/src + native_drivers + ${PLATFORM_DIR}/.. +) + +target_sources(platform_s + PRIVATE + cmsis_drivers/Driver_FVP_SSE300_MPC.c + cmsis_drivers/Driver_Flash.c + cmsis_drivers/Driver_SSE300_PPC.c + cmsis_drivers/Driver_USART.c + device/source/system_core_init.c + device/source/device_definition.c + native_drivers/mpc_sie_drv.c + native_drivers/mpu_armv8m_drv.c + native_drivers/ppc_sse300_drv.c + native_drivers/syscounter_armv8-m_cntrl_drv.c + native_drivers/systimer_armv8-m_drv.c + native_drivers/uart_cmsdk_drv.c + spm_hal.c + target_cfg.c + tfm_hal_isolation.c + ${CMAKE_SOURCE_DIR}/platform/ext/common/tfm_hal_isolation_mpu_v8m.c + $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> + $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c> +) + +target_link_libraries(platform_s + PRIVATE + tfm_utilities +) + +target_compile_options(platform_s + PUBLIC + ${COMPILER_CMSE_FLAG} +) + +target_compile_definitions(platform_s + PUBLIC + $<$<C_COMPILER_ID:GNU>:__STARTUP_CLEAR_BSS_MULTIPLE> + $<$<C_COMPILER_ID:GNU>:__STARTUP_COPY_MULTIPLE> +) + +#========================= Platform Non-Secure ================================# + +target_sources(platform_ns + PRIVATE + device/source/system_core_init.c + device/source/device_definition.c + native_drivers/systimer_armv8-m_drv.c + native_drivers/uart_cmsdk_drv.c + cmsis_drivers/Driver_Flash.c + cmsis_drivers/Driver_USART.c + $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> + $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c> +) + +target_include_directories(platform_ns + PUBLIC + . + ../common + ${PLATFORM_DIR}/.. + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + services/src + native_drivers +) + +#========================= Platform BL2 =======================================# + +if(BL2) + target_sources(platform_bl2 + PRIVATE + boot_hal.c + device/source/device_definition.c + device/source/system_core_init.c + cmsis_drivers/Driver_Flash.c + native_drivers/uart_cmsdk_drv.c + cmsis_drivers/Driver_USART.c + ) + + target_include_directories(platform_bl2 + PUBLIC + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + services/src + native_drivers + + PRIVATE + . + ${PLATFORM_DIR}/.. + native_drivers + ) +endif() diff --git a/platform/ext/target/mps3/fvp_sse300/README.rst b/platform/ext/target/mps3/fvp_sse300/README.rst new file mode 100644 index 0000000000..e27cfb824a --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/README.rst @@ -0,0 +1,16 @@ +Corstone-300 Ethos-U55 FVP +========================== + +Building TF-M +------------- + +Follow the instructions in Getting started guide / 2. Build instructions with platform name: mps3/fvp_sse300 (-DTFM_PLATFORM=mps3/fvp_sse300). + +Note +---- + +This platform support does not provide software for Ethos-U55 IP, only contains base address and interrupt number for it. + +------------- + +*Copyright (c) 2020, Arm Limited. All rights reserved.* diff --git a/platform/ext/target/mps3/fvp_sse300/boot_hal.c b/platform/ext/target/mps3/fvp_sse300/boot_hal.c new file mode 100644 index 0000000000..9e93972487 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/boot_hal.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "cmsis.h" +#include "region.h" +#include "target_cfg.h" +#include "boot_hal.h" +#include "Driver_Flash.h" +#include "flash_layout.h" + +/* Flash device name must be specified by target */ +extern ARM_DRIVER_FLASH FLASH_DEV_NAME; + +REGION_DECLARE(Image$$, ER_DATA, $$Base)[]; +REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[]; +REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base); + +__attribute__((naked)) void boot_clear_bl2_ram_area(void) +{ + __ASM volatile( + "mov r0, #0 \n" + "subs %1, %1, %0 \n" + "Loop: \n" + "subs %1, #4 \n" + "itt ge \n" + "strge r0, [%0, %1] \n" + "bge Loop \n" + "bx lr \n" + : + : "r" (REGION_NAME(Image$$, ER_DATA, $$Base)), + "r" (REGION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)) + : "r0", "memory" + ); +} + +int32_t boot_platform_init(void) +{ + int32_t result; + + /* Initialize stack limit register */ + uint32_t msp_stack_bottom = + (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base); + + __set_MSPLIM(msp_stack_bottom); + + result = FLASH_DEV_NAME.Initialize(NULL); + if (result != ARM_DRIVER_OK) { + return 1; + } + + return 0; +} + +void boot_platform_quit(struct boot_arm_vector_table *vt) +{ + /* Clang at O0, stores variables on the stack with SP relative addressing. + * When manually set the SP then the place of reset vector is lost. + * Static variables are stored in 'data' or 'bss' section, change of SP has + * no effect on them. + */ + static struct boot_arm_vector_table *vt_cpy; + int32_t result; + + result = FLASH_DEV_NAME.Uninitialize(); + if (result != ARM_DRIVER_OK) { + while (1); + } + + vt_cpy = vt; + + __set_MSPLIM(0); + __set_MSP(vt->msp); + __DSB(); + __ISB(); + + boot_jump_to_next_image(vt_cpy->reset); +} + diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_FVP_SSE300_MPC.c b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_FVP_SSE300_MPC.c new file mode 100644 index 0000000000..4b24631f79 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_FVP_SSE300_MPC.c @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2016-2020 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. + */ + +#include "Driver_MPC.h" + +#include "mpc_sie_drv.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +/* Driver version */ +#define ARM_MPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_MPC_API_VERSION, + ARM_MPC_DRV_VERSION +}; + +static ARM_DRIVER_VERSION ARM_MPC_GetVersion(void) +{ + return DriverVersion; +} + +/* + * \brief Translates error codes from native API to CMSIS API. + * + * \param[in] err Error code to translate (\ref mpc_sie_error_t). + * + * \return Returns CMSIS error code. + */ +static int32_t error_trans(enum mpc_sie_error_t err) +{ + switch(err) { + case MPC_SIE_ERR_NONE: + return ARM_DRIVER_OK; + case MPC_SIE_INVALID_ARG: + return ARM_DRIVER_ERROR_PARAMETER; + case MPC_SIE_NOT_INIT: + return ARM_MPC_ERR_NOT_INIT; + case MPC_SIE_ERR_NOT_IN_RANGE: + return ARM_MPC_ERR_NOT_IN_RANGE; + case MPC_SIE_ERR_NOT_ALIGNED: + return ARM_MPC_ERR_NOT_ALIGNED; + case MPC_SIE_ERR_INVALID_RANGE: + return ARM_MPC_ERR_INVALID_RANGE; + case MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE: + return ARM_MPC_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE; + default: + return ARM_MPC_ERR_UNSPECIFIED; + } +} + +#if (RTE_SRAM_MPC) +/* Ranges controlled by this SRAM_MPC */ +static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_S = { + .base = MPC_SRAM_RANGE_BASE_S, + .limit = MPC_SRAM_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_NS = { + .base = MPC_SRAM_RANGE_BASE_NS, + .limit = MPC_SRAM_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_SRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_SRAM_RANGE_LIST[MPC_SRAM_RANGE_LIST_LEN] = { + &MPC_SRAM_RANGE_S, + &MPC_SRAM_RANGE_NS + }; + +/* SRAM_MPC Driver wrapper functions */ +static int32_t SRAM_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_SRAM_DEV, + MPC_SRAM_RANGE_LIST, + MPC_SRAM_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t SRAM_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_SRAM_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_SRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_SRAM_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_GetRegionConfig(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR *attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_SRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t*)attr); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_ConfigRegion(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_SRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_SRAM_DEV); + + return error_trans(ret); +} + +static void SRAM_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_SRAM_DEV); +} + + +static void SRAM_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_SRAM_DEV); +} + +static uint32_t SRAM_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_SRAM_DEV); +} + +static int32_t SRAM_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_SRAM_DEV); +} + +/* SRAM_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_SRAM_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = SRAM_MPC_Initialize, + .Uninitialize = SRAM_MPC_Uninitialize, + .GetBlockSize = SRAM_MPC_GetBlockSize, + .GetCtrlConfig = SRAM_MPC_GetCtrlConfig, + .SetCtrlConfig = SRAM_MPC_SetCtrlConfig, + .ConfigRegion = SRAM_MPC_ConfigRegion, + .GetRegionConfig = SRAM_MPC_GetRegionConfig, + .EnableInterrupt = SRAM_MPC_EnableInterrupt, + .DisableInterrupt = SRAM_MPC_DisableInterrupt, + .ClearInterrupt = SRAM_MPC_ClearInterrupt, + .InterruptState = SRAM_MPC_InterruptState, + .LockDown = SRAM_MPC_LockDown, +}; +#endif /* RTE_SRAM_MPC */ + +#if (RTE_ISRAM0_MPC) +/* Ranges controlled by this ISRAM0_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_S = { + .base = MPC_ISRAM0_RANGE_BASE_S, + .limit = MPC_ISRAM0_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_NS = { + .base = MPC_ISRAM0_RANGE_BASE_NS, + .limit = MPC_ISRAM0_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM0_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_ISRAM0_RANGE_LIST[MPC_ISRAM0_RANGE_LIST_LEN] = { + &MPC_ISRAM0_RANGE_S, + &MPC_ISRAM0_RANGE_NS + }; + +/* ISRAM0_MPC Driver wrapper functions */ +static int32_t ISRAM0_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM0_DEV, + MPC_ISRAM0_RANGE_LIST, + MPC_ISRAM0_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM0_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM0_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_GetRegionConfig(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR *attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_ISRAM0_DEV, base, limit, + (enum mpc_sie_sec_attr_t*)attr); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_ConfigRegion(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_ISRAM0_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM0_DEV); + + return error_trans(ret); +} + +static void ISRAM0_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM0_DEV); +} + + +static void ISRAM0_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM0_DEV); +} + +static uint32_t ISRAM0_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM0_DEV); +} + +static int32_t ISRAM0_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM0_DEV); +} + +/* ISRAM0_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM0_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM0_MPC_Initialize, + .Uninitialize = ISRAM0_MPC_Uninitialize, + .GetBlockSize = ISRAM0_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM0_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM0_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM0_MPC_ConfigRegion, + .GetRegionConfig = ISRAM0_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM0_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM0_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM0_MPC_ClearInterrupt, + .InterruptState = ISRAM0_MPC_InterruptState, + .LockDown = ISRAM0_MPC_LockDown, +}; +#endif /* RTE_ISRAM0_MPC */ + +#if (RTE_ISRAM1_MPC) +/* Ranges controlled by this ISRAM1_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_S = { + .base = MPC_ISRAM1_RANGE_BASE_S, + .limit = MPC_ISRAM1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_NS = { + .base = MPC_ISRAM1_RANGE_BASE_NS, + .limit = MPC_ISRAM1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM1_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_ISRAM1_RANGE_LIST[MPC_ISRAM1_RANGE_LIST_LEN] = { + &MPC_ISRAM1_RANGE_S, + &MPC_ISRAM1_RANGE_NS + }; + +/* ISRAM1_MPC Driver wrapper functions */ +static int32_t ISRAM1_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM1_DEV, + MPC_ISRAM1_RANGE_LIST, + MPC_ISRAM1_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM1_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM1_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_GetRegionConfig(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR *attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_ISRAM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t*)attr); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_ConfigRegion(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_ISRAM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM1_DEV); + + return error_trans(ret); +} + +static void ISRAM1_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM1_DEV); +} + + +static void ISRAM1_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM1_DEV); +} + +static uint32_t ISRAM1_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM1_DEV); +} + +static int32_t ISRAM1_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM1_DEV); +} + +/* ISRAM1_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM1_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM1_MPC_Initialize, + .Uninitialize = ISRAM1_MPC_Uninitialize, + .GetBlockSize = ISRAM1_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM1_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM1_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM1_MPC_ConfigRegion, + .GetRegionConfig = ISRAM1_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM1_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM1_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM1_MPC_ClearInterrupt, + .InterruptState = ISRAM1_MPC_InterruptState, + .LockDown = ISRAM1_MPC_LockDown, +}; +#endif /* RTE_ISRAM1_MPC */ + +#if (RTE_QSPI_MPC) +/* Ranges controlled by this QSPI_MPC */ +static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_S = { + .base = MPC_QSPI_RANGE_BASE_S, + .limit = MPC_QSPI_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_NS = { + .base = MPC_QSPI_RANGE_BASE_NS, + .limit = MPC_QSPI_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_QSPI_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_QSPI_RANGE_LIST[MPC_QSPI_RANGE_LIST_LEN] = { + &MPC_QSPI_RANGE_S, + &MPC_QSPI_RANGE_NS + }; + +/* QSPI_MPC Driver wrapper functions */ +static int32_t QSPI_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_QSPI_DEV, + MPC_QSPI_RANGE_LIST, + MPC_QSPI_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t QSPI_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_QSPI_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_QSPI_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_QSPI_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_GetRegionConfig(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR *attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_QSPI_DEV, base, limit, + (enum mpc_sie_sec_attr_t*)attr); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_ConfigRegion(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_QSPI_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_QSPI_DEV); + + return error_trans(ret); +} + +static void QSPI_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_QSPI_DEV); +} + + +static void QSPI_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_QSPI_DEV); +} + +static uint32_t QSPI_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_QSPI_DEV); +} + +static int32_t QSPI_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_QSPI_DEV); +} + +/* QSPI_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_QSPI_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = QSPI_MPC_Initialize, + .Uninitialize = QSPI_MPC_Uninitialize, + .GetBlockSize = QSPI_MPC_GetBlockSize, + .GetCtrlConfig = QSPI_MPC_GetCtrlConfig, + .SetCtrlConfig = QSPI_MPC_SetCtrlConfig, + .ConfigRegion = QSPI_MPC_ConfigRegion, + .GetRegionConfig = QSPI_MPC_GetRegionConfig, + .EnableInterrupt = QSPI_MPC_EnableInterrupt, + .DisableInterrupt = QSPI_MPC_DisableInterrupt, + .ClearInterrupt = QSPI_MPC_ClearInterrupt, + .InterruptState = QSPI_MPC_InterruptState, + .LockDown = QSPI_MPC_LockDown, +}; +#endif /* RTE_QSPI_MPC */ + +#if (RTE_DDR4_MPC) +/* Ranges controlled by this DDR4_MPC */ +static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_S = { + .base = MPC_DDR4_RANGE_BASE_S, + .limit = MPC_DDR4_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_NS = { + .base = MPC_DDR4_RANGE_BASE_NS, + .limit = MPC_DDR4_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_DDR4_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_DDR4_RANGE_LIST[MPC_DDR4_RANGE_LIST_LEN] = { + &MPC_DDR4_RANGE_S, + &MPC_DDR4_RANGE_NS + }; + +/* DDR4_MPC Driver wrapper functions */ +static int32_t DDR4_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_DDR4_DEV, + MPC_DDR4_RANGE_LIST, + MPC_DDR4_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t DDR4_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_DDR4_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_DDR4_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_DDR4_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_GetRegionConfig(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR *attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_DDR4_DEV, base, limit, + (enum mpc_sie_sec_attr_t*)attr); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_ConfigRegion(uintptr_t base, + uintptr_t limit, + ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_DDR4_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_DDR4_DEV); + + return error_trans(ret); +} + +static void DDR4_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_DDR4_DEV); +} + + +static void DDR4_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_DDR4_DEV); +} + +static uint32_t DDR4_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_DDR4_DEV); +} + +static int32_t DDR4_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_DDR4_DEV); +} + +/* DDR4_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_DDR4_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = DDR4_MPC_Initialize, + .Uninitialize = DDR4_MPC_Uninitialize, + .GetBlockSize = DDR4_MPC_GetBlockSize, + .GetCtrlConfig = DDR4_MPC_GetCtrlConfig, + .SetCtrlConfig = DDR4_MPC_SetCtrlConfig, + .ConfigRegion = DDR4_MPC_ConfigRegion, + .GetRegionConfig = DDR4_MPC_GetRegionConfig, + .EnableInterrupt = DDR4_MPC_EnableInterrupt, + .DisableInterrupt = DDR4_MPC_DisableInterrupt, + .ClearInterrupt = DDR4_MPC_ClearInterrupt, + .InterruptState = DDR4_MPC_InterruptState, + .LockDown = DDR4_MPC_LockDown, +}; +#endif /* RTE_DDR4_MPC */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_Flash.c b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_Flash.c new file mode 100644 index 0000000000..06d3546f03 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 <string.h> +#include <stdint.h> +#include "Driver_Flash.h" +#include "RTE_Device.h" +#include "platform_base_address.h" + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) ((void)arg) +#endif + +#define FLASH0_BASE_S SRAM_BASE_S +#define FLASH0_BASE_NS SRAM_BASE_NS +#define FLASH0_SIZE SRAM_SIZE +#define FLASH0_SECTOR_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PAGE_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PROGRAM_UNIT 0x1 /* Minimum write size */ + +/* Driver version */ +#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1) +#define ARM_FLASH_DRV_ERASE_VALUE 0xFF + +/* + * ARM FLASH device structure + * + * This driver just emulates a flash interface and behaviour on top of the SRAM + * memory. + */ +struct arm_flash_dev_t { + const uint32_t memory_base; /*!< FLASH memory base address */ + ARM_FLASH_INFO *data; /*!< FLASH data */ +}; + +/* Flash Status */ +static ARM_FLASH_STATUS FlashStatus = {0, 0, 0}; + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_FLASH_API_VERSION, + ARM_FLASH_DRV_VERSION +}; + +/* Driver Capabilities */ +static const ARM_FLASH_CAPABILITIES DriverCapabilities = { + 0, /* event_ready */ + 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + 1 /* erase_chip */ +}; + +static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + uint32_t flash_limit = 0; + int32_t rc = 0; + + flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size) + - 1; + + if (offset > flash_limit) { + rc = -1; + } + return rc; +} + +static int32_t is_write_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t param) +{ + int32_t rc = 0; + + if ((param % flash_dev->data->program_unit) != 0) { + rc = -1; + } + return rc; +} + +static int32_t is_sector_aligned(struct arm_flash_dev_t *flash_dev, + uint32_t offset) +{ + int32_t rc = 0; + + if ((offset % flash_dev->data->sector_size) != 0) { + rc = -1; + } + return rc; +} + +static int32_t is_flash_ready_to_write(const uint8_t *start_addr, uint32_t cnt) +{ + int32_t rc = 0; + uint32_t i; + + for (i = 0; i < cnt; i++) { + if(start_addr[i] != ARM_FLASH_DRV_ERASE_VALUE) { + rc = -1; + break; + } + } + + return rc; +} + +#if (RTE_FLASH0) +static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = { + .sector_info = NULL, /* Uniform sector layout */ + .sector_count = FLASH0_SIZE / FLASH0_SECTOR_SIZE, + .sector_size = FLASH0_SECTOR_SIZE, + .page_size = FLASH0_PAGE_SIZE, + .program_unit = FLASH0_PROGRAM_UNIT, + .erased_value = ARM_FLASH_DRV_ERASE_VALUE}; + +static struct arm_flash_dev_t ARM_FLASH0_DEV = { +#if (__DOMAIN_NS == 1) + .memory_base = FLASH0_BASE_NS, +#else + .memory_base = FLASH0_BASE_S, +#endif /* __DOMAIN_NS == 1 */ + .data = &(ARM_FLASH0_DEV_DATA)}; + +struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV; + +/* + * Functions + */ + +static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void) +{ + return DriverVersion; +} + +static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void) +{ + return DriverCapabilities; +} + +static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) +{ + ARG_UNUSED(cb_event); + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state) +{ + switch (state) { + case ARM_POWER_FULL: + /* Nothing to be done */ + return ARM_DRIVER_OK; + break; + + case ARM_POWER_OFF: + case ARM_POWER_LOW: + default: + return ARM_DRIVER_ERROR_UNSUPPORTED; + } +} + +static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy(data, (void *)start_addr, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, + uint32_t cnt) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + int32_t rc = 0; + + /* Check flash memory boundaries and alignment with minimal write size */ + rc = is_range_valid(FLASH0_DEV, addr + cnt); + rc |= is_write_aligned(FLASH0_DEV, addr); + rc |= is_write_aligned(FLASH0_DEV, cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Check if the flash area to write the data was erased previously */ + rc = is_flash_ready_to_write((const uint8_t*)start_addr, cnt); + if (rc != 0) { + return ARM_DRIVER_ERROR; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy((void *)start_addr, data, cnt); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseSector(uint32_t addr) +{ + uint32_t start_addr = FLASH0_DEV->memory_base + addr; + uint32_t rc = 0; + + rc = is_range_valid(FLASH0_DEV, addr); + rc |= is_sector_aligned(FLASH0_DEV, addr); + if (rc != 0) { + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)start_addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + return ARM_DRIVER_OK; +} + +static int32_t ARM_Flash_EraseChip(void) +{ + uint32_t i; + uint32_t addr = FLASH0_DEV->memory_base; + int32_t rc = ARM_DRIVER_ERROR_UNSUPPORTED; + + /* Check driver capability erase_chip bit */ + if (DriverCapabilities.erase_chip == 1) { + for (i = 0; i < FLASH0_DEV->data->sector_count; i++) { + /* Flash interface just emulated over SRAM, use memset */ + memset((void *)addr, + FLASH0_DEV->data->erased_value, + FLASH0_DEV->data->sector_size); + + addr += FLASH0_DEV->data->sector_size; + rc = ARM_DRIVER_OK; + } + } + return rc; +} + +static ARM_FLASH_STATUS ARM_Flash_GetStatus(void) +{ + return FlashStatus; +} + +static ARM_FLASH_INFO * ARM_Flash_GetInfo(void) +{ + return FLASH0_DEV->data; +} + +ARM_DRIVER_FLASH Driver_FLASH0 = { + ARM_Flash_GetVersion, + ARM_Flash_GetCapabilities, + ARM_Flash_Initialize, + ARM_Flash_Uninitialize, + ARM_Flash_PowerControl, + ARM_Flash_ReadData, + ARM_Flash_ProgramData, + ARM_Flash_EraseSector, + ARM_Flash_EraseChip, + ARM_Flash_GetStatus, + ARM_Flash_GetInfo +}; +#endif /* RTE_FLASH0 */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.c b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.c new file mode 100644 index 0000000000..c16cc4aa0a --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.c @@ -0,0 +1,1305 @@ +/* + * Copyright (c) 2019-2020 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 "Driver_SSE300_PPC.h" + +#include "Driver_Common.h" +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" +#include "ppc_sse300_drv.h" + +/* Driver version */ +#define ARM_PPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_PPC_API_VERSION, + ARM_PPC_DRV_VERSION +}; + +ARM_DRIVER_VERSION PPC_SSE300_GetVersion(void) +{ + return DriverVersion; +} + +typedef struct _SSE300_PPC_Resources { + struct ppc_sse300_dev_t* dev; /* PPC device structure */ +} SSE300_PPC_Resources; + +#if (RTE_PPC_SSE300_MAIN0) + +static SSE300_PPC_Resources MAIN0_PPC_DEV = { + .dev = &PPC_SSE300_MAIN0_DEV, +}; + +/* MAIN0 PPC Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN0_Initialize(void) +{ + ppc_sse300_init(MAIN0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_MAIN0_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_MAIN0_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN0_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN0_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN0_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN0_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN0 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN0_Initialize, + .Uninitialize = PPC_SSE300_MAIN0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN0_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN0 */ + +#if (RTE_PPC_SSE300_MAIN_EXP0) + +static SSE300_PPC_Resources MAIN_EXP0_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP0_DEV, +}; + +/* MAIN PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP0_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_MAIN_EXP0_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_MAIN_EXP0_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP0_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP0_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP0_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP0_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP0 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP0_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP0 */ + +#if (RTE_PPC_SSE300_MAIN_EXP1) + +static SSE300_PPC_Resources MAIN_EXP1_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP1_DEV, +}; + +/* MAIN PPCEXP1 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP1_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_MAIN_EXP1_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_MAIN_EXP1_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP1_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP1_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP1_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP1_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP1 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP1_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP1_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP1_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP1 */ + +#if (RTE_PPC_SSE300_MAIN_EXP2) + +static SSE300_PPC_Resources MAIN_EXP2_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP2_DEV, +}; + +/* MAIN PPCEXP2 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP2_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP2_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP2_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_MAIN_EXP2_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP2_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP2_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP2_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_MAIN_EXP2_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP2_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP2_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP2_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP2_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP2_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP2_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP2_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP2_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP2_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP2_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP2_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP2 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP2 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP2_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP2_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP2_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP2_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP2_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP2_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP2_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP2_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP2_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP2_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP2 */ + +#if (RTE_PPC_SSE300_MAIN_EXP3) + +static SSE300_PPC_Resources MAIN_EXP3_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP3_DEV, +}; + +/* MAIN PPCEXP3 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP3_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP3_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP3_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_MAIN_EXP3_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP3_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP3_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP3_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_MAIN_EXP3_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP3_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP3_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP3_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP3_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP3_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP3_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP3_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP3_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP3_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP3_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP3_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP3 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP3 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP3_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP3_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP3_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP3_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP3_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP3_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP3_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP3_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP3_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP3_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP3 */ + +#if (RTE_PPC_SSE300_PERIPH0) + +static SSE300_PPC_Resources PERIPH0_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH0_DEV, +}; + +/* PERIPH0 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH0_Initialize(void) +{ + ppc_sse300_init(PERIPH0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH0_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH0_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH0_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH0_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH0_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH0_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH0 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH0_Initialize, + .Uninitialize = PPC_SSE300_PERIPH0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH0_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH0 */ + +#if (RTE_PPC_SSE300_PERIPH1) + +static SSE300_PPC_Resources PERIPH1_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH1_DEV, +}; + +/* PERIPH1 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH1_Initialize(void) +{ + ppc_sse300_init(PERIPH1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH1_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH1_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH1_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH1_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH1_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH1_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH1 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH1_Initialize, + .Uninitialize = PPC_SSE300_PERIPH1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH1_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH1_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH1 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP0) + +static SSE300_PPC_Resources PERIPH_EXP0_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP0_DEV, +}; + +/* PERIPH PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP0_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH_EXP0_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH_EXP0_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP0_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP0_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP0_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP0_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP0_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP0 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP0_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP0 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP1) + +static SSE300_PPC_Resources PERIPH_EXP1_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP1_DEV, +}; + +/* PERIPH PPCEXP1 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP1_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH_EXP1_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH_EXP1_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP1_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP1_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP1_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP1_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP1_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP1 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP1_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP1_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP1_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP1 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP2) + +static SSE300_PPC_Resources PERIPH_EXP2_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP2_DEV, +}; + +/* PERIPH PPCEXP2 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP2_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP2_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP2_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH_EXP2_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP2_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP2_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP2_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH_EXP2_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP2_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP2_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP2_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP2_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP2_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP2_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP2_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP2_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP2_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP2_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP2_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP2 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP2 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP2_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP2_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP2_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP2_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP2_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP2_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP2_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP2_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP2_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP2_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP2 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP3) + +static SSE300_PPC_Resources PERIPH_EXP3_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP3_DEV, +}; + +/* PERIPH PPCEXP3 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP3_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP3_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP3_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t +PPC_SSE300_PERIPH_EXP3_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP3_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr, + (enum ppc_sse300_priv_attr_t)priv_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP3_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP3_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE300_PERIPH_EXP3_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP3_PPC_DEV.dev, periph, + (enum ppc_sse300_sec_attr_t)sec_attr); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP3_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP3_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP3_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP3_PPC_DEV.dev); + + if( ret != PPC_SSE300_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP3_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP3_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP3_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP3_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP3_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP3_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP3 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP3 = { + .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP3_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP3_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP3_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP3_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP3_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP3_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP3_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP3_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP3_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP3_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP3 */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.h b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.h new file mode 100644 index 0000000000..c07fed07f4 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019-2020 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 __PPC_SSE300_DRIVER_H__ +#define __PPC_SSE300_DRIVER_H__ + +#include "Driver_Common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* API version */ +#define ARM_PPC_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) + +/* Security attribute used to configure the peripheral */ +typedef enum _PPC_SSE300_SecAttr { + PPC_SSE300_SECURE_CONFIG = 0, /*!< Secure access */ + PPC_SSE300_NONSECURE_CONFIG, /*!< Non-secure access */ +} PPC_SSE300_SecAttr; + +/* Privilege attribute used to configure the peripheral */ +typedef enum _PPC_SSE300_PrivAttr { + PPC_SSE300_PRIV_AND_NONPRIV_CONFIG = 0, /*!< Privilege and non-privilege + * access */ + PPC_SSE300_PRIV_CONFIG, /*!< Privilege only access */ +} PPC_SSE300_PrivAttr; + +/* Function descriptions */ +/** + SACFG - Secure Privilege Control Block + NSACFG - Non-Secure Privilege Control Block + + \fn ARM_DRIVER_VERSION PPC_SSE300_GetVersion(void) + \brief Get driver version. + \return \ref ARM_DRIVER_VERSION + + \fn int32_t PPC_SSE300_Initialize(void) + \brief Initializes PPC Interface. + \return Returns SSE-300 PPC error code. + + \fn int32_t PPC_SSE300_Uninitialize(void) + \brief De-initializes PPC Interface. + \return Returns SSE-300 PPC error code. + + \fn int32_t PPC_SSE300_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) + \brief Configures privilege level with privileged and unprivileged + access or privileged access only in the given security domain + for a peripheral controlled by the given PPC. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \param[in] sec_attr: Specifies Secure or Non Secure domain. + \param[in] priv_attr: Privilege attribute value to set. + \return Returns SSE-300 PPC error code. + + \fn bool PPC_SSE300_IsPeriphPrivOnly (uint32_t periph) + \brief Checks if the peripheral is configured to be privilege only + - with non-secure caller in the non-secure domain + - with secure caller in the configured security domain + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \return Returns true if the peripheral is configured as privilege access + only, false for privilege and unprivilege access mode. + + Secure only functions: + + \fn int32_t PPC_SSE300_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) + \brief Configures security level for a peripheral controlled by the + given PPC with secure or non-secure access only. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \param[in] sec_attr: Secure attribute value to set. + \return Returns SSE-300 PPC error code. + + \fn bool PPC_SSE300_IsPeriphSecure (uint32_t periph) + \brief Checks if the peripheral is configured to be secure. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \return Returns true if the peripheral is configured as secure, + false for non-secure. + + \fn int32_t PPC_SSE300_EnableInterrupt (void) + \brief Enables PPC interrupt. + \return Returns SSE-300 PPC error code. + + \fn void PPC_SSE300_DisableInterrupt (void) + \brief Disables PPC interrupt. + + \fn void PPC_SSE300_ClearInterrupt (void) + \brief Clears PPC interrupt. + + \fn bool PPC_SSE300_InterruptState (void) + \brief Gets PPC interrupt state. + \return Returns true if the interrupt is active, false otherwise. +*/ + +/** + * \brief Access structure of the PPC Driver. + */ +typedef struct _DRIVER_PPC_SSE300 { + ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_PPC_GetVersion : Get driver version. + int32_t (*Initialize) (void); ///< Pointer to \ref ARM_PPC_Initialize : Initialize the PPC Interface. + int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_PPC_Uninitialize : De-initialize the PPC Interface. + int32_t (*ConfigPrivilege) (uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr); ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC. + bool (*IsPeriphPrivOnly) (uint32_t periph); ///< Pointer to \ref IsPeriphPrivOnly : Check if the peripheral is configured to be privilege only. +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + int32_t (*ConfigSecurity) (uint32_t periph, PPC_SSE300_SecAttr sec_attr); ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC. + bool (*IsPeriphSecure) (uint32_t periph); ///< Pointer to \ref IsPeriphSecure : Check if the peripheral is configured to be secure. + int32_t (*EnableInterrupt) (void); ///< Pointer to \ref ARM_PPC_EnableInterrupt : Enable PPC interrupt. + void (*DisableInterrupt) (void); ///< Pointer to \ref ARM_PPC_DisableInterrupt : Disable PPC interrupt. + void (*ClearInterrupt) (void); ///< Pointer to \ref ARM_PPC_ClearInterrupt : Clear PPC interrupt. + bool (*InterruptState) (void); ///< Pointer to \ref ARM_PPC_InterruptState : PPC interrupt State. +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +} const DRIVER_PPC_SSE300; + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE300_DRIVER_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_USART.c b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_USART.c new file mode 100644 index 0000000000..cb3a14ad3e --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/Driver_USART.c @@ -0,0 +1,700 @@ +/* + * Copyright (c) 2013-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "Driver_USART.h" + +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) (void)arg +#endif + +/* Driver version */ +#define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { + ARM_USART_API_VERSION, + ARM_USART_DRV_VERSION +}; + +/* Driver Capabilities */ +static const ARM_USART_CAPABILITIES DriverCapabilities = { + 1, /* supports UART (Asynchronous) mode */ + 0, /* supports Synchronous Master mode */ + 0, /* supports Synchronous Slave mode */ + 0, /* supports UART Single-wire mode */ + 0, /* supports UART IrDA mode */ + 0, /* supports UART Smart Card mode */ + 0, /* Smart Card Clock generator available */ + 0, /* RTS Flow Control available */ + 0, /* CTS Flow Control available */ + 0, /* Transmit completed event: \ref ARM_USARTx_EVENT_TX_COMPLETE */ + 0, /* Signal receive character timeout event: \ref ARM_USARTx_EVENT_RX_TIMEOUT */ + 0, /* RTS Line: 0=not available, 1=available */ + 0, /* CTS Line: 0=not available, 1=available */ + 0, /* DTR Line: 0=not available, 1=available */ + 0, /* DSR Line: 0=not available, 1=available */ + 0, /* DCD Line: 0=not available, 1=available */ + 0, /* RI Line: 0=not available, 1=available */ + 0, /* Signal CTS change event: \ref ARM_USARTx_EVENT_CTS */ + 0, /* Signal DSR change event: \ref ARM_USARTx_EVENT_DSR */ + 0, /* Signal DCD change event: \ref ARM_USARTx_EVENT_DCD */ + 0, /* Signal RI change event: \ref ARM_USARTx_EVENT_RI */ + 0 /* Reserved */ +}; + +static ARM_DRIVER_VERSION ARM_USART_GetVersion(void) +{ + return DriverVersion; +} + +static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void) +{ + return DriverCapabilities; +} + +typedef struct { + struct uart_cmsdk_dev_t *dev; /* UART device structure */ + uint32_t tx_nbr_bytes; /* Number of bytes transfered */ + uint32_t rx_nbr_bytes; /* Number of bytes recevied */ + ARM_USART_SignalEvent_t cb_event; /* Callback function for events */ +} UARTx_Resources; + +static int32_t ARM_USARTx_Initialize(UARTx_Resources *uart_dev) +{ + /* Initializes generic UART driver */ + uart_cmsdk_init(uart_dev->dev, PeripheralClock); + + return ARM_DRIVER_OK; +} + +static int32_t ARM_USARTx_PowerControl(UARTx_Resources *uart_dev, + ARM_POWER_STATE state) +{ + ARG_UNUSED(uart_dev); + + switch (state) { + case ARM_POWER_OFF: + case ARM_POWER_LOW: + return ARM_DRIVER_ERROR_UNSUPPORTED; + case ARM_POWER_FULL: + /* Nothing to be done */ + return ARM_DRIVER_OK; + /* default: The default is not defined intentionally to force the + * compiler to check that all the enumeration values are + * covered in the switch.*/ + } +} + +static int32_t ARM_USARTx_Send(UARTx_Resources *uart_dev, const void *data, + uint32_t num) +{ + const uint8_t *p_data = (const uint8_t *)data; + + if ((data == NULL) || (num == 0U)) { + /* Invalid parameters */ + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Resets previous TX counter */ + uart_dev->tx_nbr_bytes = 0; + + while (uart_dev->tx_nbr_bytes != num) { + /* Waits until UART is ready to transmit */ + while (!uart_cmsdk_tx_ready(uart_dev->dev)) { + }; + + /* As UART is ready to transmit at this point, the write function can + * not return any transmit error */ + (void)uart_cmsdk_write(uart_dev->dev, *p_data); + + uart_dev->tx_nbr_bytes++; + p_data++; + } + + /* Waits until character is transmited */ + while (!uart_cmsdk_tx_ready(uart_dev->dev)) { + }; + + return ARM_DRIVER_OK; +} + +static int32_t ARM_USARTx_Receive(UARTx_Resources *uart_dev, + void *data, uint32_t num) +{ + uint8_t *p_data = (uint8_t *)data; + + if ((data == NULL) || (num == 0U)) { + // Invalid parameters + return ARM_DRIVER_ERROR_PARAMETER; + } + + /* Resets previous RX counter */ + uart_dev->rx_nbr_bytes = 0; + + while (uart_dev->rx_nbr_bytes != num) { + /* Waits until one character is received */ + while (!uart_cmsdk_rx_ready(uart_dev->dev)){}; + + /* As UART has received one byte, the read can not + * return any receive error at this point */ + (void)uart_cmsdk_read(uart_dev->dev, p_data); + + uart_dev->rx_nbr_bytes++; + p_data++; + } + + return ARM_DRIVER_OK; +} + +static uint32_t ARM_USARTx_GetTxCount(UARTx_Resources *uart_dev) +{ + return uart_dev->tx_nbr_bytes; +} + +static uint32_t ARM_USARTx_GetRxCount(UARTx_Resources *uart_dev) +{ + return uart_dev->rx_nbr_bytes; +} + +static int32_t ARM_USARTx_Control(UARTx_Resources *uart_dev, uint32_t control, + uint32_t arg) +{ + switch (control & ARM_USART_CONTROL_Msk) { + case ARM_USART_MODE_ASYNCHRONOUS: + if (uart_cmsdk_set_baudrate(uart_dev->dev, arg) != UART_CMSDK_ERR_NONE) { + return ARM_USART_ERROR_BAUDRATE; + } + break; + /* Unsupported command */ + default: + return ARM_DRIVER_ERROR_UNSUPPORTED; + } + + /* UART Data bits */ + if (control & ARM_USART_DATA_BITS_Msk) { + /* Data bit is not configurable */ + return ARM_DRIVER_ERROR_UNSUPPORTED; + } + + /* UART Parity */ + if (control & ARM_USART_PARITY_Msk) { + /* Parity is not configurable */ + return ARM_USART_ERROR_PARITY; + } + + /* USART Stop bits */ + if (control & ARM_USART_STOP_BITS_Msk) { + /* Stop bit is not configurable */ + return ARM_USART_ERROR_STOP_BITS; + } + + return ARM_DRIVER_OK; +} + +#if (RTE_USART0) +/* USART0 Driver wrapper functions */ +static UARTx_Resources USART0_DEV = { + .dev = &UART0_CMSDK_DEV, + .tx_nbr_bytes = 0, + .rx_nbr_bytes = 0, + .cb_event = NULL, +}; + +static int32_t ARM_USART0_Initialize(ARM_USART_SignalEvent_t cb_event) +{ + USART0_DEV.cb_event = cb_event; + + return ARM_USARTx_Initialize(&USART0_DEV); +} + +static int32_t ARM_USART0_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_USART0_PowerControl(ARM_POWER_STATE state) +{ + return ARM_USARTx_PowerControl(&USART0_DEV, state); +} + +static int32_t ARM_USART0_Send(const void *data, uint32_t num) +{ + return ARM_USARTx_Send(&USART0_DEV, data, num); +} + +static int32_t ARM_USART0_Receive(void *data, uint32_t num) +{ + return ARM_USARTx_Receive(&USART0_DEV, data, num); +} + +static int32_t ARM_USART0_Transfer(const void *data_out, void *data_in, + uint32_t num) +{ + ARG_UNUSED(data_out); + ARG_UNUSED(data_in); + ARG_UNUSED(num); + + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static uint32_t ARM_USART0_GetTxCount(void) +{ + return ARM_USARTx_GetTxCount(&USART0_DEV); +} + +static uint32_t ARM_USART0_GetRxCount(void) +{ + return ARM_USARTx_GetRxCount(&USART0_DEV); +} +static int32_t ARM_USART0_Control(uint32_t control, uint32_t arg) +{ + return ARM_USARTx_Control(&USART0_DEV, control, arg); +} + +static ARM_USART_STATUS ARM_USART0_GetStatus(void) +{ + ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; + return status; +} + +static int32_t ARM_USART0_SetModemControl(ARM_USART_MODEM_CONTROL control) +{ + ARG_UNUSED(control); + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static ARM_USART_MODEM_STATUS ARM_USART0_GetModemStatus(void) +{ + ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; + return modem_status; +} + +extern ARM_DRIVER_USART Driver_USART0; +ARM_DRIVER_USART Driver_USART0 = { + ARM_USART_GetVersion, + ARM_USART_GetCapabilities, + ARM_USART0_Initialize, + ARM_USART0_Uninitialize, + ARM_USART0_PowerControl, + ARM_USART0_Send, + ARM_USART0_Receive, + ARM_USART0_Transfer, + ARM_USART0_GetTxCount, + ARM_USART0_GetRxCount, + ARM_USART0_Control, + ARM_USART0_GetStatus, + ARM_USART0_SetModemControl, + ARM_USART0_GetModemStatus +}; +#endif /* RTE_USART0 */ + +#if (RTE_USART1) +/* USART1 Driver wrapper functions */ +static UARTx_Resources USART1_DEV = { + .dev = &UART1_CMSDK_DEV, + .tx_nbr_bytes = 0, + .rx_nbr_bytes = 0, + .cb_event = NULL, +}; + +static int32_t ARM_USART1_Initialize(ARM_USART_SignalEvent_t cb_event) +{ + USART1_DEV.cb_event = cb_event; + + return ARM_USARTx_Initialize(&USART1_DEV); +} + +static int32_t ARM_USART1_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_USART1_PowerControl(ARM_POWER_STATE state) +{ + return ARM_USARTx_PowerControl(&USART1_DEV, state); +} + +static int32_t ARM_USART1_Send(const void *data, uint32_t num) +{ + return ARM_USARTx_Send(&USART1_DEV, data, num); +} + +static int32_t ARM_USART1_Receive(void *data, uint32_t num) +{ + return ARM_USARTx_Receive(&USART1_DEV, data, num); +} + +static int32_t ARM_USART1_Transfer(const void *data_out, void *data_in, + uint32_t num) +{ + ARG_UNUSED(data_out); + ARG_UNUSED(data_in); + ARG_UNUSED(num); + + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static uint32_t ARM_USART1_GetTxCount(void) +{ + return ARM_USARTx_GetTxCount(&USART1_DEV); +} + +static uint32_t ARM_USART1_GetRxCount(void) +{ + return ARM_USARTx_GetRxCount(&USART1_DEV); +} +static int32_t ARM_USART1_Control(uint32_t control, uint32_t arg) +{ + return ARM_USARTx_Control(&USART1_DEV, control, arg); +} + +static ARM_USART_STATUS ARM_USART1_GetStatus(void) +{ + ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; + return status; +} + +static int32_t ARM_USART1_SetModemControl(ARM_USART_MODEM_CONTROL control) +{ + ARG_UNUSED(control); + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static ARM_USART_MODEM_STATUS ARM_USART1_GetModemStatus(void) +{ + ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; + return modem_status; +} + +extern ARM_DRIVER_USART Driver_USART1; +ARM_DRIVER_USART Driver_USART1 = { + ARM_USART_GetVersion, + ARM_USART_GetCapabilities, + ARM_USART1_Initialize, + ARM_USART1_Uninitialize, + ARM_USART1_PowerControl, + ARM_USART1_Send, + ARM_USART1_Receive, + ARM_USART1_Transfer, + ARM_USART1_GetTxCount, + ARM_USART1_GetRxCount, + ARM_USART1_Control, + ARM_USART1_GetStatus, + ARM_USART1_SetModemControl, + ARM_USART1_GetModemStatus +}; +#endif /* RTE_USART1 */ + +#if (RTE_USART2) +/* USART2 Driver wrapper functions */ +static UARTx_Resources USART2_DEV = { + .dev = &UART2_CMSDK_DEV, + .tx_nbr_bytes = 0, + .rx_nbr_bytes = 0, + .cb_event = NULL, +}; + +static int32_t ARM_USART2_Initialize(ARM_USART_SignalEvent_t cb_event) +{ + USART2_DEV.cb_event = cb_event; + + return ARM_USARTx_Initialize(&USART2_DEV); +} + +static int32_t ARM_USART2_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_USART2_PowerControl(ARM_POWER_STATE state) +{ + return ARM_USARTx_PowerControl(&USART2_DEV, state); +} + +static int32_t ARM_USART2_Send(const void *data, uint32_t num) +{ + return ARM_USARTx_Send(&USART2_DEV, data, num); +} + +static int32_t ARM_USART2_Receive(void *data, uint32_t num) +{ + return ARM_USARTx_Receive(&USART2_DEV, data, num); +} + +static int32_t ARM_USART2_Transfer(const void *data_out, void *data_in, + uint32_t num) +{ + ARG_UNUSED(data_out); + ARG_UNUSED(data_in); + ARG_UNUSED(num); + + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static uint32_t ARM_USART2_GetTxCount(void) +{ + return ARM_USARTx_GetTxCount(&USART2_DEV); +} + +static uint32_t ARM_USART2_GetRxCount(void) +{ + return ARM_USARTx_GetRxCount(&USART2_DEV); +} +static int32_t ARM_USART2_Control(uint32_t control, uint32_t arg) +{ + return ARM_USARTx_Control(&USART2_DEV, control, arg); +} + +static ARM_USART_STATUS ARM_USART2_GetStatus(void) +{ + ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; + return status; +} + +static int32_t ARM_USART2_SetModemControl(ARM_USART_MODEM_CONTROL control) +{ + ARG_UNUSED(control); + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static ARM_USART_MODEM_STATUS ARM_USART2_GetModemStatus(void) +{ + ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; + return modem_status; +} + +extern ARM_DRIVER_USART Driver_USART2; +ARM_DRIVER_USART Driver_USART2 = { + ARM_USART_GetVersion, + ARM_USART_GetCapabilities, + ARM_USART2_Initialize, + ARM_USART2_Uninitialize, + ARM_USART2_PowerControl, + ARM_USART2_Send, + ARM_USART2_Receive, + ARM_USART2_Transfer, + ARM_USART2_GetTxCount, + ARM_USART2_GetRxCount, + ARM_USART2_Control, + ARM_USART2_GetStatus, + ARM_USART2_SetModemControl, + ARM_USART2_GetModemStatus +}; +#endif /* RTE_USART2 */ + +#if (RTE_USART3) +/* USART3 Driver wrapper functions */ +static UARTx_Resources USART3_DEV = { + .dev = &UART3_CMSDK_DEV, + .tx_nbr_bytes = 0, + .rx_nbr_bytes = 0, + .cb_event = NULL, +}; + +static int32_t ARM_USART3_Initialize(ARM_USART_SignalEvent_t cb_event) +{ + USART3_DEV.cb_event = cb_event; + + return ARM_USARTx_Initialize(&USART3_DEV); +} + +static int32_t ARM_USART3_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_USART3_PowerControl(ARM_POWER_STATE state) +{ + return ARM_USARTx_PowerControl(&USART3_DEV, state); +} + +static int32_t ARM_USART3_Send(const void *data, uint32_t num) +{ + return ARM_USARTx_Send(&USART3_DEV, data, num); +} + +static int32_t ARM_USART3_Receive(void *data, uint32_t num) +{ + return ARM_USARTx_Receive(&USART3_DEV, data, num); +} + +static int32_t ARM_USART3_Transfer(const void *data_out, void *data_in, + uint32_t num) +{ + ARG_UNUSED(data_out); + ARG_UNUSED(data_in); + ARG_UNUSED(num); + + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static uint32_t ARM_USART3_GetTxCount(void) +{ + return ARM_USARTx_GetTxCount(&USART3_DEV); +} + +static uint32_t ARM_USART3_GetRxCount(void) +{ + return ARM_USARTx_GetRxCount(&USART3_DEV); +} +static int32_t ARM_USART3_Control(uint32_t control, uint32_t arg) +{ + return ARM_USARTx_Control(&USART3_DEV, control, arg); +} + +static ARM_USART_STATUS ARM_USART3_GetStatus(void) +{ + ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; + return status; +} + +static int32_t ARM_USART3_SetModemControl(ARM_USART_MODEM_CONTROL control) +{ + ARG_UNUSED(control); + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static ARM_USART_MODEM_STATUS ARM_USART3_GetModemStatus(void) +{ + ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; + return modem_status; +} + +extern ARM_DRIVER_USART Driver_USART3; +ARM_DRIVER_USART Driver_USART3 = { + ARM_USART_GetVersion, + ARM_USART_GetCapabilities, + ARM_USART3_Initialize, + ARM_USART3_Uninitialize, + ARM_USART3_PowerControl, + ARM_USART3_Send, + ARM_USART3_Receive, + ARM_USART3_Transfer, + ARM_USART3_GetTxCount, + ARM_USART3_GetRxCount, + ARM_USART3_Control, + ARM_USART3_GetStatus, + ARM_USART3_SetModemControl, + ARM_USART3_GetModemStatus +}; +#endif /* RTE_USART3 */ + +#if (RTE_USART4) +/* USART4 Driver wrapper functions */ +static UARTx_Resources USART4_DEV = { + .dev = &UART4_CMSDK_DEV, + .tx_nbr_bytes = 0, + .rx_nbr_bytes = 0, + .cb_event = NULL, +}; + +static int32_t ARM_USART4_Initialize(ARM_USART_SignalEvent_t cb_event) +{ + USART4_DEV.cb_event = cb_event; + + return ARM_USARTx_Initialize(&USART4_DEV); +} + +static int32_t ARM_USART4_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ARM_USART4_PowerControl(ARM_POWER_STATE state) +{ + return ARM_USARTx_PowerControl(&USART4_DEV, state); +} + +static int32_t ARM_USART4_Send(const void *data, uint32_t num) +{ + return ARM_USARTx_Send(&USART4_DEV, data, num); +} + +static int32_t ARM_USART4_Receive(void *data, uint32_t num) +{ + return ARM_USARTx_Receive(&USART4_DEV, data, num); +} + +static int32_t ARM_USART4_Transfer(const void *data_out, void *data_in, + uint32_t num) +{ + ARG_UNUSED(data_out); + ARG_UNUSED(data_in); + ARG_UNUSED(num); + + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static uint32_t ARM_USART4_GetTxCount(void) +{ + return ARM_USARTx_GetTxCount(&USART4_DEV); +} + +static uint32_t ARM_USART4_GetRxCount(void) +{ + return ARM_USARTx_GetRxCount(&USART4_DEV); +} +static int32_t ARM_USART4_Control(uint32_t control, uint32_t arg) +{ + return ARM_USARTx_Control(&USART4_DEV, control, arg); +} + +static ARM_USART_STATUS ARM_USART4_GetStatus(void) +{ + ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; + return status; +} + +static int32_t ARM_USART4_SetModemControl(ARM_USART_MODEM_CONTROL control) +{ + ARG_UNUSED(control); + return ARM_DRIVER_ERROR_UNSUPPORTED; +} + +static ARM_USART_MODEM_STATUS ARM_USART4_GetModemStatus(void) +{ + ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; + return modem_status; +} + +extern ARM_DRIVER_USART Driver_USART4; +ARM_DRIVER_USART Driver_USART4 = { + ARM_USART_GetVersion, + ARM_USART_GetCapabilities, + ARM_USART4_Initialize, + ARM_USART4_Uninitialize, + ARM_USART4_PowerControl, + ARM_USART4_Send, + ARM_USART4_Receive, + ARM_USART4_Transfer, + ARM_USART4_GetTxCount, + ARM_USART4_GetRxCount, + ARM_USART4_Control, + ARM_USART4_GetStatus, + ARM_USART4_SetModemControl, + ARM_USART4_GetModemStatus +}; +#endif /* RTE_USART4 */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/RTE_Device.h b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/RTE_Device.h new file mode 100644 index 0000000000..9d9d1430e3 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/RTE_Device.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019-2020 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 __RTE_DEVICE_H +#define __RTE_DEVICE_H + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] +// <i> Configuration settings for Driver_USART0 in component ::Drivers:USART +#define RTE_USART0 1 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] +// <i> Configuration settings for Driver_USART1 in component ::Drivers:USART +#define RTE_USART1 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// <i> Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// <i> Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_ISRAM1_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_SRAM_MPC] +// <i> Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC +#define RTE_SRAM_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_SRAM_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_QSPI_MPC] +// <i> Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC +#define RTE_QSPI_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_QSPI_MPC] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN0] +// <i> Configuration settings for Driver_PPC_SSE300_MAIN0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN0] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP0] +// <i> Configuration settings for Driver_PPC_SSE300_MAIN_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP0] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP1] +// <i> Configuration settings for Driver_PPC_SSE300_MAIN_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP1 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP1] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH0] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH0] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH1] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH1 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH1] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP0] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP0] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP1] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP1 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP1] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP2] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP2 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP2] + +// <e> Flash device emulated by SRAM [Driver_Flash0] +// <i> Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 +// </e> Flash device emulated by SRAM [Driver_Flash0] + +#endif /* __RTE_DEVICE_H */ diff --git a/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h new file mode 100644 index 0000000000..edc4633a2d --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020 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 __CMSIS_DRIVER_CONFIG_H__ +#define __CMSIS_DRIVER_CONFIG_H__ + +#include "platform_description.h" +#include "device_definition.h" +#include "RTE_Device.h" + +#define UART0_CMSDK_DEV UART0_CMSDK_DEV_NS + +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S +#define MPC_ISRAM1_DEV MPC_ISRAM1_DEV_S +#define MPC_SRAM_DEV MPC_SRAM_DEV_S +#define MPC_QSPI_DEV MPC_QSPI_DEV_S + +#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S +#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S +#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S +#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S +#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S +#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S +#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S +#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S +#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S +#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S +#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/config.cmake b/platform/ext/target/mps3/fvp_sse300/config.cmake new file mode 100644 index 0000000000..a81c8a1137 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/config.cmake @@ -0,0 +1,6 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- diff --git a/platform/ext/target/mps3/fvp_sse300/device/config/device_cfg.h b/platform/ext/target/mps3/fvp_sse300/device/config/device_cfg.h new file mode 100644 index 0000000000..33a2b90a70 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/config/device_cfg.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2019-2020 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__ + +/** + * \file device_cfg.h + * \brief + * This is the device configuration file with only used peripherals + * defined and configured via the secure and/or non-secure base address. + */ + +/* ARM Memory Protection Controller (MPC) */ +#define MPC_ISRAM0_S +#define MPC_ISRAM1_S +#define MPC_SRAM_S +#define MPC_QSPI_S + +/* ARM Peripheral Protection Controllers (PPC) */ +#define PPC_SSE300_MAIN0_S +#define PPC_SSE300_MAIN_EXP0_S +#define PPC_SSE300_MAIN_EXP1_S +#define PPC_SSE300_MAIN_EXP2_S +#define PPC_SSE300_MAIN_EXP3_S +#define PPC_SSE300_PERIPH0_S +#define PPC_SSE300_PERIPH1_S +#define PPC_SSE300_PERIPH_EXP0_S +#define PPC_SSE300_PERIPH_EXP1_S +#define PPC_SSE300_PERIPH_EXP2_S +#define PPC_SSE300_PERIPH_EXP3_S + +/* ARM UART CMSDK */ +#define DEFAULT_UART_BAUDRATE 115200 +#define UART0_CMSDK_NS + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S +#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_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 + + +/* System Timer Armv8-M */ +#define SYSTIMER0_ARMV8_M_S +#define SYSTIMER1_ARMV8_M_NS + +#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) + +#endif /* __DEVICE_CFG_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/cmsis.h b/platform/ext/target/mps3/fvp_sse300/device/include/cmsis.h new file mode 100644 index 0000000000..dbd93f43d8 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/cmsis.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019-2020 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 __CMSIS_H__ +#define __CMSIS_H__ + +/* ====================== Start of section using anonymous unions ============== */ +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* ======== Configuration of Core Peripherals ================================== */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __FPU_DP 1U /* double precision FPU */ +#define __DSP_PRESENT 1U /* DSP extension present */ +#define __MVE_PRESENT 1U /* MVE extensions present */ +#define __MVE_FP 1U /* MVE floating point present */ + +#include "platform_description.h" +#include "platform_irq.h" +#include "core_armv81mml.h" /* Processor and core peripherals */ + +/* ===================== End of section using anonymous unions ================ */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + +#endif /* __CMSIS_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/device_definition.h b/platform/ext/target/mps3/fvp_sse300/device/include/device_definition.h new file mode 100644 index 0000000000..cd93365295 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/device_definition.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +/** + * \file device_definition.h + * \brief The structure definitions in this file are exported based on the + * peripheral definitions from device_cfg.h. + * This file is meant to be used as a helper for baremetal + * applications and/or as an example of how to configure the generic + * driver structures. + */ + +#ifndef __DEVICE_DEFINITION_H__ +#define __DEVICE_DEFINITION_H__ + +#include "device_cfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ======= Defines peripheral configuration structures ======= */ +/* UART CMSDK driver structures */ +#ifdef UART0_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_S; +#endif +#ifdef UART0_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS; +#endif + +#ifdef UART1_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART1_DEV_S; +#endif +#ifdef UART1_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART1_DEV_NS; +#endif + +#ifdef UART2_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART2_DEV_S; +#endif +#ifdef UART2_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART2_DEV_NS; +#endif + +#ifdef UART3_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART3_DEV_S; +#endif +#ifdef UART3_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART3_DEV_NS; +#endif + +#ifdef UART4_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART4_DEV_S; +#endif +#ifdef UART4_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART4_DEV_NS; +#endif + +#ifdef UART5_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART5_DEV_S; +#endif +#ifdef UART5_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART5_DEV_NS; +#endif + +/* ARM PPC driver structures */ +#ifdef PPC_SSE300_MAIN0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN0_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP1_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP2_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP2_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP3_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP3_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH0_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH1_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP1_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP2_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP2_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP3_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP3_DEV_S; +#endif + +/* System counters */ +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S +#include "syscounter_armv8-m_cntrl_drv.h" +extern struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS; +#endif + +/* System timers */ +#ifdef SYSTIMER0_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER0_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER1_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER1_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER2_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER2_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER3_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER3_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS; +#endif + +/* System Watchdogs */ +#ifdef SYSWDOG_ARMV8_M_S +#include "syswdog_armv8-m_drv.h" +extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S; +#endif +#ifdef SYSWDOG_ARMV8_M_NS +#include "syswdog_armv8-m_drv.h" +extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS; +#endif + +/* ARM MPC SIE 300 driver structures */ +#ifdef MPC_SRAM_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_SRAM_DEV_S; +#endif + +#ifdef MPC_QSPI_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_QSPI_DEV_S; +#endif + +#ifdef MPC_DDR4_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_DDR4_DEV_S; +#endif + +#ifdef MPC_ISRAM0_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_ISRAM0_DEV_S; +#endif + +#ifdef MPC_ISRAM1_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_ISRAM1_DEV_S; +#endif + +#ifdef MPS3_IO_S +#include "arm_mps3_io_drv.h" +extern struct arm_mps3_io_dev_t MPS3_IO_DEV_S; +#endif + +#ifdef MPS3_IO_NS +#include "arm_mps3_io_drv.h" +extern struct arm_mps3_io_dev_t MPS3_IO_DEV_NS; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __DEVICE_DEFINITION_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/platform_description.h b/platform/ext/target/mps3/fvp_sse300/device/include/platform_description.h new file mode 100644 index 0000000000..8ec0197d32 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/platform_description.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2020 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 __PLATFORM_DESCRIPTION_H__ +#define __PLATFORM_DESCRIPTION_H__ + +#include "cmsis.h" +#include "platform_base_address.h" +#include "platform_regs.h" +#include "system_core_init.h" + +#endif /* __PLATFORM_DESCRIPTION_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/platform_irq.h b/platform/ext/target/mps3/fvp_sse300/device/include/platform_irq.h new file mode 100644 index 0000000000..8a64ea7382 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/platform_irq.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019-2020 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 __PLATFORM_IRQ_H__ +#define __PLATFORM_IRQ_H__ + +typedef enum _IRQn_Type { + NonMaskableInt_IRQn = -14, /* Non Maskable Interrupt */ + HardFault_IRQn = -13, /* HardFault Interrupt */ + MemoryManagement_IRQn = -12, /* Memory Management Interrupt */ + BusFault_IRQn = -11, /* Bus Fault Interrupt */ + UsageFault_IRQn = -10, /* Usage Fault Interrupt */ + SecureFault_IRQn = -9, /* Secure Fault Interrupt */ + SVCall_IRQn = -5, /* SV Call Interrupt */ + DebugMonitor_IRQn = -4, /* Debug Monitor Interrupt */ + PendSV_IRQn = -2, /* Pend SV Interrupt */ + SysTick_IRQn = -1, /* System Tick Interrupt */ + NONSEC_WATCHDOG_RESET_IRQn = 0, /* Non-Secure Watchdog Reset + * Interrupt + */ + NONSEC_WATCHDOG_IRQn = 1, /* Non-Secure Watchdog Interrupt */ + S32K_TIMER_IRQn = 2, /* S32K Timer Interrupt */ + TIMER0_IRQn = 3, /* TIMER 0 Interrupt */ + TIMER1_IRQn = 4, /* TIMER 1 Interrupt */ + DUALTIMER_IRQn = 5, /* Dual Timer Interrupt */ + MHU0_IRQn = 6, /* Message Handling Unit 0 */ + MHU1_IRQn = 7, /* Message Handling Unit 1 */ + MPC_IRQn = 9, /* MPC Combined (Secure) Interrupt */ + PPC_IRQn = 10, /* PPC Combined (Secure) Interrupt */ + MSC_IRQn = 11, /* MSC Combined (Secure) Interrput */ + BRIDGE_ERROR_IRQn = 12, /* Bridge Error Combined + * (Secure) Interrupt + */ + INVALID_INSTR_CACHE_IRQn = 13, /* CPU Instruction Cache Invalidation + * Interrupt + */ + SYS_PPU_IRQn = 15, /* SYS PPU */ + CPU0_PPU_IRQn = 16, /* CPU0 PPU */ + CPU1_PPU_IRQn = 17, /* CPU1 PPU */ + CPU0_DBG_PPU_IRQn = 18, /* CPU0 DBG PPU */ + CPU1_DBG_PPU_IRQn = 19, /* CPU1 DBG PPU */ + /* Reserved = 20, Reserved */ + RAM0_PPU_IRQn = 22, /* RAM0 PPU */ + RAM1_PPU_IRQn = 23, /* RAM1 PPU */ + RAM2_PPU_IRQn = 24, /* RAM2 PPU */ + RAM3_PPU_IRQn = 25, /* RAM3 PPU */ + DEBUG_PPU_IRQn = 26, /* DEBUG PPU */ + CPUx_CTI_IRQ0 = 28, /* CPUx CTI 0 */ + CPUx_CTI_IRQ1 = 29, /* CPUx CTI 1 */ + /* Reserved = 30, Reserved */ + /* Reserved = 31, Reserved */ + System_Timestamp_Counter_IRQn = 32, /* System timestamp counter Interrupt */ + UARTRX0_IRQn = 33, /* UART 0 RX Interrupt */ + UARTTX0_IRQn = 34, /* UART 0 TX Interrupt */ + UARTRX1_IRQn = 35, /* UART 1 RX Interrupt */ + UARTTX1_IRQn = 36, /* UART 1 TX Interrupt */ + UARTRX2_IRQn = 37, /* UART 2 RX Interrupt */ + UARTTX2_IRQn = 38, /* UART 2 TX Interrupt */ + UARTRX3_IRQn = 39, /* UART 3 RX Interrupt */ + UARTTX3_IRQn = 40, /* UART 3 TX Interrupt */ + UARTRX4_IRQn = 41, /* UART 4 RX Interrupt */ + UARTTX4_IRQn = 42, /* UART 4 TX Interrupt */ + UART0_Combined_IRQn = 43, /* UART 0 Combined Interrupt */ + UART1_Combined_IRQn = 44, /* UART 1 Combined Interrupt */ + UART2_Combined_IRQn = 45, /* UART 2 Combined Interrupt */ + UART3_Combined_IRQn = 46, /* UART 3 Combined Interrupt */ + UART4_Combined_IRQn = 47, /* UART 4 Combined Interrupt */ + UARTOVF_IRQn = 48, /* UART 0, 1, 2, 3, 4 & 5 Overflow Interrupt */ + ETHERNET_IRQn = 49, /* Ethernet Interrupt */ + I2S_IRQn = 50, /* Audio I2S Interrupt */ + TOUCH_SCREEN_IRQn = 51, /* Touch Screen Interrupt */ + USB_IRQn = 52, /* USB Interrupt */ + SPI_ADC_IRQn = 53, /* SPI ADC Interrupt */ + SPI_SHIELD0_IRQn = 54, /* SPI (Shield 0) Interrupt */ + SPI_SHIELD1_IRQn = 55, /* SPI (Shield 1) Interrupt */ + ETHOS_U55_IRQn = 56, /* Ethos-U55 Interrupt */ + /* Reserved = 57:68 Reserved */ + GPIO0_Combined_IRQn = 69, /* GPIO 0 Combined Interrupt */ + GPIO1_Combined_IRQn = 70, /* GPIO 1 Combined Interrupt */ + GPIO2_Combined_IRQn = 71, /* GPIO 2 Combined Interrupt */ + GPIO3_Combined_IRQn = 72, /* GPIO 3 Combined Interrupt */ + GPIO0_0_IRQn = 73, /* GPIO0 has 16 pins with IRQs */ + GPIO0_1_IRQn = 74, + GPIO0_2_IRQn = 75, + GPIO0_3_IRQn = 76, + GPIO0_4_IRQn = 77, + GPIO0_5_IRQn = 78, + GPIO0_6_IRQn = 79, + GPIO0_7_IRQn = 80, + GPIO0_8_IRQn = 81, + GPIO0_9_IRQn = 82, + GPIO0_10_IRQn = 83, + GPIO0_11_IRQn = 84, + GPIO0_12_IRQn = 85, + GPIO0_13_IRQn = 86, + GPIO0_14_IRQn = 87, + GPIO0_15_IRQn = 88, + GPIO1_0_IRQn = 89, /* GPIO1 has 16 pins with IRQs */ + GPIO1_1_IRQn = 90, + GPIO1_2_IRQn = 91, + GPIO1_3_IRQn = 92, + GPIO1_4_IRQn = 93, + GPIO1_5_IRQn = 94, + GPIO1_6_IRQn = 95, + GPIO1_7_IRQn = 96, + GPIO1_8_IRQn = 97, + GPIO1_9_IRQn = 98, + GPIO1_10_IRQn = 99, + GPIO1_11_IRQn = 100, + GPIO1_12_IRQn = 101, + GPIO1_13_IRQn = 102, + GPIO1_14_IRQn = 103, + GPIO1_15_IRQn = 104, + GPIO2_0_IRQn = 105, /* GPIO2 has 16 pins with IRQs */ + GPIO2_1_IRQn = 106, + GPIO2_2_IRQn = 107, + GPIO2_3_IRQn = 108, + GPIO2_4_IRQn = 109, + GPIO2_5_IRQn = 110, + GPIO2_6_IRQn = 111, + GPIO2_7_IRQn = 112, + GPIO2_8_IRQn = 113, + GPIO2_9_IRQn = 114, + GPIO2_10_IRQn = 115, + GPIO2_11_IRQn = 116, + GPIO2_12_IRQn = 117, + GPIO2_13_IRQn = 118, + GPIO2_14_IRQn = 119, + GPIO2_15_IRQn = 120, + GPIO3_0_IRQn = 121, /* GPIO3 has 4 pins with IRQs */ + GPIO3_1_IRQn = 122, + GPIO3_2_IRQn = 123, + GPIO3_3_IRQn = 124, + UARTRX5_IRQn = 125, /* UART 5 RX Interrupt */ + UARTTX5_IRQn = 126, /* UART 5 TX Interrupt */ + UART5_IRQn = 127, /* UART 5 combined Interrupt */ + /* Reserved = 128:130 Reserved */ +} IRQn_Type; + +#endif /* __PLATFORM_IRQ_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/platform_regs.h b/platform/ext/target/mps3/fvp_sse300/device/include/platform_regs.h new file mode 100644 index 0000000000..4c0f5221d3 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/platform_regs.h @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2019-2020 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 __PLATFORM_REGS_H__ +#define __PLATFORM_REGS_H__ + +#include <stdint.h> + +/* Secure Access Configuration Register Block */ +struct sse300_sacfg_t { + volatile uint32_t spcsecctrl; /* 0x000 (R/W) Secure Configuration + * Control Register */ + volatile uint32_t buswait; /* 0x004 (R/W) Bus Access wait control */ + volatile uint32_t reserved0[2]; + volatile uint32_t secrespcfg; /* 0x010 (R/W) Security Violation Response + * Configuration register */ + volatile uint32_t nsccfg; /* 0x014 (R/W) Non Secure Callable + * Configuration for IDAU */ + volatile uint32_t reserved1; + volatile uint32_t secmpcintstat; /* 0x01C (R/ ) Secure MPC IRQ Status */ + volatile uint32_t secppcintstat; /* 0x020 (R/ ) Secure PPC IRQ Status */ + volatile uint32_t secppcintclr; /* 0x024 (R/W) Secure PPC IRQ Clear */ + volatile uint32_t secppcinten; /* 0x028 (R/W) Secure PPC IRQ Enable */ + volatile uint32_t reserved2; + volatile uint32_t secmscintstat; /* 0x030 (R/ ) Secure MSC IRQ Status */ + volatile uint32_t secmscintclr; /* 0x034 (R/W) Secure MSC IRQ Clear */ + volatile uint32_t secmscinten; /* 0x038 (R/W) Secure MSC IRQ Enable */ + volatile uint32_t reserved3; + volatile uint32_t brgintstat; /* 0x040 (R/ ) Bridge Buffer Error IRQ + * Status */ + volatile uint32_t brgintclr; /* 0x044 (R/W) Bridge Buffer Error IRQ + * Clear */ + volatile uint32_t brginten; /* 0x048 (R/W) Bridge Buffer Error IRQ + * Enable */ + volatile uint32_t reserved4; + volatile uint32_t mainnsppc0; /* 0x050 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Main + * Interconnect */ + volatile uint32_t reserved5[3]; + volatile uint32_t mainnsppcexp0; /* 0x060 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp1; /* 0x064 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp2; /* 0x068 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp3; /* 0x06C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t periphnsppc0; /* 0x070 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Peripheral + * Interconnect */ + volatile uint32_t periphnsppc1; /* 0x074 (R/W) Non-secure Access + * Peripheral Protection + * Control 1 on the Peripheral + * Interconnect */ + volatile uint32_t reserved6[2]; + volatile uint32_t periphnsppcexp0;/* 0x080 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp1;/* 0x084 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp2;/* 0x088 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp3;/* 0x08C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t mainspppc0; /* 0x090 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on Main + * Interconnect */ + volatile uint32_t reserved7[3]; + volatile uint32_t mainspppcexp0; /* 0x0A0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp1; /* 0x0A4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp2; /* 0x0A8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp3; /* 0x0AC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphspppc0; /* 0x0B0 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphspppc1; /* 0x0B4 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved8[2]; + volatile uint32_t periphspppcexp0;/* 0x0C0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp1;/* 0x0C4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp2;/* 0x0C8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp3;/* 0x0CC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t nsmscexp; /* 0x0D0 (R/W) Expansion MSC Non-Secure + * Configuration */ + volatile uint32_t reserved9[959]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved10[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* PPC interrupt position mask */ +#define PERIPH_PPC0_INT_POS_MASK (1UL << 0) +#define PERIPH_PPC1_INT_POS_MASK (1UL << 1) +#define PERIPH_PPCEXP0_INT_POS_MASK (1UL << 4) +#define PERIPH_PPCEXP1_INT_POS_MASK (1UL << 5) +#define PERIPH_PPCEXP2_INT_POS_MASK (1UL << 6) +#define PERIPH_PPCEXP3_INT_POS_MASK (1UL << 7) +#define MAIN_PPC0_INT_POS_MASK (1UL << 16) +#define MAIN_PPCEXP0_INT_POS_MASK (1UL << 20) +#define MAIN_PPCEXP1_INT_POS_MASK (1UL << 21) +#define MAIN_PPCEXP2_INT_POS_MASK (1UL << 22) +#define MAIN_PPCEXP3_INT_POS_MASK (1UL << 23) + +/* Non-secure Access Configuration Register Block */ +struct sse300_nsacfg_t { + volatile uint32_t reserved0[36]; + volatile uint32_t mainnspppc0; /* 0x090 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Main Interconnect */ + volatile uint32_t reserved1[3]; + + volatile uint32_t mainnspppcexp0; /* 0x0A0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp1; /* 0x0A4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp2; /* 0x0A8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp3; /* 0x0AC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphnspppc0; /* 0x0B0 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphnspppc1; /* 0x0B4 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved2[2]; + volatile uint32_t periphnspppcexp0;/* 0x0C0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp1;/* 0x0C4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp2;/* 0x0C8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp3;/* 0x0CC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved3[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved4[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* MAIN PPC0 peripherals definition */ +/* End MAIN PPC0 peripherals definition */ + +/* MAIN PPCEXP0 peripherals definition */ +#define GPIO0_MAIN_PPCEXP0_POS_MASK (1UL << 0) +#define GPIO1_MAIN_PPCEXP0_POS_MASK (1UL << 1) +#define GPIO2_MAIN_PPCEXP0_POS_MASK (1UL << 2) +#define GPIO3_MAIN_PPCEXP0_POS_MASK (1UL << 3) +#define USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK (1UL << 4) +#define USER_AHB0_MAIN_PPCEXP0_POS_MASK (1UL << 5) +#define USER_AHB1_MAIN_PPCEXP0_POS_MASK (1UL << 6) +#define USER_AHB2_MAIN_PPCEXP0_POS_MASK (1UL << 7) +/* End MAIN PPCEXP0 peripherals definition */ + +/* MAIN PPCEXP1 peripherals definition */ +#define DMA0_MAIN_PPCEXP1_POS_MASK (1UL << 0) +#define DMA1_MAIN_PPCEXP1_POS_MASK (1UL << 1) +#define DMA2_MAIN_PPCEXP1_POS_MASK (1UL << 2) +#define DMA3_MAIN_PPCEXP1_POS_MASK (1UL << 3) +/* End MAIN PPCEXP1 peripherals definition */ + +/* MAIN PPCEXP2 peripherals definition */ +/* End MAIN PPCEXP2 peripherals definition */ + +/* MAIN PPCEXP3 peripherals definition */ +/* End MAIN PPCEXP3 peripherals definition */ + +/* PERIPH PPC0 peripherals definition */ +#define SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK (1UL << 0) +#define SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK (1UL << 1) +#define SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK (1UL << 2) +#define SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK (1UL << 5) +#define WATCHDOG_PERIPH_PPC0_POS_MASK (1UL << 6) +/* There are separate secure and non-secure watchdog peripherals, so this bit + * can only be used in the unprivileged access registers. */ +/* End PERIPH PPC0 peripherals definition */ + +/* PERIPH PPC1 peripherals definition */ +#define SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK (1UL << 0) +/* End PERIPH PPC1 peripherals definition */ + +/* PERIPH PPCEXP0 peripherals definition */ +#define MPC_SRAM_PERIPH_PPCEXP0_POS_MASK (1UL << 0) +#define MPC_QSPI_PERIPH_PPCEXP0_POS_MASK (1UL << 1) +#define MPC_DDR4_PERIPH_PPCEXP0_POS_MASK (1UL << 2) +/* End PERIPH PPCEXP0 peripherals definition */ + +/* PERIPH PPCEXP1 peripherals definition */ +#define FPGA_I2C_TOUCH_PERIPH_PPCEXP1_POS_MASK (1UL << 0) +#define FPGA_I2C_AUDIO_PERIPH_PPCEXP1_POS_MASK (1UL << 1) +#define FPGA_SPI_ADC_PERIPH_PPCEXP1_POS_MASK (1UL << 2) +#define FPGA_SPI_SHIELD0_PERIPH_PPCEXP1_POS_MASK (1UL << 3) +#define FPGA_SPI_SHIELD1_PERIPH_PPCEXP1_POS_MASK (1UL << 4) +#define SBCon_I2C_SHIELD0_PERIPH_PPCEXP1_POS_MASK (1UL << 5) +#define SBCon_I2C_SHIELD1_PERIPH_PPCEXP1_POS_MASK (1UL << 6) +#define FPGA_SBCon_I2C_PERIPH_PPCEXP1_POS_MASK (1UL << 8) +/* End PERIPH PPCEXP1 peripherals definition */ + +/* PERIPH PPCEXP2 peripherals definition */ +#define FPGA_SCC_PERIPH_PPCEXP2_POS_MASK (1UL << 0) +#define FPGA_I2S_PERIPH_PPCEXP2_POS_MASK (1UL << 1) +#define FPGA_IO_PERIPH_PPCEXP2_POS_MASK (1UL << 2) +#define UART0_PERIPH_PPCEXP2_POS_MASK (1UL << 3) +#define UART1_PERIPH_PPCEXP2_POS_MASK (1UL << 4) +#define UART2_PERIPH_PPCEXP2_POS_MASK (1UL << 5) +#define UART3_PERIPH_PPCEXP2_POS_MASK (1UL << 6) +#define UART4_PERIPH_PPCEXP2_POS_MASK (1UL << 7) +#define UART5_PERIPH_PPCEXP2_POS_MASK (1UL << 8) +#define CLCD_PERIPH_PPCEXP2_POS_MASK (1UL << 10) +#define RTC_PERIPH_PPCEXP2_POS_MASK (1UL << 11) +/* End PERIPH PPCEXP2 peripherals definition */ + +/* PERIPH PPCEXP3 peripherals definition */ +/* End PERIPH PPCEXP3 peripherals definition */ + +struct cpu0_pwrctrl_t { + volatile uint32_t cpupwrcfg; /* 0x000 (R/W) CPU 0 Local Power + * Configuration */ + volatile uint32_t reserved0[1011]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved1[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct cpu0_identity_t { + volatile uint32_t cpuid; /* 0x000 (R/ ) Unique CPU 0 Identity + * Number */ + volatile uint32_t reserved0[1011]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved1[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct cpu0_secctrl_t { + volatile uint32_t cpuseccfg; /* 0x000 (R/W) CPU Local Security + * Configuration */ + volatile uint32_t reserved0[1011]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved1[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_sysinfo_t { + volatile uint32_t soc_identity; /* 0x000 (R/ ) SoC Identity Register */ + volatile uint32_t sys_config0; /* 0x004 (R/ ) System Hardware + * Configuration 0 */ + volatile uint32_t sys_config1; /* 0x008 (R/ ) System Hardware + * Configuration 1 */ + volatile uint32_t reserved0[1006]; + volatile uint32_t iidr; /* 0xFC8 (R/ ) Subsystem Implementation + * Identity */ + volatile uint32_t reserved1; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved2[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_sysctrl_t { + volatile uint32_t secdbgstat; /* 0x000 (R/ ) Secure Debug + * Configuration Status */ + volatile uint32_t secdbgset; /* 0x004 (R/W) Secure Debug + * Configuration Set */ + volatile uint32_t secdbgclr; /* 0x008 ( /W) Secure Debug + * Configuration Clear */ + volatile uint32_t scsecctrl; /* 0x00C (R/W) System Control Security + * Controls */ + volatile uint32_t clk_cfg0; /* 0x010 (R/W) Clock Configuration 0 */ + volatile uint32_t clk_cfg1; /* 0x014 (R/W) Clock Configuration 1 */ + volatile uint32_t clock_force; /* 0x018 (R/W) Clock Forces */ + volatile uint32_t reserved0[57]; + volatile uint32_t reset_syndrome; /* 0x100 (R/W) Reset syndrome */ + volatile uint32_t reset_mask; /* 0x104 (R/W) Reset mask */ + volatile uint32_t swreset; /* 0x108 ( /W) Software Reset */ + volatile uint32_t gretreg; /* 0x10C (R/W) General Purpose + * Retention */ + volatile uint32_t initsvtor0; /* 0x110 (R/W) CPU 0 Initial Secure + * Reset Vector Register */ + volatile uint32_t reserved1[3]; + volatile uint32_t cpuwait; /* 0x120 (R/W) CPU Boot Wait Control */ + volatile uint32_t nmi_enable; /* 0x124 (R/W) Non Maskable Interrupts + * Enable */ + volatile uint32_t reserved2[53]; + volatile uint32_t pwrctrl; /* 0x1FC (R/W) Power Configuration and + * Control */ + volatile uint32_t pdcm_pd_sys_sense; /* 0x200 (R/W) PDCM PD_SYS + * Sensitivity */ + volatile uint32_t pdcm_pd_cpu0_sense;/* 0x204 (R/ ) PDCM PD_CPU0 + * Sensitivity */ + volatile uint32_t reserved3[3]; + volatile uint32_t pdcm_pd_vmr0_sense;/* 0x214 (R/W) PDCM PD_VMR0 + * Sensitivity */ + volatile uint32_t pdcm_pd_vmr1_sense;/* 0x218 (R/W) PDCM PD_VMR1 + * Sensitivity */ + volatile uint32_t reserved4[877]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved5[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_ewic_t { + volatile uint32_t ewic_cr; /* 0x000 (R/W) EWIC Control */ + volatile uint32_t ewic_ascr; /* 0x004 (R/W) Automatic Sequence + * Control */ + volatile uint32_t ewic_clrmask; /* 0x008 ( /W) Clear All Mask */ + volatile uint32_t ewic_numid; /* 0x00C (R/ ) ID Register for the number + * of events supported */ + volatile uint32_t reserved0[124]; + volatile uint32_t ewic_maska; /* 0x200 (R/W) Set which internal events + * cause wakeup */ + volatile uint32_t ewic_mask[15]; /* 0x204 (R/W) Set which external + * interrupts cause wakeup */ + volatile uint32_t reserved1[112]; + volatile uint32_t ewic_penda; /* 0x400 (R/ ) Shows which internal + * interrupts were pended + * while the EWIC was + * enabled */ + + volatile uint32_t ewic_pend[15]; /* 0x404 (R/W) Shows which external + * interrupts were pended + * while the EWIC was + * enabled */ + volatile uint32_t reserved2[112]; + volatile uint32_t ewic_psr; /* 0x600 (R/ ) Pending Summary */ + volatile uint32_t reserved3[575]; + volatile uint32_t itctrl; /* 0xF00 (R/ ) Integration Mode Control */ + volatile uint32_t reserved4[39]; + volatile uint32_t claimset; /* 0xFA0 (R/W) Claim Tag Set */ + volatile uint32_t claimclr; /* 0xFA4 (R/W) Claim Tag Clear */ + volatile uint32_t devaff0; /* 0xFA8 (R/ ) Device Affinity 0 */ + volatile uint32_t devaff1; /* 0xFAC (R/ ) Device Affinity 1 */ + volatile uint32_t lar; /* 0xFB0 ( /W) Lock Access */ + volatile uint32_t lsr; /* 0xFB4 (R/ ) Lock Status */ + volatile uint32_t authstatus; /* 0xFB8 (R/ ) Authentication Status */ + volatile uint32_t devarch; /* 0xFBC (R/ ) Device Architecture */ + volatile uint32_t devid2; /* 0xFC0 (R/ ) Device Configuration 2 */ + volatile uint32_t devid1; /* 0xFC4 (R/ ) Device Configuration 1 */ + volatile uint32_t devid; /* 0xFC8 (R/ ) Device Configuration */ + volatile uint32_t devtype; /* 0xFCC (R/ ) Device Type */ + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved5[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; +#endif /* __PLATFORM_REGS_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/include/system_core_init.h b/platform/ext/target/mps3/fvp_sse300/device/include/system_core_init.h new file mode 100644 index 0000000000..feba5e9aa0 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/include/system_core_init.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009-2020 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. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.h + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#ifndef __SYSTEM_CORE_INIT_H__ +#define __SYSTEM_CORE_INIT_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency */ + +/** + * \brief Initializes the system + */ +extern void SystemInit(void); + +/** + * \brief Restores system core clock + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_CORE_INIT_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_bl2.sct b/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_bl2.sct new file mode 100644 index 0000000000..1f6a34aff3 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_bl2.sct @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017-2020 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. + */ + +#include "region_defs.h" + +LR_CODE BL2_CODE_START { + ER_CODE BL2_CODE_START BL2_CODE_SIZE { + *.o (RESET +First) + * (+RO) + } + + TFM_SHARED_DATA BOOT_TFM_SHARED_DATA_BASE ALIGN 32 EMPTY BOOT_TFM_SHARED_DATA_SIZE { + } + + ER_DATA +0 { + * (+ZI +RW) + } + + /* MSP */ + ARM_LIB_STACK +0 ALIGN 32 EMPTY BL2_MSP_STACK_SIZE { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY BL2_HEAP_SIZE { + } + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + SRAM_WATERMARK +0 EMPTY 0x0 { + } + + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(SRAM_WATERMARK) <= BL2_DATA_START + BL2_DATA_SIZE) +} diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_ns.sct b/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_ns.sct new file mode 100644 index 0000000000..92707b9ce5 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/armclang/fvp_sse300_mps3_ns.sct @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017-2020 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. + */ + +#include "region_defs.h" + +LR_CODE NS_CODE_START { + ER_CODE NS_CODE_START NS_CODE_SIZE { + *.o (RESET +First) + * (+RO) + } + + ER_DATA NS_DATA_START { + * (+ZI +RW) + } + + /* MSP */ + ARM_LIB_STACK_MSP +0 ALIGN 32 EMPTY NS_MSP_STACK_SIZE { + } + + /* PSP */ + ARM_LIB_STACK +0 ALIGN 32 EMPTY NS_PSP_STACK_SIZE { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY NS_HEAP_SIZE { + } + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + SRAM_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(SRAM_WATERMARK) <= NS_DATA_START + NS_DATA_SIZE) +} diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/device_definition.c b/platform/ext/target/mps3/fvp_sse300/device/source/device_definition.c new file mode 100644 index 0000000000..8249e92a07 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/device_definition.c @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +/** + * \file device_definition.c + * \brief This file defines exports the structures based on the peripheral + * definitions from device_cfg.h. + * This file is meant to be used as a helper for baremetal + * applications and/or as an example of how to configure the generic + * driver structures. + */ + +#include "device_definition.h" +#include "platform_base_address.h" + +#define INIT_TO_ZERO_VALUE 0 + +/* UART CMSDK driver structures */ +#ifdef UART0_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_S = { + .base = UART0_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t UART0_CMSDK_DEV_S = { + &(UART0_CMSDK_DEV_CFG_S), + &(UART0_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART0_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_NS = { + .base = UART0_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS = { + &(UART0_CMSDK_DEV_CFG_NS), + &(UART0_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART1_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART1_CMSDK_DEV_CFG_S = { + .base = UART1_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART1_DEV_S = { + &(UART1_CMSDK_DEV_CFG_S), + &(UART1_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART1_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART1_CMSDK_DEV_CFG_NS = { + .base = UART1_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART1_DEV_NS = { + &(UART1_CMSDK_DEV_CFG_NS), + &(UART1_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART2_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART2_CMSDK_DEV_CFG_S = { + .base = UART2_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART2_DEV_S = { + &(UART2_CMSDK_DEV_CFG_S), + &(UART2_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART2_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART2_CMSDK_DEV_CFG_NS = { + .base = UART2_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART2_DEV_NS = { + &(UART2_CMSDK_DEV_CFG_NS), + &(UART2_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART3_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_S = { + .base = UART3_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART3_DEV_S = { + &(UART3_CMSDK_DEV_CFG_S), + &(UART3_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART3_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_NS = { + .base = UART3_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART3_DEV_NS = { + &(UART3_CMSDK_DEV_CFG_NS), + &(UART3_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART4_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_S = { + .base = UART4_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART4_DEV_S = { + &(UART4_CMSDK_DEV_CFG_S), + &(UART4_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART4_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_NS = { + .base = UART4_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART4_DEV_NS = { + &(UART4_CMSDK_DEV_CFG_NS), + &(UART4_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART5_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_S = { + .base = UART5_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_S = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART5_DEV_S = { + &(UART5_CMSDK_DEV_CFG_S), + &(UART5_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART5_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_NS = { + .base = UART5_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_NS = { + .state = INIT_TO_ZERO_VALUE, + .system_clk = INIT_TO_ZERO_VALUE, + .baudrate = INIT_TO_ZERO_VALUE +}; +struct uart_cmsdk_dev_t ARM_UART5_DEV_NS = { + &(UART5_CMSDK_DEV_CFG_NS), + &(UART5_CMSDK_DEV_DATA_NS) +}; +#endif + +/* SSE-300 PPC driver structures */ +#ifdef PPC_SSE300_MAIN0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN0_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN0}; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN0_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_MAIN0_DEV_S = { + &PPC_SSE300_MAIN0_CFG_S, + &PPC_SSE300_MAIN0_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP0_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP0}; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP0_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP0_DEV_S = { + &PPC_SSE300_MAIN_EXP0_CFG_S, + &PPC_SSE300_MAIN_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP1_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP1}; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP1_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP1_DEV_S = { + &PPC_SSE300_MAIN_EXP1_CFG_S, + &PPC_SSE300_MAIN_EXP1_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP2_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP2_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP2}; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP2_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP2_DEV_S = { + &PPC_SSE300_MAIN_EXP2_CFG_S, + &PPC_SSE300_MAIN_EXP2_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP3_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP3_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP3}; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP3_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP3_DEV_S = { + &PPC_SSE300_MAIN_EXP3_CFG_S, + &PPC_SSE300_MAIN_EXP3_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH0_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH0}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH0_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH0_DEV_S = { + &PPC_SSE300_PERIPH0_CFG_S, + &PPC_SSE300_PERIPH0_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH1_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH1}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH1_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH1_DEV_S = { + &PPC_SSE300_PERIPH1_CFG_S, + &PPC_SSE300_PERIPH1_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP0_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP0}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP0_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP0_DEV_S = { + &PPC_SSE300_PERIPH_EXP0_CFG_S, + &PPC_SSE300_PERIPH_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP1_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP1}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP1_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP1_DEV_S = { + &PPC_SSE300_PERIPH_EXP1_CFG_S, + &PPC_SSE300_PERIPH_EXP1_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP2_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP2_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP2}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP2_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP2_DEV_S = { + &PPC_SSE300_PERIPH_EXP2_CFG_S, + &PPC_SSE300_PERIPH_EXP2_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP3_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP3_CFG_S = { + .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP3}; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP3_DATA_S = { + .sacfg_ns_ppc = INIT_TO_ZERO_VALUE, + .sacfg_sp_ppc = INIT_TO_ZERO_VALUE, + .nsacfg_nsp_ppc = INIT_TO_ZERO_VALUE, + .int_bit_mask = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP3_DEV_S = { + &PPC_SSE300_PERIPH_EXP3_CFG_S, + &PPC_SSE300_PERIPH_EXP3_DATA_S }; +#endif + +/* System counters */ +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S + +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT is invalid. +#endif + +static const struct syscounter_armv8_m_cntrl_dev_cfg_t +SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_CNTRL_BASE_S, + .scale0.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT, + .scale0.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT, + .scale1.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT, + .scale1.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT +}; +static struct syscounter_armv8_m_cntrl_dev_data_t +SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S = { + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S), + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +static const struct syscounter_armv8_m_read_dev_cfg_t +SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_READ_BASE_S, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S = { + &(SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S), +}; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +static const struct syscounter_armv8_m_read_dev_cfg_t +SYSCOUNTER_READ_ARMV8_M_DEV_CFG_NS = { + .base = SYSCNTR_READ_BASE_NS, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS = { + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_NS), +}; +#endif + +/* System timers */ +#ifdef SYSTIMER0_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER0_ARMV8_M_DEV_CFG_S = { + .base = SYSTIMER0_ARMV8_M_BASE_S, + .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER0_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S = { + &(SYSTIMER0_ARMV8_M_DEV_CFG_S), + &(SYSTIMER0_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSTIMER0_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER0_ARMV8_M_DEV_CFG_NS = { + .base = SYSTIMER0_ARMV8_M_BASE_NS, + .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER0_ARMV8_M_DEV_DATA_NS = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS = { + &(SYSTIMER0_ARMV8_M_DEV_CFG_NS), + &(SYSTIMER0_ARMV8_M_DEV_DATA_NS) +}; +#endif + +#ifdef SYSTIMER1_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER1_ARMV8_M_DEV_CFG_S = { + .base = SYSTIMER1_ARMV8_M_BASE_S, + .default_freq_hz = SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER1_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S = { + &(SYSTIMER1_ARMV8_M_DEV_CFG_S), + &(SYSTIMER1_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSTIMER1_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER1_ARMV8_M_DEV_CFG_NS = { + .base = SYSTIMER1_ARMV8_M_BASE_NS, + .default_freq_hz = SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER1_ARMV8_M_DEV_DATA_NS = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS = { + &(SYSTIMER1_ARMV8_M_DEV_CFG_NS), + &(SYSTIMER1_ARMV8_M_DEV_DATA_NS) +}; +#endif + +#ifdef SYSTIMER2_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER2_ARMV8_M_DEV_CFG_S = { + .base = SYSTIMER2_ARMV8_M_BASE_S, + .default_freq_hz = SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER2_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S = { + &(SYSTIMER2_ARMV8_M_DEV_CFG_S), + &(SYSTIMER2_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSTIMER2_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER2_ARMV8_M_DEV_CFG_NS = { + .base = SYSTIMER2_ARMV8_M_BASE_NS, + .default_freq_hz = SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER2_ARMV8_M_DEV_DATA_NS = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS = { + &(SYSTIMER2_ARMV8_M_DEV_CFG_NS), + &(SYSTIMER2_ARMV8_M_DEV_DATA_NS) +}; +#endif + +#ifdef SYSTIMER3_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER3_ARMV8_M_DEV_CFG_S = { + .base = SYSTIMER3_ARMV8_M_BASE_S, + .default_freq_hz = SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER3_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S = { + &(SYSTIMER3_ARMV8_M_DEV_CFG_S), + &(SYSTIMER3_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSTIMER3_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER3_ARMV8_M_DEV_CFG_NS = { + .base = SYSTIMER3_ARMV8_M_BASE_NS, + .default_freq_hz = SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ +}; +static struct systimer_armv8_m_dev_data_t +SYSTIMER3_ARMV8_M_DEV_DATA_NS = { + .is_initialized = false +}; +struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS = { + &(SYSTIMER3_ARMV8_M_DEV_CFG_NS), + &(SYSTIMER3_ARMV8_M_DEV_DATA_NS) +}; +#endif + +/* System Watchdogs */ +#ifdef SYSWDOG_ARMV8_M_S +static const struct syswdog_armv8_m_dev_cfg_t +SYSWDOG_ARMV8_M_DEV_CFG_S = { + .base = SYSWDOG_ARMV8_M_CNTRL_BASE_S +}; +struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S = { + &(SYSWDOG_ARMV8_M_DEV_CFG_S) +}; +#endif + +#ifdef SYSWDOG_ARMV8_M_NS +static const struct syswdog_armv8_m_dev_cfg_t +SYSWDOG_ARMV8_M_DEV_CFG_NS = { + .base = SYSWDOG_ARMV8_M_CNTRL_BASE_NS +}; +struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS = { + &(SYSWDOG_ARMV8_M_DEV_CFG_NS) +}; +#endif + +/* ARM MPC SSE 300 driver structures */ +#ifdef MPC_SRAM_S +static const struct mpc_sie_dev_cfg_t MPC_SRAM_DEV_CFG_S = { + .base = MPC_SRAM_BASE_S}; +static struct mpc_sie_dev_data_t MPC_SRAM_DEV_DATA_S = { + .range_list = INIT_TO_ZERO_VALUE, + .nbr_of_ranges = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_SRAM_DEV_S = { + &(MPC_SRAM_DEV_CFG_S), + &(MPC_SRAM_DEV_DATA_S)}; +#endif + +#ifdef MPC_QSPI_S +static const struct mpc_sie_dev_cfg_t MPC_QSPI_DEV_CFG_S = { + .base = MPC_QSPI_BASE_S}; +static struct mpc_sie_dev_data_t MPC_QSPI_DEV_DATA_S = { + .range_list = INIT_TO_ZERO_VALUE, + .nbr_of_ranges = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_QSPI_DEV_S = { + &(MPC_QSPI_DEV_CFG_S), + &(MPC_QSPI_DEV_DATA_S)}; +#endif + +#ifdef MPC_DDR4_S +static const struct mpc_sie_dev_cfg_t MPC_DDR4_DEV_CFG_S = { + .base = MPC_DDR4_BASE_S}; +static struct mpc_sie_dev_data_t MPC_DDR4_DEV_DATA_S = { + .range_list = INIT_TO_ZERO_VALUE, + .nbr_of_ranges = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_DDR4_DEV_S = { + &(MPC_DDR4_DEV_CFG_S), + &(MPC_DDR4_DEV_DATA_S)}; +#endif + +#ifdef MPC_ISRAM0_S +static const struct mpc_sie_dev_cfg_t MPC_ISRAM0_DEV_CFG_S = { + .base = MPC_ISRAM0_BASE_S}; +static struct mpc_sie_dev_data_t MPC_ISRAM0_DEV_DATA_S = { + .range_list = INIT_TO_ZERO_VALUE, + .nbr_of_ranges = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_ISRAM0_DEV_S = { + &(MPC_ISRAM0_DEV_CFG_S), + &(MPC_ISRAM0_DEV_DATA_S)}; +#endif + +#ifdef MPC_ISRAM1_S +static const struct mpc_sie_dev_cfg_t MPC_ISRAM1_DEV_CFG_S = { + .base = MPC_ISRAM1_BASE_S}; +static struct mpc_sie_dev_data_t MPC_ISRAM1_DEV_DATA_S = { + .range_list = INIT_TO_ZERO_VALUE, + .nbr_of_ranges = INIT_TO_ZERO_VALUE, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_ISRAM1_DEV_S = { + &(MPC_ISRAM1_DEV_CFG_S), + &(MPC_ISRAM1_DEV_DATA_S)}; +#endif + +#ifdef MPS3_IO_S +static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_S = { + .base = FPGA_IO_BASE_S +}; +struct arm_mps3_io_dev_t MPS3_IO_DEV_S = { + .cfg = &(MPS3_IO_DEV_CFG_S) +}; +#endif + +#ifdef MPS3_IO_NS +static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_NS = { + .base = FPGA_IO_BASE_NS +}; +struct arm_mps3_io_dev_t MPS3_IO_DEV_NS = { + .cfg = &(MPS3_IO_DEV_CFG_NS) +}; +#endif diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_bl2.c b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_bl2.c new file mode 100644 index 0000000000..53e367c0a7 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_bl2.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TIMER0_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TIMER0_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_ns.c b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_ns.c new file mode 100644 index 0000000000..0d4cb5238c --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_ns.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" +#include "region.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ + +#define __MSP_INITIAL_SP REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit) +#define __MSP_STACK_LIMIT REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Base) + +extern uint32_t __MSP_INITIAL_SP; +extern uint32_t __MSP_STACK_LIMIT; + +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__MSP_INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TFM_TIMER0_IRQ_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__MSP_STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __ASM volatile("MRS R0, control\n" /* Get control value */ + "ORR R0, R0, #1\n" /* Select switch to unprivilage mode */ + "ORR R0, R0, #2\n" /* Select switch to PSP */ + "MSR control, R0\n" /* Load control register */ + : + : + : "r0"); + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_s.c b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_s.c new file mode 100644 index 0000000000..3624024408 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/startup_fvp_sse300_mps3_s.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" +#include "region.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ + +#define __MSP_INITIAL_SP REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit) +#define __MSP_STACK_LIMIT REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Base) + +extern uint32_t __MSP_INITIAL_SP; +extern uint32_t __MSP_STACK_LIMIT; + +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__MSP_INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TFM_TIMER0_IRQ_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 56: Reserved */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__MSP_STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __ASM volatile("MRS R0, control\n" /* Get control value */ + "ORR R0, R0, #2\n" /* Select switch to PSP */ + "MSR control, R0\n" /* Load control register */ + : + : + : "r0"); + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/platform/ext/target/mps3/fvp_sse300/device/source/system_core_init.c b/platform/ext/target/mps3/fvp_sse300/device/source/system_core_init.c new file mode 100644 index 0000000000..e8e9e4c90f --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/device/source/system_core_init.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ + #define XTAL (32000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Externals + *----------------------------------------------------------------------------*/ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + extern uint32_t __VECTOR_TABLE; +#endif + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE); +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif +} diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.c new file mode 100644 index 0000000000..23dbf50acf --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.c @@ -0,0 +1,791 @@ +/* + * Copyright (c) 2016-2020 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. + */ +#include "mpc_sie_drv.h" + +#include <stddef.h> +#include <stdbool.h> + +#include "cmsis_compiler.h" + +/* Values for hardware version in PIDR0 reg */ +#define SIE200 0x60 +#define SIE300 0x65 + +#define MPC_SIE_BLK_CFG_OFFSET 5U + +/* Defines with numbering (eg: SIE300) are only relevant to the given SIE + * version. Defines without the numbering are applicable to all SIE versions. + */ + +/* CTRL register bit indexes */ +#define MPC_SIE200_CTRL_SEC_RESP (1UL << 4UL) /* MPC fault triggers a + * bus error + */ +#define MPC_SIE300_CTRL_GATE_REQ (1UL << 6UL) /* Request for gating + * incoming transfers + */ +#define MPC_SIE300_CTRL_GATE_ACK (1UL << 7UL) /* Acknowledge for gating + * incoming transfers + */ +#define MPC_SIE_CTRL_AUTOINCREMENT (1UL << 8UL) /* BLK_IDX auto increment */ +#define MPC_SIE300_CTRL_SEC_RESP (1UL << 16UL) /* Response type when SW + * asks to gate the transfer + */ +#define MPC_SIE300_CTRL_GATE_PRESENT (1UL << 23UL) /* Gating feature present */ +#define MPC_SIE_CTRL_SEC_LOCK_DOWN (1UL << 31UL) /* MPC Security lock down */ + +/* PIDR register bit masks */ +#define MPC_PIDR0_SIE_VERSION_MASK ((1UL << 8UL) - 1UL) + +/* ARM MPC interrupt */ +#define MPC_SIE_INT_BIT (1UL) + +/* Error code returned by the internal driver functions */ +enum mpc_sie_intern_error_t { + MPC_SIE_INTERN_ERR_NONE = MPC_SIE_ERR_NONE, + MPC_SIE_INTERN_ERR_NOT_IN_RANGE = MPC_SIE_ERR_NOT_IN_RANGE, + MPC_SIE_INTERN_ERR_NOT_ALIGNED = MPC_SIE_ERR_NOT_ALIGNED, + MPC_SIE_INTERN_ERR_INVALID_RANGE = MPC_SIE_ERR_INVALID_RANGE, + MPC_INTERN_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE = + MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, + /* Calculated block index + * is higher than the maximum allowed by the MPC. It should never + * happen unless the controlled ranges of the MPC are misconfigured + * in the driver or if the IP has not enough LUTs to cover the + * range, due to wrong reported block size for example. + */ + MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH = -1, + +}; + +/* ARM MPC memory mapped register access structure */ +struct mpc_sie_reg_map_t { + volatile uint32_t ctrl; /* (R/W) MPC Control */ + volatile uint32_t reserved[3];/* Reserved */ + volatile uint32_t blk_max; /* (R/ ) Maximum value of block based index */ + volatile uint32_t blk_cfg; /* (R/ ) Block configuration */ + volatile uint32_t blk_idx; /* (R/W) Index value for accessing block + * based look up table + */ + volatile uint32_t blk_lutn; /* (R/W) Block based gating + * Look Up Table (LUT) + */ + volatile uint32_t int_stat; /* (R/ ) Interrupt state */ + volatile uint32_t int_clear; /* ( /W) Interrupt clear */ + volatile uint32_t int_en; /* (R/W) Interrupt enable */ + volatile uint32_t int_info1; /* (R/ ) Interrupt information 1 */ + volatile uint32_t int_info2; /* (R/ ) Interrupt information 2 */ + volatile uint32_t int_set; /* ( /W) Interrupt set. Debug purpose only */ + volatile uint32_t reserved2[998]; /* Reserved */ + volatile uint32_t pidr4; /* (R/ ) Peripheral ID 4 */ + volatile uint32_t pidr5; /* (R/ ) Peripheral ID 5 */ + volatile uint32_t pidr6; /* (R/ ) Peripheral ID 6 */ + volatile uint32_t pidr7; /* (R/ ) Peripheral ID 7 */ + volatile uint32_t pidr0; /* (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* (R/ ) Component ID 3 */ +}; + +/* + * Checks if the address is controlled by the MPC and returns + * the range index in which it is contained. + * + * \param[in] dev MPC device to initialize \ref mpc_sie_dev_t + * \param[in] addr Address to check if it is controlled by MPC. + * \param[out] addr_range Range index in which it is contained. + * + * \return True if the base is controller by the range list, false otherwise. + */ +static uint32_t is_ctrl_by_range_list( + struct mpc_sie_dev_t* dev, + uint32_t addr, + const struct mpc_sie_memory_range_t** addr_range) +{ + uint32_t i; + const struct mpc_sie_memory_range_t* range; + + for(i = 0; i < dev->data->nbr_of_ranges; i++) { + range = dev->data->range_list[i]; + if(addr >= range->base && addr <= range->limit) { + *addr_range = range; + return 1; + } + } + return 0; +} + +/* + * Gets the masks selecting the bits in the LUT of the MPC corresponding + * to the base address (included) up to the limit address (included) + * + * \param[in] mpc_dev The MPC device. + * \param[in] base Address in a range controlled by this MPC + * (included), aligned on block size. + * \param[in] limit Address in a range controlled by this MPC + * (included), aligned on block size. + * \param[out] range Memory range in which the base address and + * limit are. + * \param[out] first_word_idx Index of the first touched word in the LUT. + * \param[out] nr_words Number of words used in the LUT. If 1, only + * first_word_mask is valid and limit_word_mask + * must not be used. + * \param[out] first_word_mask First word mask in the LUT will be stored here. + * \param[out] limit_word_mask Limit word mask in the LUT will be stored here. + * + * \return Returns error code as specified in \ref mpc_sie_intern_error_t + */ +static enum mpc_sie_intern_error_t get_lut_masks( + struct mpc_sie_dev_t* dev, + const uint32_t base, const uint32_t limit, + const struct mpc_sie_memory_range_t** range, + uint32_t *first_word_idx, + uint32_t *nr_words, + uint32_t *first_word_mask, + uint32_t *limit_word_mask) +{ + const struct mpc_sie_memory_range_t* base_range; + uint32_t block_size; + uint32_t base_block_idx; + uint32_t base_word_idx; + uint32_t blk_max; + const struct mpc_sie_memory_range_t* limit_range; + uint32_t limit_block_idx; + uint32_t limit_word_idx; + uint32_t mask; + uint32_t norm_base; + uint32_t norm_limit; + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + /* + * Check that the addresses are within the controlled regions + * of this MPC + */ + if(!is_ctrl_by_range_list(dev, base, &base_range) || + !is_ctrl_by_range_list(dev, limit, &limit_range)) { + return MPC_SIE_INTERN_ERR_NOT_IN_RANGE; + } + + /* Base and limit should be part of the same range */ + if(base_range != limit_range) { + return MPC_SIE_INTERN_ERR_INVALID_RANGE; + } + *range = base_range; + + block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + /* Base and limit+1 addresses must be aligned on the MPC block size */ + if(base % block_size || (limit+1) % block_size) { + return MPC_SIE_INTERN_ERR_NOT_ALIGNED; + } + + /* + * Get a normalized address that is an offset from the beginning + * of the lowest range controlled by the MPC + */ + norm_base = (base - base_range->base) + base_range->range_offset; + norm_limit = (limit - base_range->base) + base_range->range_offset; + + /* + * Calculate block index and to which 32 bits word it belongs + */ + limit_block_idx = norm_limit/block_size; + limit_word_idx = limit_block_idx/32; + + base_block_idx = norm_base/block_size; + base_word_idx = base_block_idx/32; + + if(base_block_idx > limit_block_idx) { + return MPC_SIE_INTERN_ERR_INVALID_RANGE; + } + + /* Transmit the information to the caller */ + *nr_words = limit_word_idx - base_word_idx + 1; + *first_word_idx = base_word_idx; + + /* Limit to the highest block that can be configured */ + blk_max = p_mpc->blk_max; + + if((limit_word_idx > blk_max) || (base_word_idx > blk_max)) { + return MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH; + } + + /* + * Create the mask for the first word to only select the limit N bits + */ + *first_word_mask = ~((1 << (base_block_idx % 32)) - 1); + + /* + * Create the mask for the limit word to select only the first M bits. + */ + *limit_word_mask = (1 << ((limit_block_idx+1) % 32)) - 1; + /* + * If limit_word_mask is 0, it means that the limit touched block index is + * the limit in its word, so the limit word mask has all its bits selected + */ + if(*limit_word_mask == 0) { + *limit_word_mask = 0xFFFFFFFF; + } + + /* + * If the blocks to configure are all packed in one word, only + * touch this word. + * Code using the computed masks should test if this mask + * is non-zero, and if so, only use this one instead of the limit_word_mask + * and first_word_mask. + * As the only bits that are the same in both masks are the 1 that we want + * to select, just use XOR to extract them. + */ + if(base_word_idx == limit_word_idx) { + mask = ~(*first_word_mask ^ *limit_word_mask); + *first_word_mask = mask; + *limit_word_mask = mask; + } + + return MPC_SIE_INTERN_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t* dev, + const struct mpc_sie_memory_range_t** range_list, + uint8_t nbr_of_ranges) +{ + if((range_list == NULL) || (nbr_of_ranges == 0)) { + return MPC_SIE_INVALID_ARG; + } + + dev->data->sie_version = get_sie_version(dev); + + if ((dev->data->sie_version != SIE200) && + (dev->data->sie_version != SIE300)) { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + dev->data->range_list = range_list; + dev->data->nbr_of_ranges = nbr_of_ranges; + dev->data->is_initialized = true; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev, + uint32_t* blk_size) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if(blk_size == 0) { + return MPC_SIE_INVALID_ARG; + } + + /* Calculate the block size in byte according to the manual */ + *blk_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t* dev, + const uint32_t base, + const uint32_t limit, + enum mpc_sie_sec_attr_t attr) +{ + enum mpc_sie_intern_error_t error; + uint32_t first_word_idx; + uint32_t first_word_mask; + uint32_t i; + uint32_t limit_word_mask; + uint32_t limit_word_idx; + uint32_t nr_words; + const struct mpc_sie_memory_range_t* range; + uint32_t word_value; + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + /* Get the bitmasks used to select the bits in the LUT */ + error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words, + &first_word_mask, &limit_word_mask); + + limit_word_idx = first_word_idx + nr_words - 1; + + if(error != MPC_SIE_INTERN_ERR_NONE) { + /* Map internal error code lower than 0 to a generic errpr */ + if(error < 0) { + return MPC_SIE_ERR_INVALID_RANGE; + } + return (enum mpc_sie_error_t)error; + } + + /* + * The memory range should allow accesses in with the wanted security + * attribute if it requires special attribute for successful accesses + */ + if(range->attr != attr) { + return MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE; + } + + /* + * Starts changing actual configuration so issue DMB to ensure every + * transaction has completed by now + */ + __DMB(); + + /* Set the block index to the first word that will be updated */ + p_mpc->blk_idx = first_word_idx; + + /* If only one word needs to be touched in the LUT */ + if(nr_words == 1) { + word_value = p_mpc->blk_lutn; + if(attr == MPC_SIE_SEC_ATTR_NONSECURE) { + word_value |= first_word_mask; + } else { + word_value &= ~first_word_mask; + } + + /* + * Set the index again because full word read or write could have + * incremented it + */ + p_mpc->blk_idx = first_word_idx; + p_mpc->blk_lutn = word_value; + + /* Commit the configuration change */ + __DSB(); + __ISB(); + + return MPC_SIE_ERR_NONE; + } + + /* First word */ + word_value = p_mpc->blk_lutn; + if(attr == MPC_SIE_SEC_ATTR_NONSECURE) { + word_value |= first_word_mask; + } else { + word_value &= ~first_word_mask; + } + /* + * Set the index again because full word read or write could have + * incremented it + */ + p_mpc->blk_idx = first_word_idx; + /* Partially configure the first word */ + p_mpc->blk_lutn = word_value; + + /* Fully configure the intermediate words if there are any */ + for(i=first_word_idx+1; i<limit_word_idx; i++) { + p_mpc->blk_idx = i; + if(attr == MPC_SIE_SEC_ATTR_NONSECURE) { + p_mpc->blk_lutn = 0xFFFFFFFF; + } else { + p_mpc->blk_lutn = 0x00000000; + } + } + + /* Partially configure the limit word */ + p_mpc->blk_idx = limit_word_idx; + word_value = p_mpc->blk_lutn; + if(attr == MPC_SIE_SEC_ATTR_NONSECURE) { + word_value |= limit_word_mask; + } else { + word_value &= ~limit_word_mask; + } + p_mpc->blk_idx = limit_word_idx; + p_mpc->blk_lutn = word_value; + + /* Commit the configuration change */ + __DSB(); + __ISB(); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_region_config( + struct mpc_sie_dev_t* dev, + uint32_t base, uint32_t limit, + enum mpc_sie_sec_attr_t* attr) +{ + enum mpc_sie_sec_attr_t attr_prev; + uint32_t block_size; + uint32_t block_size_mask; + enum mpc_sie_intern_error_t error; + uint32_t first_word_idx; + uint32_t first_word_mask; + uint32_t i; + uint32_t limit_word_idx; + uint32_t limit_word_mask; + uint32_t nr_words; + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + const struct mpc_sie_memory_range_t* range; + uint32_t word_value; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if(attr == 0) { + return MPC_SIE_INVALID_ARG; + } + + /* + * Initialize the security attribute to mixed in case of early + * termination of this function. A caller that does not check the + * returned error will act as if it does not know anything about the + * region queried, which is the safest bet + */ + *attr = MPC_SIE_SEC_ATTR_MIXED; + + /* + * If the base and limit are not aligned, align them and make sure + * that the resulting region fully includes the original region + */ + block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + block_size_mask = block_size - 1; + base &= ~(block_size_mask); + limit &= ~(block_size_mask); + limit += block_size - 1; /* Round to the upper block address, + * and then remove one to get the preceding + * address. + */ + + /* Get the bitmasks used to select the bits in the LUT */ + error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words, + &first_word_mask, &limit_word_mask); + + limit_word_idx = first_word_idx+nr_words - 1; + + if(error != MPC_SIE_INTERN_ERR_NONE) { + /* Map internal error code lower than 0 to generic error */ + if(error < 0) { + return MPC_SIE_ERR_INVALID_RANGE; + } + return (enum mpc_sie_error_t)error; + } + + /* Set the block index to the first word that will be updated */ + p_mpc->blk_idx = first_word_idx; + + /* If only one word needs to be touched in the LUT */ + if(nr_words == 1) { + word_value = p_mpc->blk_lutn; + word_value &= first_word_mask; + if(word_value == 0) { + *attr = MPC_SIE_SEC_ATTR_SECURE; + /* + * If there are differences between the mask and the word value, + * it means that the security attributes of blocks are mixed + */ + } else if(word_value ^ first_word_mask) { + *attr = MPC_SIE_SEC_ATTR_MIXED; + } else { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + return MPC_SIE_ERR_NONE; + } + + /* Get the partial configuration of the first word */ + word_value = p_mpc->blk_lutn & first_word_mask; + if(word_value == 0x00000000) { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } else if(word_value ^ first_word_mask) { + *attr = MPC_SIE_SEC_ATTR_MIXED; + /* + * Bail out as the security attribute will be the same regardless + * of the configuration of other blocks + */ + return MPC_SIE_ERR_NONE; + } else { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + /* + * Store the current found attribute, to check that all the blocks indeed + * have the same security attribute. + */ + attr_prev = *attr; + + /* Get the configuration of the intermediate words if there are any */ + for(i=first_word_idx+1; i<limit_word_idx; i++) { + p_mpc->blk_idx = i; + word_value = p_mpc->blk_lutn; + if(word_value == 0x00000000) { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } else if(word_value == 0xFFFFFFFF) { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } else { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + + /* If the attribute is different than the one found before, bail out */ + if(*attr != attr_prev) { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + attr_prev = *attr; + } + + /* Get the partial configuration of the limit word */ + p_mpc->blk_idx = limit_word_idx; + word_value = p_mpc->blk_lutn & limit_word_mask; + if(word_value == 0x00000000) { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } else if(word_value ^ first_word_mask) { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } else { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + + if(*attr != attr_prev) { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev, + uint32_t* ctrl_val) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if(ctrl_val == 0) { + return MPC_SIE_INVALID_ARG; + } + + *ctrl_val = p_mpc->ctrl; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev, + uint32_t mpc_ctrl) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + p_mpc->ctrl = mpc_ctrl; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev, + enum mpc_sie_sec_resp_t* sec_rep) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + bool gating_present = false; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if(sec_rep == NULL) { + return MPC_SIE_INVALID_ARG; + } + + if (dev->data->sie_version == SIE200) { + if(p_mpc->ctrl & MPC_SIE200_CTRL_SEC_RESP) { + *sec_rep = MPC_SIE_RESP_BUS_ERROR; + } else { + *sec_rep = MPC_SIE_RESP_RAZ_WI; + } + + } else if (dev->data->sie_version == SIE300) { + mpc_sie_is_gating_present(dev, &gating_present); + if (!gating_present) { + return MPC_SIE_ERR_GATING_NOT_PRESENT; + } + + if(p_mpc->ctrl & MPC_SIE300_CTRL_SEC_RESP) { + /* MPC returns a BUS ERROR response */ + *sec_rep = MPC_SIE_RESP_BUS_ERROR; + } else { + /* MPC sets the ready signals LOW, which stalls any transactions */ + *sec_rep = MPC_SIE_RESP_WAIT_GATING_DISABLED; + } + } else { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev, + enum mpc_sie_sec_resp_t sec_rep) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + bool gating_present = false; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if (dev->data->sie_version == SIE200) { + if (sec_rep == MPC_SIE_RESP_BUS_ERROR) { + p_mpc->ctrl |= MPC_SIE200_CTRL_SEC_RESP; + } else if (sec_rep == MPC_SIE_RESP_RAZ_WI) { + p_mpc->ctrl &= ~MPC_SIE200_CTRL_SEC_RESP; + } else { + return MPC_SIE_INVALID_ARG; + } + + } else if (dev->data->sie_version == SIE300) { + mpc_sie_is_gating_present(dev, &gating_present); + if (!gating_present) { + return MPC_SIE_ERR_GATING_NOT_PRESENT; + } + + if (sec_rep == MPC_SIE_RESP_BUS_ERROR) { + p_mpc->ctrl |= MPC_SIE300_CTRL_SEC_RESP; + } else if (sec_rep == MPC_SIE_RESP_WAIT_GATING_DISABLED) { + p_mpc->ctrl &= ~MPC_SIE300_CTRL_SEC_RESP; + } else { + return MPC_SIE_INVALID_ARG; + } + + } else { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + p_mpc->int_en |= MPC_SIE_INT_BIT; + + return MPC_SIE_ERR_NONE; +} + +void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + p_mpc->int_en &= ~MPC_SIE_INT_BIT; +} + +void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + p_mpc->int_clear = MPC_SIE_INT_BIT; +} + +uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + return (p_mpc->int_stat & MPC_SIE_INT_BIT); +} + +enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + p_mpc->ctrl |= (MPC_SIE_CTRL_AUTOINCREMENT + | MPC_SIE_CTRL_SEC_LOCK_DOWN); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev, + bool* gating_present) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + if(dev->data->is_initialized != true) { + return MPC_SIE_NOT_INIT; + } + + if (dev->data->sie_version != SIE300) { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + *gating_present = (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_PRESENT); + + return MPC_SIE_ERR_NONE; +} + +uint32_t get_sie_version(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + return p_mpc->pidr0 & MPC_PIDR0_SIE_VERSION_MASK; +} + +bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + return (bool)(p_mpc->ctrl & MPC_SIE300_CTRL_GATE_ACK); +} + +void mpc_sie_request_gating(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + p_mpc->ctrl |= MPC_SIE300_CTRL_GATE_REQ; +} + +void mpc_sie_release_gating(struct mpc_sie_dev_t* dev) +{ + struct mpc_sie_reg_map_t* p_mpc = + (struct mpc_sie_reg_map_t*)dev->cfg->base; + + p_mpc->ctrl &= ~MPC_SIE300_CTRL_GATE_REQ; +} diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.h new file mode 100644 index 0000000000..927d0a80d5 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpc_sie_drv.h @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2016-2019 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. + */ + +/** + * \file mpc_sie_drv.h + * \brief Generic driver for ARM SIE Memory Protection + * Controllers (MPC). + */ + +#ifndef __MPC_SIE__DRV_H__ +#define __MPC_SIE__DRV_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error code returned by the driver functions */ +enum mpc_sie_error_t { + MPC_SIE_ERR_NONE, /*!< No error */ + MPC_SIE_INVALID_ARG, /*!< MPC invalid input arguments */ + MPC_SIE_NOT_INIT, /*!< MPC not initialized */ + MPC_SIE_ERR_NOT_IN_RANGE, /*!< Address does not belong to a range + * controlled by the MPC */ + MPC_SIE_ERR_NOT_ALIGNED, /*!< Address is not aligned on the block size + * of this MPC + */ + MPC_SIE_ERR_INVALID_RANGE, /*!< The given address range to configure + * is invalid. This could be because: + * - The base and limit swapped + * - The base and limit addresses + * are in different ranges + */ + MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be + * accessed with the wanted + * security attributes + */ + MPC_SIE_UNSUPPORTED_HARDWARE_VERSION, /*!< MPC hardware version read from + * PIDR0 is not supported + */ + MPC_SIE_ERR_GATING_NOT_PRESENT /*!< MPC gating not present in HW */ +}; + +/* Security attribute used in various place of the API */ +enum mpc_sie_sec_attr_t { + MPC_SIE_SEC_ATTR_SECURE, /*!< Secure attribute */ + MPC_SIE_SEC_ATTR_NONSECURE, /*!< Non-secure attribute */ + /*!< Used when getting the configuration of a memory range and some blocks + * are secure whereas some other are non secure + */ + MPC_SIE_SEC_ATTR_MIXED, +}; + +/* What can happen when trying to do an illegal memory access */ +enum mpc_sie_sec_resp_t { + MPC_SIE_RESP_RAZ_WI, /*!< Read As Zero, Write Ignored */ + MPC_SIE_RESP_BUS_ERROR, /*!< Bus error */ + MPC_SIE_RESP_WAIT_GATING_DISABLED /*!< Wait until gating is disabled */ +}; + +/* Description of a memory range controlled by the MPC */ +struct mpc_sie_memory_range_t { + const uint32_t base; /*!< Base address (included in the range) */ + const uint32_t limit; /*!< Limit address (included in the range) */ + const uint32_t range_offset; /*!< Offset of current range area to the 0 + * point of the whole area (the sum of the + * sizes of the previous memory ranges + * covered by the same MPC) + */ + const enum mpc_sie_sec_attr_t attr; /*!< Optional security attribute + * needed to be matched when + * accessing this range. + * For example, the non-secure + * alias of a memory region can not + * be accessed using secure access, + * and configuring the MPC to + * secure using that range will not + * be permitted by the driver. + */ +}; + +/* ARM MPC SIE device configuration structure */ +struct mpc_sie_dev_cfg_t { + const uint32_t base; /*!< MPC base address */ +}; + +/* ARM MPC SIE device data structure */ +struct mpc_sie_dev_data_t { + /*!< Array of pointers to memory ranges controlled by the MPC */ + const struct mpc_sie_memory_range_t** range_list; + uint8_t nbr_of_ranges; /*!< Number of memory ranges in the list */ + bool is_initialized; /*!< Indicates if the MPC driver + * is initialized and enabled + */ + uint32_t sie_version; /*!< SIE version */ +}; + +/* ARM MPC SIE device structure */ +struct mpc_sie_dev_t { + const struct mpc_sie_dev_cfg_t* const cfg; /*!< MPC configuration */ + struct mpc_sie_dev_data_t* const data; /*!< MPC data */ +}; + +/** + * \brief Initializes a MPC device. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] range_list List of memory ranges controller by the MPC + * (\ref mpc_sie_memory_range_t). This list can not + * freed after the initializations. + * \param[in] nbr_of_ranges Number of memory ranges + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t* dev, + const struct mpc_sie_memory_range_t** range_list, + uint8_t nbr_of_ranges); + +/** + * \brief Gets MPC block size. All regions must be aligned on this block + * size (base address and limit+1 address). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] blk_size MPC block size + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t* dev, + uint32_t* blk_size); + +/** + * \brief Configures a memory region (base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] base Base address of the region to poll. This bound is + * included. It does not need to be aligned in any way. + * + * \param[in] limit Limit address of the region to poll. This bound is + * included. (limit+1) does not need to be aligned + * in any way. + * \param[in] attr Security attribute of the region. If the region has mixed + * secure/non-secure, a special value is returned + * (\ref mpc_sie_sec_attr_t). + * + * In case base and limit+1 addresses are not aligned on + * the block size, the enclosing region with base and + * limit+1 aligned on block size will be queried. + * In case of early termination of the function (error), the + * security attribute will be set to MPC_SIE_ATTR_MIXED. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t* dev, + const uint32_t base, + const uint32_t limit, + enum mpc_sie_sec_attr_t attr); + +/** + * \brief Gets a memory region configuration(base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] base Base address of the region to get the configuration. + * \param[in] limit Limit address of the region to get the configuration. + * \param[out] attr Security attribute of the region + * \ref mpc_sie_sec_attr_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_region_config(struct mpc_sie_dev_t* dev, + uint32_t base, + uint32_t limit, + enum mpc_sie_sec_attr_t* attr); + +/** + * \brief Gets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] ctrl_val Current MPC control value. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t* dev, + uint32_t* ctrl_val); + +/** + * \brief Sets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] mpc_ctrl New MPC control value + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t* dev, + uint32_t mpc_ctrl); + +/** + * \brief Gets the configured secure response. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] sec_rep Configured secure response (\ref mpc_sie_sec_resp_t). + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t* dev, + enum mpc_sie_sec_resp_t* sec_rep); + +/** + * \brief Sets the response type when SW asks to gate the incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] sec_rep Secure response to configure (\ref mpc_sie_sec_resp_t). + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t* dev, + enum mpc_sie_sec_resp_t sec_rep); + +/** + * \brief Enables MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t* dev); + +/** + * \brief Disables MPC interrupt + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_irq_disable(struct mpc_sie_dev_t* dev); + +/** + * \brief Clears MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_clear_irq(struct mpc_sie_dev_t* dev); + +/** + * \brief Returns the MPC interrupt state. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns 1 if the interrupt is active, 0 otherwise. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t* dev); + +/** + * \brief Locks down the MPC configuration. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t* dev); + +/** + * \brief Returns if gating is present in hardware. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] gating_present Returns if gating is present in hardware. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t* dev, + bool* gating_present); + +/** + * \brief Returns the value of Peripheral ID 0 register. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns the value of Peripheral ID 0 register. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t get_sie_version(struct mpc_sie_dev_t* dev); + +/** + * \brief Reads bit indicating acknowledge for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return True if acknowledge is set. + * + * \note This function doesn't check if dev is NULL. + */ +bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t* dev); + +/** + * \brief Sets bit to request for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_request_gating(struct mpc_sie_dev_t* dev); + +/** + * \brief Clears bit to request for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_release_gating(struct mpc_sie_dev_t* dev); + +#ifdef __cplusplus +} +#endif +#endif /* __MPC_SIE_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.c new file mode 100644 index 0000000000..3121224e23 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "mpu_armv8m_drv.h" +#include "cmsis.h" + +/* + * FixMe: + * This is a beta quality driver for MPU in v8M. To be finalized. + */ + +enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev, + uint32_t privdef_en, + uint32_t hfnmi_en) +{ + /*No error checking*/ + + MPU_Type *mpu = (MPU_Type *)dev->base; + + /* + * FixMe: Set 3 pre-defined MAIR_ATTR for memory. The attributes come + * from default memory map, need to check if fine-tune is necessary. + * + * MAIR0_0: Peripheral, Device-nGnRE. + * MAIR0_1: Code, WT RA. Same attr for Outer and Inner. + * MAIR0_2: SRAM, WBWA RA. Same attr for Outer and Inner. + */ + mpu->MAIR0 = (MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL << MPU_MAIR0_Attr0_Pos) | + (MPU_ARMV8M_MAIR_ATTR_CODE_VAL << MPU_MAIR0_Attr1_Pos) | + (MPU_ARMV8M_MAIR_ATTR_DATA_VAL << MPU_MAIR0_Attr2_Pos); + + mpu->CTRL = + (privdef_en ? MPU_CTRL_PRIVDEFENA_Msk : 0) | + (hfnmi_en ? MPU_CTRL_HFNMIENA_Msk : 0); + + /*Ensure all configuration is written before enable*/ + + mpu->CTRL |= MPU_CTRL_ENABLE_Msk; + + /* Enable MPU before next instruction */ + __DSB(); + __ISB(); + return MPU_ARMV8M_OK; +} + +enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev) +{ + MPU_Type *mpu = (MPU_Type *)dev->base; + + /* Reset all fields as enable does full setup */ + mpu->CTRL = 0; + + return MPU_ARMV8M_OK; +} + + +enum mpu_armv8m_error_t mpu_armv8m_region_enable( + struct mpu_armv8m_dev_t *dev, + struct mpu_armv8m_region_cfg_t *region_cfg) +{ + MPU_Type *mpu = (MPU_Type *)dev->base; + + enum mpu_armv8m_error_t ret_val = MPU_ARMV8M_OK; + uint32_t ctrl_before; + uint32_t base_cfg; + uint32_t limit_cfg; + + /*FIXME : Add complete error checking*/ + if ((region_cfg->region_base & ~MPU_RBAR_ADDR_Msk) != 0) { + return MPU_ARMV8M_ERROR; + } + /* region_limit doesn't need to be aligned but the scatter + * file needs to be setup to ensure that partitions do not overlap. + */ + + ctrl_before = mpu->CTRL; + mpu->CTRL = 0; + + mpu->RNR = region_cfg->region_nr & MPU_RNR_REGION_Msk; + + /* This 0s the lower bits of the base address */ + base_cfg = region_cfg->region_base & MPU_RBAR_ADDR_Msk; + base_cfg |= (region_cfg->attr_sh << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk; + base_cfg |= (region_cfg->attr_access << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk; + base_cfg |= (region_cfg->attr_exec << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk; + + mpu->RBAR = base_cfg; + + /*This 0s the lower bits of base address but they are treated as 1 */ + limit_cfg = (region_cfg->region_limit-1) & MPU_RLAR_LIMIT_Msk; + + limit_cfg |= (region_cfg->region_attridx << MPU_RLAR_AttrIndx_Pos) & + MPU_RLAR_AttrIndx_Msk; + + limit_cfg |= MPU_RLAR_EN_Msk; + + mpu->RLAR = limit_cfg; + + /*Restore main MPU control*/ + mpu->CTRL = ctrl_before; + + /* Enable MPU before the next instruction */ + __DSB(); + __ISB(); + + return ret_val; +} + + +enum mpu_armv8m_error_t mpu_armv8m_region_disable( + struct mpu_armv8m_dev_t *dev, + uint32_t region_nr) +{ + + MPU_Type *mpu = (MPU_Type *)dev->base; + + enum mpu_armv8m_error_t ret_val = MPU_ARMV8M_OK; + uint32_t ctrl_before; + + /*FIXME : Add complete error checking*/ + + ctrl_before = mpu->CTRL; + mpu->CTRL = 0; + + mpu->RNR = region_nr & MPU_RNR_REGION_Msk; + + mpu->RBAR = 0; + mpu->RLAR = 0; + + /*Restore main MPU control*/ + mpu->CTRL = ctrl_before; + + return ret_val; +} + +enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev) +{ + MPU_Type *mpu = (MPU_Type *)dev->base; + uint32_t i = (mpu->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; + + while (i > 0) { + mpu_armv8m_region_disable(dev, i-1); + i--; + } + + return MPU_ARMV8M_OK; + +} diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.h new file mode 100644 index 0000000000..d427604f38 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/mpu_armv8m_drv.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017-2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __MPU_ARMV8M_DRV_H__ +#define __MPU_ARMV8M_DRV_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define PRIVILEGED_DEFAULT_ENABLE 1 +#define HARDFAULT_NMI_ENABLE 1 + +/* MAIR_ATTR */ +#define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL 0x04 +#define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX 0 +#define MPU_ARMV8M_MAIR_ATTR_CODE_VAL 0xAA +#define MPU_ARMV8M_MAIR_ATTR_CODE_IDX 1 +#define MPU_ARMV8M_MAIR_ATTR_DATA_VAL 0xFF +#define MPU_ARMV8M_MAIR_ATTR_DATA_IDX 2 + +struct mpu_armv8m_dev_t { + const uint32_t base; +}; + +enum mpu_armv8m_error_t { + MPU_ARMV8M_OK, + MPU_ARMV8M_ERROR +}; + +enum mpu_armv8m_attr_exec_t { + MPU_ARMV8M_XN_EXEC_OK, + MPU_ARMV8M_XN_EXEC_NEVER +}; + +enum mpu_armv8m_attr_access_t { + MPU_ARMV8M_AP_RW_PRIV_ONLY, + MPU_ARMV8M_AP_RW_PRIV_UNPRIV, + MPU_ARMV8M_AP_RO_PRIV_ONLY, + MPU_ARMV8M_AP_RO_PRIV_UNPRIV +}; + +enum mpu_armv8m_attr_shared_t { + MPU_ARMV8M_SH_NONE, + MPU_ARMV8M_SH_UNUSED, + MPU_ARMV8M_SH_OUTER, + MPU_ARMV8M_SH_INNER +}; + +struct mpu_armv8m_region_cfg_t { + uint32_t region_nr; + uint32_t region_base; + uint32_t region_limit; + uint32_t region_attridx; + enum mpu_armv8m_attr_exec_t attr_exec; + enum mpu_armv8m_attr_access_t attr_access; + enum mpu_armv8m_attr_shared_t attr_sh; +}; + +struct mpu_armv8m_region_cfg_raw_t { + uint32_t region_nr; + uint32_t region_base; + uint32_t region_limit; +}; + + +/** + * \brief Enable MPU + * + * \param[in] dev MPU device \ref mpu_armv8m_dev_t + * \param[in] privdef_en privilege default region 1:enable 0:disable + * \param[in] hfnmi_en mpu for hard fault & nmi 1:enable 0:disable + * + * \return Error code \ref mpu_armv8m_error_t + * + * \note This function doesn't check if dev is NULL. + */ + +enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev, + uint32_t privdef_en, + uint32_t hfnmi_en); + +/** + * \brief Disable MPU + * + * \param[in] dev MPU device \ref mpu_armv8m_dev_t + * + * \return Error code \ref arm_mpu_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev); + +/** + * \brief Disable MPU and clean all regions + * + * \param[in] dev MPU device \ref mpu_armv8m_dev_t + * + * \return Error code \ref arm_mpu_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev); + +/** + * \brief Enable MPU Region + * + * \param[in] dev MPU device \ref mpu_armv8m_dev_t + * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_t + * + * \return Error code \ref arm_mpu_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpu_armv8m_error_t mpu_armv8m_region_enable( + struct mpu_armv8m_dev_t *dev, + struct mpu_armv8m_region_cfg_t *region_cfg); + +/** + * \brief Disable MPU Region + * + * \param[in] dev MPU device \ref mpu_armv8m_dev_t + * \param[in] region_nr Region number + * + * \return Error code \ref arm_mpu_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpu_armv8m_error_t mpu_armv8m_region_disable( + struct mpu_armv8m_dev_t *dev, + uint32_t region_nr); + +#ifdef __cplusplus +} +#endif + +#endif /* __MPU_ARMV8M_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.c new file mode 100644 index 0000000000..38d068d745 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2019-2020 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 "ppc_sse300_drv.h" +#include <stdint.h> +#include <stdbool.h> + +/* Default peripheral states */ +#define SECURE_AS_DEFAULT_PERIPHERAL_STATE true +#define PRIVILEGE_ONLY_AS_DEFAULT_PERIPHERAL_STATE true + +/* Secure Access Configuration Register Block */ +struct sse300_sacfg_block_t { + volatile uint32_t reserved0[8]; + volatile uint32_t secppcintstat; /* 0x020 (R/ ) Secure PPC IRQ Status */ + volatile uint32_t secppcintclr; /* 0x024 (R/W) Secure PPC IRQ Clear */ + volatile uint32_t secppcinten; /* 0x028 (R/W) Secure PPC IRQ Enable */ + volatile uint32_t reserved1[9]; + volatile uint32_t mainnsppc0; /* 0x050 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Main + * Interconnect */ + volatile uint32_t reserved2[3]; + volatile uint32_t mainnsppcexp0; /* 0x060 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp1; /* 0x064 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp2; /* 0x068 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp3; /* 0x06C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t periphnsppc0; /* 0x070 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Peripheral + * Interconnect */ + volatile uint32_t periphnsppc1; /* 0x074 (R/W) Non-secure Access + * Peripheral Protection + * Control 1 on the Peripheral + * Interconnect */ + volatile uint32_t reserved3[2]; + volatile uint32_t periphnsppcexp0;/* 0x080 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp1;/* 0x084 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp2;/* 0x088 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp3;/* 0x08C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t mainspppc0; /* 0x090 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on Main + * Interconnect */ + volatile uint32_t reserved4[3]; + volatile uint32_t mainspppcexp0; /* 0x0A0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp1; /* 0x0A4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp2; /* 0x0A8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp3; /* 0x0AC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphspppc0; /* 0x0B0 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphspppc1; /* 0x0B4 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved5[2]; + volatile uint32_t periphspppcexp0;/* 0x0C0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp1;/* 0x0C4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp2;/* 0x0C8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp3;/* 0x0CC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved6[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved7[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* PPC interrupt position mask */ +#define PERIPH_PPC0_INT_POS_MASK (1UL << 0) +#define PERIPH_PPC1_INT_POS_MASK (1UL << 1) +#define PERIPH_PPCEXP0_INT_POS_MASK (1UL << 4) +#define PERIPH_PPCEXP1_INT_POS_MASK (1UL << 5) +#define PERIPH_PPCEXP2_INT_POS_MASK (1UL << 6) +#define PERIPH_PPCEXP3_INT_POS_MASK (1UL << 7) +#define MAIN_PPC0_INT_POS_MASK (1UL << 16) +#define MAIN_PPCEXP0_INT_POS_MASK (1UL << 20) +#define MAIN_PPCEXP1_INT_POS_MASK (1UL << 21) +#define MAIN_PPCEXP2_INT_POS_MASK (1UL << 22) +#define MAIN_PPCEXP3_INT_POS_MASK (1UL << 23) + +/* Non-secure Access Configuration Register Block */ +struct sse300_nsacfg_block_t { + volatile uint32_t reserved0[36]; + volatile uint32_t mainnspppc0; /* 0x090 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Main Interconnect */ + volatile uint32_t reserved1[3]; + + volatile uint32_t mainnspppcexp0; /* 0x0A0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp1; /* 0x0A4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp2; /* 0x0A8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp3; /* 0x0AC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphnspppc0; /* 0x0B0 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphnspppc1; /* 0x0B4 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved2[2]; + volatile uint32_t periphnspppcexp0;/* 0x0C0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp1;/* 0x0C4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp2;/* 0x0C8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp3;/* 0x0CC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved3[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved4[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +enum ppc_sse300_error_t ppc_sse300_init(struct ppc_sse300_dev_t* dev) +{ + struct sse300_sacfg_block_t* p_sacfg = + (struct sse300_sacfg_block_t*)dev->cfg->sacfg_base; + struct sse300_nsacfg_block_t* p_nsacfg = + (struct sse300_nsacfg_block_t*)dev->cfg->nsacfg_base; + + switch(dev->cfg->ppc_name) { + /* Case for MAIN0 */ + case PPC_SSE300_MAIN0: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppc0; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppc0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppc0; + dev->data->int_bit_mask = MAIN_PPC0_INT_POS_MASK; + break; + + /* Case for MAIN EXPX */ + case PPC_SSE300_MAIN_EXP0: + dev->data->sacfg_ns_ppc = &p_sacfg-> mainnsppcexp0; + dev->data->sacfg_sp_ppc = &p_sacfg-> mainspppcexp0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp0; + dev->data->int_bit_mask = MAIN_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP1: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp1; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp1; + dev->data->int_bit_mask = MAIN_PPCEXP1_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP2: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp2; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp2; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp2; + dev->data->int_bit_mask = MAIN_PPCEXP2_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP3: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp3; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp3; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp3; + dev->data->int_bit_mask = MAIN_PPCEXP3_INT_POS_MASK; + break; + + /* Case for PERIPHX */ + case PPC_SSE300_PERIPH0: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppc0; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppc0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc0; + dev->data->int_bit_mask = PERIPH_PPC0_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH1: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppc1; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppc1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc1; + dev->data->int_bit_mask = PERIPH_PPC1_INT_POS_MASK; + break; + + /* Case for PERIPH EXPX */ + case PPC_SSE300_PERIPH_EXP0: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp0; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp0; + dev->data->int_bit_mask = PERIPH_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP1: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp1; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp1; + dev->data->int_bit_mask = PERIPH_PPCEXP1_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP2: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp2; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp2; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp2; + dev->data->int_bit_mask = PERIPH_PPCEXP2_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP3: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp3; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp3; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp3; + dev->data->int_bit_mask = PERIPH_PPCEXP3_INT_POS_MASK; + break; + default: + return PPC_SSE300_ERR_INVALID_PARAM; + } + + dev->data->is_initialized = true; + + return PPC_SSE300_ERR_NONE; +} + +enum ppc_sse300_error_t +ppc_sse300_config_privilege(struct ppc_sse300_dev_t* dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr, + enum ppc_sse300_priv_attr_t priv_attr) +{ + if(dev->data->is_initialized != true) { + return PPC_SSE300_ERR_NOT_INIT; + } + + if(sec_attr == PPC_SSE300_SECURE_ACCESS) { +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + /* Uses secure unprivileged access address (SACFG) to set privilege + * attribute + */ + if(priv_attr == PPC_SSE300_PRIV_ONLY_ACCESS) { + *(dev->data->sacfg_sp_ppc) &= ~mask; + } else { + *(dev->data->sacfg_sp_ppc) |= mask; + } +#else + /* Configuring security from Non-Secure application is not permitted. */ + return PPC_SSE300_ERR_NOT_PERMITTED; +#endif + } else { + /* Uses non-secure unprivileged access address (NSACFG) to set + * privilege attribute */ + if(priv_attr == PPC_SSE300_PRIV_ONLY_ACCESS) { + *(dev->data->nsacfg_nsp_ppc) &= ~mask; + } else { + *(dev->data->nsacfg_nsp_ppc) |= mask; + } + } + + return PPC_SSE300_ERR_NONE; +} + +bool ppc_sse300_is_periph_priv_only(struct ppc_sse300_dev_t* dev, + uint32_t mask) +{ + if(dev->data->is_initialized != true) { + /* Return true as the default configuration is privilege only */ + return true; + } + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + /* In secure domain either secure or non-secure privilege access is returned + * based on the configuration */ + if ((*(dev->data->sacfg_ns_ppc) & mask) == 0) { + /* Returns secure unprivileged access (SACFG) */ + return ((*(dev->data->sacfg_sp_ppc) & mask) == 0); + } else { + /* Returns non-secure unprivileged access (NSACFG) */ + return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0); + } +#else + /* Returns non-secure unprivileged access (NSACFG) */ + return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0); +#endif +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +enum ppc_sse300_error_t +ppc_sse300_config_security(struct ppc_sse300_dev_t* dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr) +{ + if(dev->data->is_initialized != true) { + return PPC_SSE300_ERR_NOT_INIT; + } + + if(sec_attr == PPC_SSE300_SECURE_ACCESS) { + *(dev->data->sacfg_ns_ppc) &= ~mask; + } else { + *(dev->data->sacfg_ns_ppc) |= mask; + } + + return PPC_SSE300_ERR_NONE; +} + +bool ppc_sse300_is_periph_secure(struct ppc_sse300_dev_t* dev, + uint32_t mask) +{ + if(dev->data->is_initialized != true) { + /* Return true as the default configuration is secure */ + return true; + } + + return ((*(dev->data->sacfg_ns_ppc) & mask) == 0); +} + +enum ppc_sse300_error_t ppc_sse300_irq_enable(struct ppc_sse300_dev_t* dev) +{ + struct sse300_sacfg_block_t* p_sacfg = + (struct sse300_sacfg_block_t*)dev->cfg->sacfg_base; + + if(dev->data->is_initialized != true) { + return PPC_SSE300_ERR_NOT_INIT; + } + + p_sacfg->secppcinten |= dev->data->int_bit_mask; + + return PPC_SSE300_ERR_NONE; +} + +void ppc_sse300_irq_disable(struct ppc_sse300_dev_t* dev) +{ + struct sse300_sacfg_block_t* p_sacfg = + (struct sse300_sacfg_block_t*)dev->cfg->sacfg_base; + + if(dev->data->is_initialized == true) { + p_sacfg->secppcinten &= ~(dev->data->int_bit_mask); + } +} + +void ppc_sse300_clear_irq(struct ppc_sse300_dev_t* dev) +{ + struct sse300_sacfg_block_t* p_sacfg = + (struct sse300_sacfg_block_t*)dev->cfg->sacfg_base; + + if(dev->data->is_initialized == true) { + p_sacfg->secppcintclr = dev->data->int_bit_mask; + } +} + +bool ppc_sse300_irq_state(struct ppc_sse300_dev_t* dev) +{ + struct sse300_sacfg_block_t* p_sacfg = + (struct sse300_sacfg_block_t*)dev->cfg->sacfg_base; + + if(dev->data->is_initialized != true) { + return false; + } + + return ((p_sacfg->secppcintstat & dev->data->int_bit_mask) != 0); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.h new file mode 100644 index 0000000000..a3f7e1d700 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/ppc_sse300_drv.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +/** + * \file ppc_sse300_drv.h + * \brief Generic driver for SSE-300 Peripheral Protection Controllers (PPC). + */ + +#ifndef __PPC_SSE_300_DRV_H__ +#define __PPC_SSE_300_DRV_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSE-300 PPC names */ +enum ppc_sse300_name_t { + PPC_SSE300_MAIN0 = 0, /*!< MAIN PPC 0 */ + PPC_SSE300_MAIN_EXP0, /*!< Expansion 0 MAIN PPC */ + PPC_SSE300_MAIN_EXP1, /*!< Expansion 1 MAIN PPC */ + PPC_SSE300_MAIN_EXP2, /*!< Expansion 2 MAIN PPC */ + PPC_SSE300_MAIN_EXP3, /*!< Expansion 3 MAIN PPC */ + PPC_SSE300_PERIPH0, /*!< PERIPH PPC0 */ + PPC_SSE300_PERIPH1, /*!< PERIPH PPC1 */ + PPC_SSE300_PERIPH_EXP0, /*!< Expansion 0 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP1, /*!< Expansion 1 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP2, /*!< Expansion 2 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP3, /*!< Expansion 3 PERIPH PPC */ + SSE300_PPC_MAX_NUM +}; + +/* SSE-300 PPC device configuration structure */ +struct ppc_sse300_dev_cfg_t { + uint32_t const sacfg_base; /*!< Secure Privilege Control Block base */ + uint32_t const nsacfg_base; /*!< Non-Secure Privilege Control Block base */ + enum ppc_sse300_name_t ppc_name; +}; + +/* SSE-300 PPC device data structure */ +struct ppc_sse300_dev_data_t { + volatile uint32_t* sacfg_ns_ppc; /*!< Pointer to non-secure register */ + volatile uint32_t* sacfg_sp_ppc; /*!< Pointer to secure unprivileged + register */ + volatile uint32_t* nsacfg_nsp_ppc; /*!< Pointer to non-secure unprivileged + register */ + uint32_t int_bit_mask; /*!< Interrupt bit mask */ + bool is_initialized; /*!< Indicates if the PPC driver + is initialized */ +}; + +/* SSE-300 PPC device structure */ +struct ppc_sse300_dev_t { + const struct ppc_sse300_dev_cfg_t* const cfg; /*!< PPC configuration */ + struct ppc_sse300_dev_data_t* const data; /*!< PPC data */ +}; + +/* Security attribute used to configure the peripherals */ +enum ppc_sse300_sec_attr_t { + PPC_SSE300_SECURE_ACCESS = 0, /*! Secure access */ + PPC_SSE300_NONSECURE_ACCESS, /*! Non-secure access */ +}; + +/* Privilege attribute used to configure the peripherals */ +enum ppc_sse300_priv_attr_t { + PPC_SSE300_PRIV_AND_NONPRIV_ACCESS = 0, /*! Privilege and NonPrivilege + access */ + PPC_SSE300_PRIV_ONLY_ACCESS, /*! Privilege only access */ +}; + +/* ARM PPC error codes */ +enum ppc_sse300_error_t { + PPC_SSE300_ERR_NONE = 0, /*!< No error */ + PPC_SSE300_ERR_INVALID_PARAM, /*!< PPC invalid parameter error */ + PPC_SSE300_ERR_NOT_INIT, /*!< PPC not initialized */ + PPC_SSE300_ERR_NOT_PERMITTED /*!< PPC Operation not permitted */ +}; + +/** + * \brief Initialize the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_init(struct ppc_sse300_dev_t* dev); + +/** + * \brief Configures privilege attribute through the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * \param[in] sec_attr Secure attribute value. + * \param[in] priv_attr Privilege attribute value. + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t +ppc_sse300_config_privilege(struct ppc_sse300_dev_t* dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr, + enum ppc_sse300_priv_attr_t priv_attr); + +/** + * \brief Checks if the peripheral is configured as Privilege only or + * Privilege and non-Privilege access mode. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * + * \return Returns true for Privilege only configuration and false otherwise + * - with non-secure caller in the non-secure domain + * - with secure caller in the configured security domain + * If the driver is not initalized the return value of this function is + * true (Privilege only) as it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_is_periph_priv_only(struct ppc_sse300_dev_t* dev, + uint32_t mask); + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +/** + * \brief Configures security attribute through the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * \param[in] sec_attr Secure attribute value. + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t +ppc_sse300_config_security(struct ppc_sse300_dev_t* dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr); + +/** + * \brief Checks if the peripheral is configured as secure or non-secure. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * + * \return Returns true for secure and false for non-secure. + * If the driver is not initalized the return value is true (secure) as + * it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_is_periph_secure(struct ppc_sse300_dev_t* dev, + uint32_t mask); + +/** + * \brief Enables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_irq_enable(struct ppc_sse300_dev_t* dev); + +/** + * \brief Disables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse300_irq_disable(struct ppc_sse300_dev_t* dev); + +/** + * \brief Clears PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse300_clear_irq(struct ppc_sse300_dev_t* dev); + +/** + * \brief Returns the PPC interrupt state. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns true if the interrupt is active and otherwise false. + * If the driver is not initalized the return value of this function is + * false (not active) as it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_irq_state(struct ppc_sse300_dev_t* dev); + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE_300_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.c new file mode 100644 index 0000000000..832bb0292f --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * \file syscounter_armv8-m_cntrl_drv.c + * + * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase + * Frame + * + * This System Counter is a 64-bit up-counter, generating the physical + * count for System Timer. + * + * Main features: + * - Enabled/disable and Set/Get the 64-bit upcounter + * - 2 scaling register for the 2 clock sources + * - These registers are used to pre-program the scaling values so + * that when hardware based clock switching is implemented there is no + * need to program the scaling increment value each time when clock is + * switched. + * - When counter scaling is enabled, ScaleVal is the amount added to the + * Counter Count Value for every period of the counter as determined + * by 1/Frequency from the current operating frequency of the system + * counter (the “counter tick”). + * - ScaleVal is expressed as an unsigned fixed-point number with + * a 8 bit integer value and a 24-bit fractional value + * - Interrupt for error detection + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + */ + +#include "syscounter_armv8-m_cntrl_drv.h" + +/** Setter bit manipulation macro */ +#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX))) +/** Clearing bit manipulation macro */ +#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX))) +/** Getter bit manipulation macro */ +#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX)))) +/** Clear-and-Set bit manipulation macro */ +#define ASSIGN_BIT(WORD, BIT_INDEX, VALUE) \ + (WORD = ((WORD & ~(1U << (BIT_INDEX))) | (VALUE << (BIT_INDEX)))) +/** Getter bit-field manipulation macro */ +#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \ + ((WORD & BIT_MASK) >> BIT_OFFSET) +/** Bit mask for given width bit-field manipulation macro */ +#define BITMASK(width) ((1u<<(width))-1) + +/** + * \brief CNTControlBase Register map structure + */ +struct cnt_control_base_reg_map_t { + volatile uint32_t cntcr; + /*!< Offset: 0x000 (R/W) Counter Control Register */ + volatile const uint32_t cntsr; + /*!< Offset: 0x004 (RO) Counter Status Register */ + volatile uint32_t cntcv_low; + /*!< Offset: 0x008 (R/W) Counter Count Value [31:0] Register */ + volatile uint32_t cntcv_high; + /*!< Offset: 0x00C (R/W) Counter Count Value [63:32] Register */ + volatile uint32_t cntscr; + /*!< Offset: 0x010 (R/W) Counter Scale Register + * Aliased with CNTSCR0, meaning that either addresses of CNTSCR and + * CNTSCR0 will physically access a single register + */ + volatile const uint32_t reserved0[2]; + /*!< Offset: 0x014-0x018 Reserved (RAZWI) */ + volatile const uint32_t cntid; + /*!< Offset: 0x01C (RO) Counter ID Register */ + volatile const uint32_t reserved1[40]; + /*!< Offset: 0x020-0x0BC Reserved (RAZWI) */ + volatile const uint32_t reserved2[4]; + /*!< Offset: 0x0C0-0x0CC Reserved (RAZWI) */ + volatile uint32_t cntscr0; + /*!< Offset: 0x0D0 (R/W) Counter Scale Register 0 */ + volatile uint32_t cntscr1; + /*!< Offset: 0x0D4 (R/W) Counter Scale Register 1 */ + volatile const uint32_t reserved3[958]; + /*!< Offset: 0x0D8-0xFCC Reserved (RAZWI) */ + volatile const uint32_t cntpidr4; + /*!< Offset: 0xFD0 (RO) Peripheral ID Register */ + volatile const uint32_t reserved4[3]; + /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */ + volatile const uint32_t cntpidr0; + /*!< Offset: 0xFE0 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr1; + /*!< Offset: 0xFE4 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr2; + /*!< Offset: 0xFE8 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr3; + /*!< Offset: 0xFEC (RO) Peripheral ID Register */ + volatile const uint32_t cntcidr0; + /*!< Offset: 0xFF0 (RO) Component ID Register */ + volatile const uint32_t cntcidr1; + /*!< Offset: 0xFF4 (RO) Component ID Register */ + volatile const uint32_t cntcidr2; + /*!< Offset: 0xFF8 (RO) Component ID Register */ + volatile const uint32_t cntcidr3; + /*!< Offset: 0xFFC (RO) Component ID Register */ +}; + +/** + * \brief Counter Control Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTCR_EN_OFF 0u + /*!< Counter Control Register Enable Counter bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF 1u + /*!< Counter Control Register Halt On Debug bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF 2u + /*!< Counter Control Register Scale enable bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF 3u + /*!< Counter Control Register Interrupt mask bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF 4u + /*!< Counter Control Register PSLVERR disable bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF 5u + /*!< Counter Control Register Interrupt Clear bit field offset */ + +/** + * \brief Counter Status Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF 1u + /*!< Counter Status Register Halt-on-Debug bit field offset */ + +/** + * \brief Counter ID Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF 0u + /*!< Counter ID Register Counter Scaling is implemented bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF 16u + /*!< Counter ID Register Clock switching is implemented bit field offset */ + +/*! Counter ID Register Clock source */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF 17u +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH 2u +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK \ + (BITMASK(SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH) \ + << SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF) + +#define SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF 19u + /*!< Counter ID Register Override counter enable condition for + * writing to CNTSCR registers bit offset + */ + +enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + enum syscounter_armv8_m_cntrl_error_t result = SYSCOUNTER_ARMV8_M_ERR_NONE; + + if (dev->data->is_initialized == false) { + syscounter_armv8_m_cntrl_disable_counter(dev); + if (syscounter_armv8_m_cntrl_is_counter_scaling_implemented(dev)) { + result = syscounter_armv8_m_cntrl_set_counter_scale_value( + dev, SYSCOUNTER_ARMV8_M_SCALE_NR_0, dev->cfg->scale0); + if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) { + return result; + } + result = syscounter_armv8_m_cntrl_set_counter_scale_value( + dev, SYSCOUNTER_ARMV8_M_SCALE_NR_1, dev->cfg->scale1); + if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) { + return result; + } + } + syscounter_armv8_m_cntrl_set_counter_value(dev, + SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL); + syscounter_armv8_m_cntrl_disable_interrupt(dev); + syscounter_armv8_m_cntrl_disable_scale(dev); + + syscounter_armv8_m_cntrl_enable_counter(dev); + dev->data->is_initialized = true; + } + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} + +void syscounter_armv8_m_cntrl_uninit( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + if (dev->data->is_initialized == true) { + syscounter_armv8_m_cntrl_disable_counter(dev); + syscounter_armv8_m_cntrl_disable_interrupt(dev); + syscounter_armv8_m_cntrl_set_counter_value(dev, + SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL); + dev->data->is_initialized = false; + } +} + +void syscounter_armv8_m_cntrl_enable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +void syscounter_armv8_m_cntrl_disable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +bool syscounter_armv8_m_cntrl_is_counter_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +void syscounter_armv8_m_cntrl_enable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +void syscounter_armv8_m_cntrl_disable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +void syscounter_armv8_m_cntrl_enable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +void syscounter_armv8_m_cntrl_disable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +bool syscounter_armv8_m_cntrl_is_scale_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +void syscounter_armv8_m_cntrl_enable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +void syscounter_armv8_m_cntrl_disable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +bool syscounter_armv8_m_cntrl_is_interrupt_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +void syscounter_armv8_m_cntrl_enable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +void syscounter_armv8_m_cntrl_disable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +bool syscounter_armv8_m_cntrl_is_pslverr_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +void syscounter_armv8_m_cntrl_clear_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF); +} + +bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntsr, + SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF); +} + +uint64_t syscounter_armv8_m_cntrl_get_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + uint32_t high = 0; + uint32_t low = 0; + uint32_t high_prev = 0; + uint64_t value = 0; + + /* Make sure the 64-bit read will be atomic to avoid overflow between + * the low and high registers read + */ + high = p_cnt->cntcv_high; + do { + high_prev = high; + low = p_cnt->cntcv_low; + high = p_cnt->cntcv_high; + }while(high != high_prev); + + value = low | + (((uint64_t)high) << SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH); + return value; +} + +void syscounter_armv8_m_cntrl_set_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + uint64_t value) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + p_cnt->cntcv_low = value & UINT32_MAX; + p_cnt->cntcv_high = value >> SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH; +} + +bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF); +} + +bool syscounter_armv8_m_cntrl_is_clock_switching_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF); +} + +enum syscounter_armv8_m_cntrl_selclk_t +syscounter_armv8_m_cntrl_get_clock_source( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return (enum syscounter_armv8_m_cntrl_selclk_t) + GET_BIT_FIELD(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK, + SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF); +} + +enum syscounter_armv8_m_cntrl_cntscr_ovr_t +syscounter_armv8_m_cntrl_get_override_cntscr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return (enum syscounter_armv8_m_cntrl_cntscr_ovr_t) + GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF); +} + +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_get_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t *val) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + + switch (nr) { + case SYSCOUNTER_ARMV8_M_SCALE_NR_0: + val->integer = p_cnt->cntscr0 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + val->fixed_point_fraction = p_cnt->cntscr0 & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX; + break; + case SYSCOUNTER_ARMV8_M_SCALE_NR_1: + val->integer = p_cnt->cntscr1 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + val->fixed_point_fraction = p_cnt->cntscr1 & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX; + break; + default: + val->integer = 0; + val->fixed_point_fraction = 0; + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} + +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_set_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t val) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + uint32_t reg_val = 0; + + if ((syscounter_armv8_m_cntrl_get_override_cntscr(dev) == + SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED) && + syscounter_armv8_m_cntrl_is_counter_enabled(dev)) { + return SYSCOUNTER_ARMV8_M_ERR_INVALID; + } + if (val.integer > SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX || + val.fixed_point_fraction > SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX) { + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + reg_val = val.integer << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + reg_val |= (val.fixed_point_fraction & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX); + + switch (nr) { + case SYSCOUNTER_ARMV8_M_SCALE_NR_0: + p_cnt->cntscr0 = reg_val; + break; + case SYSCOUNTER_ARMV8_M_SCALE_NR_1: + p_cnt->cntscr1 = reg_val; + break; + default: + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h new file mode 100644 index 0000000000..e84786d23c --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/syscounter_armv8-m_cntrl_drv.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * \file syscounter_armv8-m_cntrl_drv.h + * + * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase + * Frame + * + * This System Counter is a 64-bit up-counter, generating the physical + * count for System Timer. + * + * Main features: + * - Enable/disable and Set/Get the 64-bit upcounter + * - 2 scaling registers for the 2 clock sources + * - These registers are used to pre-program the scaling values so + * that when hardware based clock switching is implemented there is no + * need to program the scaling increment value each time when clock is + * switched. + * - When counter scaling is enabled, ScaleVal is the value added to the + * Counter Count Value for every period of the counter as determined + * by 1/Frequency from the current operating frequency of the system + * counter (the “counter tick”). + * - ScaleVal is expressed as an unsigned fixed-point number with + * a 8 bit integer value and a 24-bit fractional value + * - Interrupt for error detection + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + */ + +#ifndef __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ +#define __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH 32u + /*!< Armv8-M System Counter Control registers bit width */ + +#define SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL 0u + /*!< Armv8-M System Counter Control default counter init value */ + +/** + * \brief Armv8-M System Counter Control scaling value + */ +struct syscounter_armv8_m_cntrl_scale_val_t { + uint32_t integer; /* 8 bit */ + uint32_t fixed_point_fraction; /* 24 bit */ +}; + +/** + * \brief Armv8-M System Counter Control scaling value macros * + * 8 bit integer and 24 bit fixed point fractional value + */ +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX UINT8_MAX +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF 24u +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX \ + ((1u << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF) - 1u) + +/** + * \brief Armv8-M System Counter Control device configuration structure + */ +struct syscounter_armv8_m_cntrl_dev_cfg_t { + const uint32_t base; + /*!< Armv8-M System Counter Control device base address */ + struct syscounter_armv8_m_cntrl_scale_val_t scale0; + /*!< Default clock scaling value for Clock source 0 */ + struct syscounter_armv8_m_cntrl_scale_val_t scale1; + /*!< Default clock scaling value for Clock source 1 */ +}; + +/** + * \brief Armv8-M System Counter Control device data structure + */ +struct syscounter_armv8_m_cntrl_dev_data_t { + bool is_initialized; +}; + +/** + * \brief Armv8-M System Counter Control device structure + */ +struct syscounter_armv8_m_cntrl_dev_t { + const struct syscounter_armv8_m_cntrl_dev_cfg_t* const cfg; + /*!< Armv8-M System Counter Control configuration structure */ + struct syscounter_armv8_m_cntrl_dev_data_t* const data; + /*!< Armv8-M System Counter Control data structure */ +}; + +/** + * \brief Armv8-M System Counter Control error enumeration types + */ +enum syscounter_armv8_m_cntrl_error_t { + SYSCOUNTER_ARMV8_M_ERR_NONE = 0u, + SYSCOUNTER_ARMV8_M_ERR_INVALID = 1u, + SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG = 2u +}; + +/** + * \brief Armv8-M System Counter Control scaling number for each clock sources + */ +enum syscounter_armv8_m_cntrl_scale_nr_t { + SYSCOUNTER_ARMV8_M_SCALE_NR_0 = 0u, + /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK0 */ + SYSCOUNTER_ARMV8_M_SCALE_NR_1 = 1u + /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK1 */ +}; + +/** + * \brief Clock select values + */ +enum syscounter_armv8_m_cntrl_selclk_t { + SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID0 = 0u, + /*!< Clock select invalid value */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK0 = 1u, + /*!< Clock select clock source 0 */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK1 = 2u, + /*!< Clock select clock source 1 */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID1 = 3u + /*!< Clock select invalid value */ +}; + +/** + * \brief Override counter enable condition for writing to CNTSCR registers + * + */ +enum syscounter_armv8_m_cntrl_cntscr_ovr_t { + SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED = 0u, + /*!< Scaling registers can be written only when counter is disabled */ + SYSCOUNTER_ARMV8_M_CNTSCR_ALWAYS = 1u + /*!< CNTSCR can be written regardless of counter enabled or disabled */ +}; + +/** + * \brief Initializes counter to a known default state, which is: + * - counter is enabled, so starts counting + * - interrupt is disabled + * - counter reset to default reset value + * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL + * - scaling is disabled + * - scaling registers are set to the set values: + * \ref struct syscounter_armv8_m_cntrl_dev_cfg_t + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Uninitializes counter to a known default state, which is: + * - counter is disabled, so stops counting + * - interrupt is disabled + * - counter reset to default reset value + * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL + * - scaling is disabled + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_uninit( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables the counter, so counter starts counting + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables the counter, so counter stops counting + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls counter enable status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables Halt-On-Debug feature + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables Halt-On-Debug feature + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls Halt-On-Debug enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables scaling + * The used scaling register is depending on the used HW clock source. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables scaling + * Counter count will be incremented by default 1 for each ticks. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls scaling enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_scale_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables interrupt + * + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables interrupt + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls interrupt enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_interrupt_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables PSLVERR output + * + * PSLVERR output signal on APB bus dynamically generated for the + * following error: + * For security attribute mismatch between register access and security + * attribute of the CONTROL frame + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables PSLVERR output + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls PSLVERR output enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_pslverr_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Clears interrupt pending flag + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_clear_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls Halt-On-Debug status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if counter is halted, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Read counter value + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return 64 bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t syscounter_armv8_m_cntrl_get_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Writes counter value + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] value 64 bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_set_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + uint64_t value); + +/** + * \brief Polls whether scaling is implemented + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls whether HW based clock switching is implemented + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_clock_switching_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads which clock source is being used + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Clock source \ref enum syscounter_armv8_m_cntrl_selclk_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_selclk_t + syscounter_armv8_m_cntrl_get_clock_source( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads scaling register can be overriden anytime + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_cntscr_ovr_t + syscounter_armv8_m_cntrl_get_override_cntscr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads scaling register + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] nr Index of scaling register to read + * \ref enum syscounter_armv8_m_cntrl_scale_nr_t + * \param[out] nr Pointer to structure to read the scale value + * \ref struct syscounter_armv8_m_cntrl_scale_val_t + * + * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_get_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t *val); + +/** + * \brief Writes scaling register + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] nr Index of scaling register to write + * \ref enum syscounter_armv8_m_cntrl_scale_nr_t + * \param[in] Scale value structure + * \ref struct syscounter_armv8_m_cntrl_scale_val_t + * + * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_set_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t val); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.c new file mode 100644 index 0000000000..c7b4b153ac --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +/** + * \file systimer_armv8-m_drv.c + * + * \brief Driver for Armv8-M System Timer + * + */ + +#include "systimer_armv8-m_drv.h" + +/** Setter bit manipulation macro */ +#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1u << (BIT_INDEX))) +/** Clearing bit manipulation macro */ +#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1u << (BIT_INDEX))) +/** Getter bit manipulation macro */ +#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1u << (BIT_INDEX)))) +/** Getter bit-field manipulation macro */ +#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \ + ((WORD & BIT_MASK) >> BIT_OFFSET) +/** Bit mask for given width bit-field manipulation macro */ +#define BITMASK(width) ((1u<<(width))-1) + +/** + * \brief CNTBase Register map structure + */ +struct cnt_base_reg_map_t { + volatile const uint32_t cntpct_low; + /*!< Offset: 0x000 (RO) Current Physical Counter Value [31:0] */ + volatile const uint32_t cntpct_high; + /*!< Offset: 0x004 (RO) Current Physical Counter Value [63:32] */ + volatile const uint32_t reserved0[2]; + /*!< Offset: 0x008-0x0C Reserved */ + volatile uint32_t cntfrq; + /*!< Offset: 0x010 (R/W) Counter Frequency register in Hz */ + volatile const uint32_t reserved1[3]; + /*!< Offset: 0x014-0x01C Reserved */ + volatile uint32_t cntp_cval_low; + /*!< Offset: 0x020 (R/W) Timer Compare Value register [31:0] */ + volatile uint32_t cntp_cval_high; + /*!< Offset: 0x024 (R/W) Timer Compare Value register [63:32] */ + volatile uint32_t cntp_tval; + /*!< Offset: 0x028 (R/W) Timer Value register */ + volatile uint32_t cntp_ctl; + /*!< Offset: 0x02C (R/W) Timer Control register */ + volatile const uint32_t reserved2[4]; + /*!< Offset: 0x030-0x03C Reserved */ + volatile const uint32_t cntp_aival_low; + /*!< Offset: 0x040 (RO) Auto Increment Value register [31:0]*/ + volatile const uint32_t cntp_aival_high; + /*!< Offset: 0x044 (RO) Auto Increment Value register [63:32]*/ + volatile uint32_t cntp_aival_reload; + /*!< Offset: 0x048 (R/W) Auto Increment Value Reload register [63:32]*/ + volatile uint32_t cntp_aival_ctl; + /*!< Offset: 0x04C (R/W) Auto Increment Control register */ + volatile const uint32_t cntp_cfg; + /*!< Offset: 0x050 (RO) Timer Configuration register */ + volatile const uint32_t reserved3[991]; + /*!< Offset: 0x054-0xFCC Reserved */ + volatile const uint32_t cntp_pid4; + /*!< Offset: 0xFD0 (RO) Peripheral ID Register */ + volatile const uint32_t reserved4[3]; + /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */ + volatile const uint32_t cntp_pid0; + /*!< Offset: 0xFE0 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid1; + /*!< Offset: 0xFE4 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid2; + /*!< Offset: 0xFE8 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid3; + /*!< Offset: 0xFEC (RO) Peripheral ID Register */ + volatile const uint32_t cntp_cid0; + /*!< Offset: 0xFF0 (RO) Component ID Register */ + volatile const uint32_t cntp_cid1; + /*!< Offset: 0xFF4 (RO) Component ID Register */ + volatile const uint32_t cntp_cid2; + /*!< Offset: 0xFF8 (RO) Component ID Register */ + volatile const uint32_t cntp_cid3; + /*!< Offset: 0xFFC (RO) Component ID Register */ +}; + +/** + * \brief Timer Control Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF 0u + /*!< Timer Control Register Enable Counter bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF 1u +/*!< Timer Control Register Interrupt Mask bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF 2u +/*!< Timer Control Register Interrupt Status bit field offset */ + +/** + * \brief Timer AutoInc Control Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF 0u + /*!< Timer Control Register Enable Counter bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF 1u +/*!< Timer Control Register Interrupt clear bit field offset */ + +/** + * \brief Timer AutoInc Config Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF 0u + /*!< Timer Control Register AutoInc is implemented bit field offset */ + + +void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev) +{ + if (dev->data->is_initialized == false) { + systimer_armv8_m_disable_interrupt(dev); + systimer_armv8_m_disable_autoinc(dev); + systimer_armv8_m_set_counter_freq(dev, dev->cfg->default_freq_hz); + systimer_armv8_m_enable_timer(dev); + dev->data->is_initialized = true; + } +} + +void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev) +{ + if (dev->data->is_initialized == true) { + systimer_armv8_m_disable_interrupt(dev); + systimer_armv8_m_disable_autoinc(dev); + systimer_armv8_m_disable_timer(dev); + dev->data->is_initialized = false; + } +} + +uint64_t systimer_armv8_m_get_counter_value( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + uint32_t high = 0; + uint32_t low = 0; + uint32_t high_prev = 0; + uint64_t value = 0; + + /* Make sure the 64-bit read will be atomic to avoid overflow between + * the low and high registers read + */ + high = p_cnt->cntpct_high; + do { + high_prev = high; + low = p_cnt->cntpct_low; + high = p_cnt->cntpct_high; + }while(high != high_prev); + + value = low | (((uint64_t)high) << SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_compare_value( + struct systimer_armv8_m_dev_t* dev, + uint64_t value) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + p_cnt->cntp_cval_low = value & UINT32_MAX; + p_cnt->cntp_cval_high = value >> SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH; +} + +uint64_t systimer_armv8_m_get_compare_value( + struct systimer_armv8_m_dev_t* dev) +{ + uint64_t value = 0; + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + value = p_cnt->cntp_cval_low | + (((uint64_t)p_cnt->cntp_cval_high) << + SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_counter_freq(struct systimer_armv8_m_dev_t* dev, + uint32_t value) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + p_cnt->cntfrq = value; +} + +uint32_t systimer_armv8_m_get_counter_freq( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return p_cnt->cntfrq; +} + +void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev, + uint32_t value) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + p_cnt->cntp_tval = value; +} + +uint32_t systimer_armv8_m_get_timer_value( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return p_cnt->cntp_tval; +} + +void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +bool systimer_armv8_m_is_timer_enabled( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +void systimer_armv8_m_enable_interrupt( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +void systimer_armv8_m_disable_interrupt( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +bool systimer_armv8_m_is_interrupt_enabled( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + return !GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +bool systimer_armv8_m_is_interrupt_asserted( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF); +} + +uint64_t systimer_armv8_m_get_autoinc_value( + struct systimer_armv8_m_dev_t* dev) +{ + uint64_t value = 0; + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + value = p_cnt->cntp_aival_low | + (((uint64_t)p_cnt->cntp_aival_high) << + SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_autoinc_reload( + struct systimer_armv8_m_dev_t* dev, + uint32_t value) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + p_cnt->cntp_aival_reload = value; +} + +uint32_t systimer_armv8_m_get_autoinc_reload( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return p_cnt->cntp_aival_reload; +} + +void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +bool systimer_armv8_m_is_autoinc_enabled( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntp_aival_ctl, + SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +void systimer_armv8_m_clear_autoinc_interrupt( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF); +} + +bool systimer_armv8_m_is_autoinc_implemented( + struct systimer_armv8_m_dev_t* dev) +{ + struct cnt_base_reg_map_t* p_cnt = + (struct cnt_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntp_cfg, + SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF); +} + diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.h new file mode 100644 index 0000000000..d14d2f79e2 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/systimer_armv8-m_drv.h @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2019 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. + */ + +/** + * \file systimer_armv8-m_drv.h + * + * \brief Driver for Armv8-M System Timer + * + * This System Timer is based on the 64-bit Armv8-M System Counter, + * generating the physical count for System Timer. + * + * Main features: + * - Disabling the timer doesn't stop counting, but it disables timer output + * signal, what might be a power saving option. + * - 1 interrupt signal, can be triggered by the 2 modes below + * Modes: + * 1. Normal mode + * For clearing the interrupt generated by normal mode, the Timer + * should be disabled. + * Views + * 1.1. 64-bit up-counting Compare view + * As soon as the physical up-counter reaches the set + * compare value, the interrupt status will be asserted. + * \ref systimer_armv8_m_set_compare_value + * \ref systimer_armv8_m_get_compare_value + + * 1.2. 32-bit down-counting Timer view + * As soon as the down-counter timer reaches zero, + * the interrupt status will be asserted. + * Setting the down-counter timer value, sets the compare + * register by + * compare register = current counter + timer value + * \ref systimer_armv8_m_set_timer_value + * \ref systimer_armv8_m_get_timer_value + * + * 2. Auto-Increment mode + * - The auto-increment feature allows generation of Timer + * interrupt at regular intervals without the need for + * reprogramming the Timer after each interrupt and re-enabling + * the timer logic. + * - Auto-increment is working as a 64-bit up-counter, which is set + * by the 32-bit reload register. + * - If auto-increment mode is enabled, none of the normal modes' + * views can assert interrupt. * + * \ref systimer_armv8_m_get_autoinc_value + * \ref systimer_armv8_m_set_autoinc_reload + * \ref systimer_armv8_m_enable_autoinc + * \ref systimer_armv8_m_disable_autoinc + * \ref systimer_armv8_m_is_autoinc_enabled + * \ref systimer_armv8_m_clear_autoinc_interrupt + * \ref systimer_armv8_m_is_autoinc_implemented + * + */ + +#ifndef __SYSTIMER_ARMV8_M_DRV_H__ +#define __SYSTIMER_ARMV8_M_DRV_H__ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH 32u + /*!< Armv8-M System Timer registers bit width */ + +/** + * \brief Armv8-M System Timer device configuration structure + */ +struct systimer_armv8_m_dev_cfg_t { + const uint32_t base; + /*!< Armv8-M System Timer device base address */ + uint32_t default_freq_hz; + /*!< Default reported frequency in Hz */ +}; + +/** + * \brief Armv8-M System Timer device data structure + */ +struct systimer_armv8_m_dev_data_t { + bool is_initialized; +}; + +/** + * \brief Armv8-M System Timer device structure + */ +struct systimer_armv8_m_dev_t { + const struct systimer_armv8_m_dev_cfg_t* const cfg; + /*!< Armv8-M System Timer configuration structure */ + struct systimer_armv8_m_dev_data_t* const data; + /*!< Armv8-M System Timer data structure */ +}; + +/** + * \brief Initializes timer to a known default state, which is: + * - timer is enabled + * - interrupt is disabled + * - auto-increment is disabled + * - reported timer frequency is set to default + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Uninitializes timer to a known default state, which is: + * - timer is disabled + * - interrupt is disabled + * - auto-increment is disabled + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Reads 64-bit physical counter value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_counter_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 64-bit compare value + * As soon as the physical up-counter reaches this value, the interrupt + * condition will be asserted \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 64-bit compare value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_compare_value( + struct systimer_armv8_m_dev_t* dev, + uint64_t value); + +/** + * \brief Reads 64-bit compare value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit compare value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_compare_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets frequency register in Hz + * Hardware does not interpret the value of the register, so it's only + * for software can discover the frequency of the system counter. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value frequency in Hz + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_counter_freq( + struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads frequency register in Hz + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return frequency in Hz + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_counter_freq( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 32-bit down-counter timer value + * 'Down-counter timer set' automatically sets the compare register by + * compare register = current counter + this timer value + * + * As soon as the timer value reaches zero, the interrupt condition will + * be asserted \ref systimer_armv8_m_is_interrupt_asserted. + * Reaching zero doesn't stop the timer. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 32-bit timer value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads down-counter timer value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 32-bit timer value + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_timer_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables timer + * Enables timer output signal and interrupt status assertion + * \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables timer + * Disables timer output signal. Interrupt status will be unknown + * \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_timer_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables timer interrupt + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables timer interrupt + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer interrupt enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_interrupt_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer interrupt status + * It's asserted if + * 1. Auto-Inc is disabled and counter reaches compare value + * OR + * 2. Auto-Inc is enabled and counter reaches auto-inc value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if asserted, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_interrupt_asserted( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Reads auto-increment value + * This value is automatically calculated by + * auto-inc = current counter + auto-inc reload + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit auto-increment value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_autoinc_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 32-bit auto-increment reload value + * Auto-Inc value is automatically calculated by adding this reload value + * to the current counter. + * If the counter reaches auto-inc value, interrupt status is asserted + * and auto-inc value is automatically set by current reload. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 32-bit reload value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_autoinc_reload( + struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads auto-increment reload value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 32-bit auto-increment reload value + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_autoinc_reload( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables auto-increment mode + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables auto-increment mode + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls auto-increment enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_autoinc_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Clears auto-increment mode interrupt flag + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_clear_autoinc_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls auto-increment implementation status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_autoinc_implemented( + struct systimer_armv8_m_dev_t* dev); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSTIMER_ARMV8_M_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.c b/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.c new file mode 100644 index 0000000000..c3d1230052 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2016-2019 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. + */ + +#include "uart_cmsdk_drv.h" + +#include <stddef.h> + +/* UART register map structure */ +struct _uart_cmsdk_reg_map_t { + volatile uint32_t data; /* Offset: 0x000 (R/W) data register */ + volatile uint32_t state; /* Offset: 0x004 (R/W) status register */ + volatile uint32_t ctrl; /* Offset: 0x008 (R/W) control register */ + union { + volatile uint32_t intrstatus; /* Offset: 0x00c (R/ ) interrupt status + * register + */ + volatile uint32_t intrclear; /* Offset: 0x00c ( /W) interrupt clear + * register + */ + }intr_reg; + volatile uint32_t bauddiv; /* Offset: 0x010 (R/W) Baudrate divider + * register + */ +}; + +/* CTRL Register */ +#define UART_CMSDK_TX_EN (1ul << 0) +#define UART_CMSDK_RX_EN (1ul << 1) +#define UART_CMSDK_TX_INTR_EN (1ul << 2) +#define UART_CMSDK_RX_INTR_EN (1ul << 3) + +/* STATE Register */ +#define UART_CMSDK_TX_BF (1ul << 0) +#define UART_CMSDK_RX_BF (1ul << 1) + +/* INTSTATUS Register */ +#define UART_CMSDK_TX_INTR (1ul << 0) +#define UART_CMSDK_RX_INTR (1ul << 1) + +/* UART state definitions */ +#define UART_CMSDK_INITIALIZED (1ul << 0) + +enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev, + uint32_t system_clk) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + if(system_clk == 0) { + return UART_CMSDK_ERR_INVALID_ARG; + } + + /* Sets baudrate and system clock */ + dev->data->system_clk = system_clk; + dev->data->baudrate = dev->cfg->default_baudrate; + + /* Sets baudrate */ + p_uart->bauddiv = (dev->data->system_clk / dev->cfg->default_baudrate); + + /* Enables receiver and transmitter */ + p_uart->ctrl = UART_CMSDK_RX_EN | UART_CMSDK_TX_EN; + + dev->data->state = UART_CMSDK_INITIALIZED; + + return UART_CMSDK_ERR_NONE; +} + +enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev, + uint32_t baudrate) +{ + uint32_t bauddiv; + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(baudrate == 0) { + return UART_CMSDK_ERR_INVALID_BAUD; + } + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return UART_CMSDK_ERR_NOT_INIT; + } + + /* Sets baudrate */ + bauddiv = (dev->data->system_clk / baudrate); + dev->data->baudrate = baudrate; + + /* Minimum bauddiv value */ + if(bauddiv < 16) { + return UART_CMSDK_ERR_INVALID_BAUD; + } + + p_uart->bauddiv = bauddiv; + + return UART_CMSDK_ERR_NONE; +} + +uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev) +{ + return dev->data->baudrate; +} + +enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev, + uint32_t system_clk) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(system_clk == 0) { + return UART_CMSDK_ERR_INVALID_ARG; + } + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return UART_CMSDK_ERR_NOT_INIT; + } + + /* Sets system clock */ + dev->data->system_clk = system_clk; + + /* Updates baudrate divider */ + p_uart->bauddiv = (dev->data->system_clk / dev->data->baudrate); + + /* Enables receiver and transmitter */ + return UART_CMSDK_ERR_NONE; +} + +enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev, + uint8_t* byte) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(!(p_uart->state & UART_CMSDK_RX_BF)) { + return UART_CMSDK_ERR_NOT_READY; + } + + /* Reads data */ + *byte = (uint8_t)p_uart->data; + + return UART_CMSDK_ERR_NONE; +} + +enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev, + uint8_t byte) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(p_uart->state & UART_CMSDK_TX_BF) { + return UART_CMSDK_ERR_NOT_READY; + } + + /* Sends data */ + p_uart->data = byte; + + return UART_CMSDK_ERR_NONE; +} + +enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return UART_CMSDK_ERR_NOT_INIT; + } + + p_uart->ctrl |= UART_CMSDK_TX_INTR_EN; + + return UART_CMSDK_ERR_NONE; +} + +void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(dev->data->state & UART_CMSDK_INITIALIZED ) { + p_uart->ctrl &= ~UART_CMSDK_TX_INTR_EN; + } +} + +uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return 0; + } + + return !(p_uart->state & UART_CMSDK_TX_BF); +} + +enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return UART_CMSDK_ERR_NOT_INIT; + } + + p_uart->ctrl |= UART_CMSDK_RX_INTR_EN; + + return UART_CMSDK_ERR_NONE; +} + +void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(dev->data->state & UART_CMSDK_INITIALIZED) { + p_uart->ctrl &= ~UART_CMSDK_RX_INTR_EN; + } +} + +uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & UART_CMSDK_INITIALIZED)) { + return 0; + } + + return (p_uart->state & UART_CMSDK_RX_BF); +} + +void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev, + enum uart_cmsdk_irq_t irq) +{ + struct _uart_cmsdk_reg_map_t* p_uart = + (struct _uart_cmsdk_reg_map_t*)dev->cfg->base; + + if(dev->data->state & UART_CMSDK_INITIALIZED) { + /* Clears pending interrupts */ + switch(irq) { + case UART_CMSDK_IRQ_RX: + p_uart->intr_reg.intrclear = UART_CMSDK_RX_INTR; + break; + case UART_CMSDK_IRQ_TX: + p_uart->intr_reg.intrclear = UART_CMSDK_TX_INTR; + break; + case UART_CMSDK_IRQ_COMBINED: + p_uart->intr_reg.intrclear = + (UART_CMSDK_RX_INTR | UART_CMSDK_TX_INTR); + break; + /* default: not defined to force all cases to be handled */ + } + } +} diff --git a/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.h b/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.h new file mode 100644 index 0000000000..2d3278ef65 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/native_drivers/uart_cmsdk_drv.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016-2019 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. + */ + +/** + * \file uart_cmsdk_drv.h + * \brief Generic driver for ARM UART. + */ + +#ifndef __UART_CMSDK_DRV_H__ +#define __UART_CMSDK_DRV_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* ARM UART device configuration structure */ +struct uart_cmsdk_dev_cfg_t { + const uint32_t base; /*!< UART base address */ + const uint32_t default_baudrate; /*!< Default baudrate */ +}; + +/* ARM UART device data structure */ +struct uart_cmsdk_dev_data_t { + uint32_t state; /*!< Indicates if the uart driver + * is initialized and enabled + */ + uint32_t system_clk; /*!< System clock */ + uint32_t baudrate; /*!< Baudrate */ +}; + +/* ARM UART device structure */ +struct uart_cmsdk_dev_t { + const struct uart_cmsdk_dev_cfg_t* const cfg; /*!< UART configuration */ + struct uart_cmsdk_dev_data_t* const data; /*!< UART data */ +}; + +/* ARM UART enumeration types */ +enum uart_cmsdk_error_t { + UART_CMSDK_ERR_NONE = 0, /*!< No error */ + UART_CMSDK_ERR_INVALID_ARG, /*!< Error invalid input argument */ + UART_CMSDK_ERR_INVALID_BAUD, /*!< Invalid baudrate */ + UART_CMSDK_ERR_NOT_INIT, /*!< Error UART not initialized */ + UART_CMSDK_ERR_NOT_READY, /*!< Error UART not ready */ +}; + +enum uart_cmsdk_irq_t { + UART_CMSDK_IRQ_RX, /*!< RX interrupt source */ + UART_CMSDK_IRQ_TX, /*!< TX interrupt source */ + UART_CMSDK_IRQ_COMBINED /*!< RX-TX combined interrupt source */ +}; + +/** + * \brief Initializes UART. It uses the default baudrate to configure + * the peripheral at this point. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] system_clk System clock used by the device. + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev, + uint32_t system_clk); + +/** + * \brief Sets the UART baudrate. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] baudrate New baudrate. + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev, + uint32_t baudrate); + +/** + * \brief Gets the UART baudrate. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \return Returns the UART baudrate. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Sets system clock. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] system_clk System clock used by the device. + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev, + uint32_t system_clk); +/** + * \brief Reads one byte from UART dev. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] byte Pointer to byte. + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note For better performance, this function doesn't check if dev and byte + * pointer are NULL, and if the driver is initialized. + */ +enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev, + uint8_t* byte); + +/** + * \brief Writes a byte to UART dev. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] byte Byte to write. + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note For better performance, this function doesn't check if dev is NULL and + * if the driver is initialized to have better performance. + */ +enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev, + uint8_t byte); + +/** + * \brief Enables TX interrupt. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Disables TX interrupt. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Verifies if Tx is ready to send more data. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \return 1 if TX is ready, 0 otherwise. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Enables RX interrupt. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \return Returns error code as specified in \ref uart_cmsdk_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Disables RX interrupt + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Verifies if Rx has data. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \return 1 if RX has data, 0 otherwise. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev); + +/** + * \brief Clears UART interrupt. + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * \param[in] irq IRQ source to clean \ref uart_cmsdk_irq_t + * + * \note This function doesn't check if dev is NULL. + */ +void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev, + enum uart_cmsdk_irq_t irq); + +#ifdef __cplusplus +} +#endif +#endif /* __UART_CMSDK_DRV_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/partition/flash_layout.h b/platform/ext/target/mps3/fvp_sse300/partition/flash_layout.h new file mode 100644 index 0000000000..8ae6d256a4 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/partition/flash_layout.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2019-2020 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 __FLASH_LAYOUT_H__ +#define __FLASH_LAYOUT_H__ + +#include "platform_base_address.h" + +/* Flash layout on fvp_sse300_mps3 with BL2 (multiple image boot): + * + * 0x0000_0000 Secure image primary slot (384 KB) + * 0x0006_0000 Non-secure image primary slot (384 KB) + * 0x000C_0000 Secure image secondary slot (384 KB) + * 0x0012_0000 Non-secure image secondary slot (384 KB) + * 0x0018_0000 Scratch area (384 KB) + * 0x001E_0000 Protected Storage Area (20 KB) + * 0x001E_8000 Internal Trusted Storage Area (16 KB) + * 0x001E_D800 NV counters area (4 KB) + * 0x001E_E800 Unused + * + * Flash layout on fvp_sse300_mps3 with BL2 (single image boot): + * + * 0x0000_0000 Primary image area (768 KB): + * 0x0000_0000 Secure image primary (384 KB) + * 0x0006_0000 Non-secure image primary (384 KB) + * 0x000C_0000 Secondary image area (768 KB): + * 0x000C_0000 Secure image secondary (384 KB) + * 0x0012_0000 Non-secure image secondary (384 KB) + * 0x0018_0000 Scratch area (384 KB) + * 0x001C_0000 Protected Storage Area (20 KB) + * 0x001C_5000 Internal Trusted Storage Area (16 KB) + * 0x001C_9000 NV counters area (4 KB) + * 0x001C_A000 Unused + */ + + + +/* This header file is included from linker scatter file as well, where only a + * limited C constructs are allowed. Therefore it is not possible to include + * here the platform_retarget.h to access flash related defines. To resolve this + * some of the values are redefined here with different names, these are marked + * with comment. + */ + +/* Size of a Secure and of a Non-secure image */ +#define FLASH_S_PARTITION_SIZE (0x60000) /* S partition: 384 KB */ +#define FLASH_NS_PARTITION_SIZE (0x60000) /* NS partition: 384 KB */ +#define FLASH_MAX_PARTITION_SIZE ((FLASH_S_PARTITION_SIZE > \ + FLASH_NS_PARTITION_SIZE) ? \ + FLASH_S_PARTITION_SIZE : \ + FLASH_NS_PARTITION_SIZE) + +/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */ +#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB */ +/* Same as FLASH0_SIZE */ +#define FLASH_TOTAL_SIZE (SRAM_SIZE) /* 2 MB */ + +/* Flash layout info for BL2 bootloader */ +/* Same as FLASH0_BASE_S */ +#define FLASH_BASE_ADDRESS (SRAM_BASE_S) + +/* Offset and size definitions of the flash partitions that are handled by the + * bootloader. The image swapping is done between IMAGE_PRIMARY and + * IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image + * swapping. + */ +#define FLASH_AREA_BL2_OFFSET (0x0) +#define FLASH_AREA_BL2_SIZE (ITCM_SIZE) /* 256 KB */ + +#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1) +/* Secure + Non-secure image primary slot */ +#define FLASH_AREA_0_ID (1) +#define FLASH_AREA_0_OFFSET (0) +#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) +/* Secure + Non-secure secondary slot */ +#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1) +#define FLASH_AREA_2_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE) +#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) +/* Scratch area */ +#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1) +#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE) +#define FLASH_AREA_SCRATCH_SIZE (FLASH_MAX_PARTITION_SIZE) +/* The maximum number of status entries supported by the bootloader. */ +#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) / \ + FLASH_AREA_SCRATCH_SIZE) +/* Maximum number of image sectors supported by the bootloader. */ +#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) / \ + FLASH_AREA_IMAGE_SECTOR_SIZE) +#elif (MCUBOOT_IMAGE_NUMBER == 2) +/* Secure image primary slot */ +#define FLASH_AREA_0_ID (1) +#define FLASH_AREA_0_OFFSET (0) +#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE) +/* Non-secure image primary slot */ +#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1) +#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE) +#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE) +/* Secure image secondary slot */ +#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1) +#define FLASH_AREA_2_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE) +#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE) +/* Non-secure image secondary slot */ +#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1) +#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE) +#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE) +/* Scratch area */ +#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1) +#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE) +#define FLASH_AREA_SCRATCH_SIZE (FLASH_MAX_PARTITION_SIZE) +/* The maximum number of status entries supported by the bootloader. */ +#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \ + FLASH_AREA_SCRATCH_SIZE) +/* Maximum number of image sectors supported by the bootloader. */ +#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \ + FLASH_AREA_IMAGE_SECTOR_SIZE) +#else /* MCUBOOT_IMAGE_NUMBER > 2 */ +#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!" +#endif /* MCUBOOT_IMAGE_NUMBER */ + +/* mpc_init_cfg function in target_cfg.c expects that all the images are located + * in SSRAM2 device, and those do not overlap to SSRAM3. */ +#if ( FLASH_AREA_SCRATCH_OFFSET > SRAM_SIZE) +#error "Out of SRAM memory!" +#endif + +/* Protected Storage (PS) Service definitions */ +#define FLASH_PS_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + \ + FLASH_AREA_SCRATCH_SIZE) +#define FLASH_PS_AREA_SIZE (0x5000) /* 20 KB */ + +/* Internal Trusted Storage (ITS) Service definitions */ +#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \ + FLASH_PS_AREA_SIZE) +#define FLASH_ITS_AREA_SIZE (0x4000) /* 16 KB */ + +/* NV Counters definitions */ +#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \ + FLASH_ITS_AREA_SIZE) +#define FLASH_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE) + +/* Offset and size definition in flash area used by assemble.py */ +#define SECURE_IMAGE_OFFSET (0x0) +#define SECURE_IMAGE_MAX_SIZE FLASH_S_PARTITION_SIZE + +#define NON_SECURE_IMAGE_OFFSET (SECURE_IMAGE_OFFSET + \ + SECURE_IMAGE_MAX_SIZE) +#define NON_SECURE_IMAGE_MAX_SIZE FLASH_NS_PARTITION_SIZE + +/* Flash device name used by BL2 + * Name is defined in flash driver file: Driver_Flash.c + */ +#define FLASH_DEV_NAME Driver_FLASH0 + +/* Protected Storage (PS) Service definitions + * Note: Further documentation of these definitions can be found in the + * TF-M PS Integration Guide. + */ +#define PS_FLASH_DEV_NAME Driver_FLASH0 + +/* In this target the CMSIS driver requires only the offset from the base + * address instead of the full memory address. + */ +#define PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET +/* Dedicated flash area for PS */ +#define PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE +#define PS_RAM_FS_SIZE PS_FLASH_AREA_SIZE +#define PS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE +/* Number of PS_SECTOR_SIZE per block */ +#define PS_SECTORS_PER_BLOCK (0x1) +/* Specifies the smallest flash programmable unit in bytes */ +#define PS_FLASH_PROGRAM_UNIT (0x1) + +/* Internal Trusted Storage (ITS) Service definitions + * Note: Further documentation of these definitions can be found in the + * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is + * allocated in the external flash just for development platforms that don't + * have internal flash available. + */ +#define ITS_FLASH_DEV_NAME Driver_FLASH0 + +/* In this target the CMSIS driver requires only the offset from the base + * address instead of the full memory address. + */ +#define ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET +/* Dedicated flash area for ITS */ +#define ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE +#define ITS_RAM_FS_SIZE ITS_FLASH_AREA_SIZE +#define ITS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE +/* Number of ITS_SECTOR_SIZE per block */ +#define ITS_SECTORS_PER_BLOCK (0x1) +/* Specifies the smallest flash programmable unit in bytes */ +#define ITS_FLASH_PROGRAM_UNIT (0x1) + +/* NV Counters definitions */ +#define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET +#define TFM_NV_COUNTERS_AREA_SIZE (0x18) /* 24 Bytes */ +#define TFM_NV_COUNTERS_SECTOR_ADDR FLASH_NV_COUNTERS_AREA_OFFSET +#define TFM_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE + +#endif /* __FLASH_LAYOUT_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/partition/platform_base_address.h b/platform/ext/target/mps3/fvp_sse300/partition/platform_base_address.h new file mode 100644 index 0000000000..3634416125 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/partition/platform_base_address.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +/** + * \file platform_base_address.h + * \brief This file defines all the peripheral base addresses for MPS3 SSE-300 + * Ethos-U55 FVP platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H__ +#define __PLATFORM_BASE_ADDRESS_H__ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ITCM_BASE_NS 0x00000000 /* Instruction TCM Non-Secure base address */ +#define SRAM_BASE_NS 0x01000000 /* CODE SRAM Non-Secure base address */ +#define DTCM0_BASE_NS 0x20000000 /* Data TCM block 0 Non-Secure base address */ +#define DTCM1_BASE_NS 0x20100000 /* Data TCM block 1 Non-Secure base address */ +#define DTCM2_BASE_NS 0x20200000 /* Data TCM block 2 Non-Secure base address */ +#define DTCM3_BASE_NS 0x20300000 /* Data TCM block 3 Non-Secure base address */ +#define ISRAM0_BASE_NS 0x21000000 /* Internal SRAM Area Non-Secure base address */ +#define ISRAM1_BASE_NS 0x21040000 /* Internal SRAM Area Non-Secure base address */ +#define QSPI_SRAM_BASE_NS 0x28000000 /* QSPI SRAM Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */ +#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */ +#define SSE300_NSACFG_BASE_NS 0x40080000 /* SSE-300 Non-Secure Access Configuration Register Block Non-Secure base address */ +/* Non-Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_NS 0x41100000 /* GPIO 0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x41101000 /* GPIO 1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x41102000 /* GPIO 2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x41103000 /* GPIO 3 Non-Secure base address */ +#define AHB_USER_0_BASE_NS 0x41104000 /* AHB USER 0 Non-Secure base address */ +#define AHB_USER_1_BASE_NS 0x41105000 /* AHB USER 1 Non-Secure base address */ +#define AHB_USER_2_BASE_NS 0x41106000 /* AHB USER 2 Non-Secure base address */ +#define AHB_USER_3_BASE_NS 0x41107000 /* AHB USER 3 Non-Secure base address */ +#define DMA_0_BASE_NS 0x41200000 /* DMA 0 Non-Secure base address */ +#define DMA_1_BASE_NS 0x41201000 /* DMA 1 Non-Secure base address */ +#define DMA_2_BASE_NS 0x41202000 /* DMA 2 Non-Secure base address */ +#define DMA_3_BASE_NS 0x41203000 /* DMA 3 Non-Secure base address */ +#define ETHERNET_BASE_NS 0x41400000 /* Ethernet Non-Secure base address */ +#define USB_BASE_NS 0x41500000 /* USB Non-Secure base address */ +#define USER_APB0_BASE_NS 0x41700000 /* User APB 0 Non-Secure base address */ +#define USER_APB1_BASE_NS 0x41701000 /* User APB 1 Non-Secure base address */ +#define USER_APB2_BASE_NS 0x41702000 /* User APB 2 Non-Secure base address */ +#define USER_APB3_BASE_NS 0x41703000 /* User APB 3 Non-Secure base address */ +#define QSPI_CONFIG_BASE_NS 0x41800000 /* QSPI Config Non-Secure base address */ +#define QSPI_WRITE_BASE_NS 0x41801000 /* QSPI Write Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_NS 0x48000000 /* System Timer 0 Non-Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_NS 0x48001000 /* System Timer 1 Non-Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_NS 0x48002000 /* System Timer 2 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 3 Non-Secure base address */ +#define SSE300_SYSINFO_BASE_NS 0x48020000 /* SSE-300 System info Block Non-Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_NS 0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS 0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_NS 0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48101000 /* System Counter Read Secure base address */ +/* Non-Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_NS 0x48102000 /* Ethos-U55 APB Non-Secure base address */ +#define U55_TIMING_ADAPTER_BASE_NS 0x48103000 /* Ethos-U55 Timing Adapter registers Non-Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_NS 0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */ +#define FPGA_SPI_ADC_BASE_NS 0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_NS 0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_NS 0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_NS 0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_NS 0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */ +#define USER_APB_BASE_NS 0x49207000 /* USER APB Non-Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_NS 0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */ +#define FPGA_SCC_BASE_NS 0x49300000 /* FPGA - SCC registers Non-Secure base address */ +#define FPGA_I2S_BASE_NS 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */ +#define FPGA_IO_BASE_NS 0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */ +#define UART0_BASE_NS 0x49303000 /* UART 0 Non-Secure base address */ +#define UART1_BASE_NS 0x49304000 /* UART 1 Non-Secure base address */ +#define UART2_BASE_NS 0x49305000 /* UART 2 Non-Secure base address */ +#define UART3_BASE_NS 0x49306000 /* UART 3 Non-Secure base address */ +#define UART4_BASE_NS 0x49307000 /* UART 4 Non-Secure base address */ +#define UART5_BASE_NS 0x49308000 /* UART 5 Non-Secure base address */ +#define CLCD_Config_Reg_BASE_NS 0x4930A000 /* CLCD Config Reg Non-Secure base address */ +#define RTC_BASE_NS 0x4930B000 /* RTC Non-Secure base address */ +#define DDR4_BLK0_BASE_NS 0x60000000 /* DDR4 block 0 Non-Secure base address */ +#define DDR4_BLK1_BASE_NS 0x80000000 /* DDR4 block 1 Non-Secure base address */ +#define DDR4_BLK2_BASE_NS 0xA0000000 /* DDR4 block 2 Non-Secure base address */ +#define DDR4_BLK3_BASE_NS 0xC0000000 /* DDR4 block 3 Non-Secure base address */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define SRAM_BASE_S 0x11000000 /* CODE SRAM Secure base address */ +#define DTCM0_BASE_S 0x30000000 /* Data TCM block 0 Secure base address */ +#define DTCM1_BASE_S 0x30100000 /* Data TCM block 1 Secure base address */ +#define DTCM2_BASE_S 0x30200000 /* Data TCM block 2 Secure base address */ +#define DTCM3_BASE_S 0x30300000 /* Data TCM block 3 Secure base address */ +#define ISRAM0_BASE_S 0x31000000 /* Internal SRAM Area Secure base address */ +#define ISRAM1_BASE_S 0x31040000 /* Internal SRAM Area Secure base address */ +#define QSPI_SRAM_BASE_S 0x38000000 /* QSPI SRAM Secure base address */ +/* Secure Subsystem peripheral region */ +#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */ +#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */ +#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */ +#define SSE300_SACFG_BASE_S 0x50080000 /* SSE-300 Secure Access Configuration Register Secure base address */ +#define MPC_ISRAM0_BASE_S 0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */ +#define MPC_ISRAM1_BASE_S 0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */ +/* Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_S 0x51100000 /* GPIO 0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x51101000 /* GPIO 1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x51102000 /* GPIO 2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x51103000 /* GPIO 3 Secure base address */ +#define AHB_USER_0_BASE_S 0x51104000 /* AHB USER 0 Secure base address */ +#define AHB_USER_1_BASE_S 0x51105000 /* AHB USER 1 Secure base address */ +#define AHB_USER_2_BASE_S 0x51106000 /* AHB USER 2 Secure base address */ +#define AHB_USER_3_BASE_S 0x51107000 /* AHB USER 3 Secure base address */ +#define DMA_0_BASE_S 0x51200000 /* DMA 0 Secure base address */ +#define DMA_1_BASE_S 0x51201000 /* DMA 1 Secure base address */ +#define DMA_2_BASE_S 0x51202000 /* DMA 2 Secure base address */ +#define DMA_3_BASE_S 0x51203000 /* DMA 3 Secure base address */ +#define ETHERNET_BASE_S 0x51400000 /* Ethernet Secure base address */ +#define USB_BASE_S 0x51500000 /* USB Secure base address */ +#define USER_APB0_BASE_S 0x51700000 /* User APB 0 Secure base address */ +#define USER_APB1_BASE_S 0x51701000 /* User APB 1 Secure base address */ +#define USER_APB2_BASE_S 0x51702000 /* User APB 2 Secure base address */ +#define USER_APB3_BASE_S 0x51703000 /* User APB 3 Secure base address */ +#define QSPI_CONFIG_BASE_S 0x51800000 /* QSPI Config Secure base address */ +#define QSPI_WRITE_BASE_S 0x51801000 /* QSPI Write Secure base address */ +#define MPC_SRAM_BASE_S 0x57000000 /* SRAM Memory Protection Controller Secure base address */ +#define MPC_QSPI_BASE_S 0x57001000 /* QSPI Memory Protection Controller Secure base address */ +#define MPC_DDR4_BASE_S 0x57002000 /* DDR4 Memory Protection Controller Secure base address */ +/* Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_S 0x58000000 /* System Timer 0 Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_S 0x58001000 /* System Timer 1 Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_S 0x58002000 /* System Timer 0 Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_S 0x58003000 /* System Timer 1 Secure base address */ +#define SSE300_SYSINFO_BASE_S 0x58020000 /* SSE-300 System info Block Secure base address */ +#define SSE300_SYSCTRL_BASE_S 0x58021000 /* SSE-300 System control Block Secure base address */ +#define SSE300_SYSPPU_BASE_S 0x58022000 /* SSE-300 System Power Policy Unit Secure base address */ +#define SSE300_CPU0PPU_BASE_S 0x58023000 /* SSE-300 CPU 0 Power Policy Unit Secure base address */ +#define SSE300_MGMTPPU_BASE_S 0x58028000 /* SSE-300 Management Power Policy Unit Secure base address */ +#define SSE300_DBGPPU_BASE_S 0x58029000 /* SSE-300 Debug Power Policy Unit Secure base address */ +#define SLOWCLK_WDOG_CMSDK_BASE_S 0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_S 0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_S 0x58040000 /* Secure Watchdog Timer control frame Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_S 0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58100000 /* System Counter Control Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58101000 /* System Counter Read Secure base address */ +/* Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_S 0x58102000 /* Ethos-U55 APB Secure base address */ +#define U55_TIMING_ADAPTER_BASE_S 0x58103000 /* Ethos-U55 Timing Adapter registers Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_S 0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */ +#define FPGA_SPI_ADC_BASE_S 0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_S 0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_S 0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_S 0x59205000 /* SBCon (I2C - Shield0) Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_S 0x59206000 /* SBCon (I2C – Shield1) Secure base address */ +#define USER_APB_BASE_S 0x59207000 /* USER APB Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_S 0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */ +#define FPGA_SCC_BASE_S 0x59300000 /* FPGA - SCC registers Secure base address */ +#define FPGA_I2S_BASE_S 0x59301000 /* FPGA - I2S (Audio) Secure base address */ +#define FPGA_IO_BASE_S 0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */ +#define UART0_BASE_S 0x59303000 /* UART 0 Secure base address */ +#define UART1_BASE_S 0x59304000 /* UART 1 Secure base address */ +#define UART2_BASE_S 0x59305000 /* UART 2 Secure base address */ +#define UART3_BASE_S 0x59306000 /* UART 3 Secure base address */ +#define UART4_BASE_S 0x59307000 /* UART 4 Secure base address */ +#define UART5_BASE_S 0x59308000 /* UART 5 Secure base address */ +#define CLCD_Config_Reg_BASE_S 0x5930A000 /* CLCD Config Reg Secure base address */ +#define RTC_BASE_S 0x5930B000 /* RTC Secure base address */ +#define DDR4_BLK0_BASE_S 0x70000000 /* DDR4 block 0 Secure base address */ +#define DDR4_BLK1_BASE_S 0x90000000 /* DDR4 block 1 Secure base address */ +#define DDR4_BLK2_BASE_S 0xB0000000 /* DDR4 block 2 Secure base address */ +#define DDR4_BLK3_BASE_S 0xD0000000 /* DDR4 block 3 Secure base address */ + +/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */ +#define SSE300_EWIC_BASE 0xE0047000 /* External Wakeup Interrupt Controller + * Access from Non-secure software is only allowed + * if AIRCR.BFHFNMINS is set to 1 */ + +/* Memory size definitions */ +#define ITCM_SIZE (0x00100000) /* 1 MB */ +#define DTCM_BLK_SIZE (0x00100000) /* 1 MB */ +#define SRAM_SIZE (0x00200000) /* 2 MB */ +#define ISRAM0_SIZE (0x00040000) /* 256 kB */ +#define ISRAM1_SIZE (0x00040000) /* 256 kB */ +#define QSPI_SRAM_SIZE (0x00800000) /* 8 MB */ +#define DDR4_BLK_SIZE (0x10000000) /* 256 MB */ + +/* Defines for Driver MPC's */ +/* SRAM -- 2 MB */ +#define MPC_SRAM_RANGE_BASE_NS (SRAM_BASE_NS) +#define MPC_SRAM_RANGE_LIMIT_NS (SRAM_BASE_NS + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_BASE_S (SRAM_BASE_S) +#define MPC_SRAM_RANGE_LIMIT_S (SRAM_BASE_S + SRAM_SIZE-1) + +/* QSPI -- 8 MB*/ +#define MPC_QSPI_RANGE_BASE_NS (QSPI_SRAM_BASE_NS) +#define MPC_QSPI_RANGE_LIMIT_NS (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_BASE_S (QSPI_SRAM_BASE_S) +#define MPC_QSPI_RANGE_LIMIT_S (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE-1) + +/* ISRAM0 -- 256 kB*/ +#define MPC_ISRAM0_RANGE_BASE_NS (ISRAM0_BASE_NS) +#define MPC_ISRAM0_RANGE_LIMIT_NS (ISRAM0_BASE_NS + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_BASE_S (ISRAM0_BASE_S) +#define MPC_ISRAM0_RANGE_LIMIT_S (ISRAM0_BASE_S + ISRAM0_SIZE-1) + +/* ISRAM1 -- 256 kB*/ +#define MPC_ISRAM1_RANGE_BASE_NS (ISRAM1_BASE_NS) +#define MPC_ISRAM1_RANGE_LIMIT_NS (ISRAM1_BASE_NS + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_BASE_S (ISRAM1_BASE_S) +#define MPC_ISRAM1_RANGE_LIMIT_S (ISRAM1_BASE_S + ISRAM1_SIZE-1) + +/* DDR4_BLK0 -- 256 MB */ +#define MPC_DDR4_RANGE_BASE_NS (DDR4_BLK0_BASE_NS) +#define MPC_DDR4_RANGE_LIMIT_NS (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_RANGE_BASE_S (DDR4_BLK0_BASE_S) +#define MPC_DDR4_RANGE_LIMIT_S (DDR4_BLK0_BASE_S + ((DDR4_BLK_SIZE)-1)) + +#endif /* __PLATFORM_BASE_ADDRESS_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/partition/region_defs.h b/platform/ext/target/mps3/fvp_sse300/partition/region_defs.h new file mode 100644 index 0000000000..ca225ea44c --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/partition/region_defs.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019-2020 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 __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "flash_layout.h" +#include "platform_base_address.h" + +#define BL2_HEAP_SIZE (0x0001000) +#define BL2_MSP_STACK_SIZE (0x0001800) + +#define S_HEAP_SIZE (0x0001000) +#define S_MSP_STACK_SIZE_INIT (0x0000400) +#define S_MSP_STACK_SIZE (0x0000800) +#define S_PSP_STACK_SIZE (0x0000800) + +#define NS_HEAP_SIZE (0x0001000) +#define NS_MSP_STACK_SIZE (0x0000400) +#define NS_PSP_STACK_SIZE (0x0000C00) + +/* This size of buffer is big enough to store an attestation + * token produced by initial attestation service + */ +#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE (0x250) + +/* + * MPC granularity is 4 KB on SSE300_MPS3 FVP. Alignment + * of partitions is defined in accordance with this constraint. + */ + +#ifdef BL2 +#ifndef LINK_TO_SECONDARY_PARTITION +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET) +#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET) +#else +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET) +#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET) +#endif /* !LINK_TO_SECONDARY_PARTITION */ +#else +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0) +#endif /* BL2 */ + +#ifndef LINK_TO_SECONDARY_PARTITION +#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET \ + + FLASH_S_PARTITION_SIZE) +#else +#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET \ + + FLASH_S_PARTITION_SIZE) +#endif /* !LINK_TO_SECONDARY_PARTITION */ + +/* Boot partition structure if MCUBoot is used: + * 0x0_0000 Bootloader header + * 0x0_0400 Image area + * 0x5_0000 Trailer + */ +/* IMAGE_CODE_SIZE is the space available for the software binary image. + * It is less than the FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE + * because we reserve space for the image header and trailer introduced + * by the bootloader. + */ +#ifdef BL2 +#define BL2_HEADER_SIZE (0x400) /* 1 KB */ +#define BL2_TRAILER_SIZE (0x800) /* 2 KB */ +#else +/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */ +#define BL2_HEADER_SIZE (0x0) +#define BL2_TRAILER_SIZE (0xC00) +#endif /* BL2 */ + +#define IMAGE_S_CODE_SIZE \ + (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE) +#define IMAGE_NS_CODE_SIZE \ + (FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE) + +#define CMSE_VENEER_REGION_SIZE (0x340) + +/* Secure regions */ +#define S_IMAGE_PRIMARY_AREA_OFFSET \ + (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) +/* Secure Code stored in SSRAM2 */ +#define S_CODE_START ((SRAM_BASE_S) + (S_IMAGE_PRIMARY_AREA_OFFSET)) +#define S_CODE_SIZE (IMAGE_S_CODE_SIZE - CMSE_VENEER_REGION_SIZE) +#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1) + +/* Secure Data stored in DTCM */ +#define S_DATA_START (DTCM0_BASE_S) +#define S_DATA_SIZE (DTCM_BLK_SIZE) +#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1) + +/* CMSE Veneers region */ +#define CMSE_VENEER_REGION_START (S_CODE_LIMIT + 1) + +/* Non-secure regions */ +#define NS_IMAGE_PRIMARY_AREA_OFFSET \ + (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) +/* Non-Secure Code stored in SSRAM2 memory */ +#define NS_CODE_START (SRAM_BASE_NS + (NS_IMAGE_PRIMARY_AREA_OFFSET)) +#define NS_CODE_SIZE (IMAGE_NS_CODE_SIZE) +#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1) + +/* Non-Secure Data stored in ISRAM0 */ +#define NS_DATA_START (ISRAM0_BASE_NS) +#define NS_DATA_SIZE (ISRAM0_SIZE) +#define NS_DATA_LIMIT (NS_DATA_START + NS_DATA_SIZE - 1) + +/* NS partition information is used for MPC and SAU configuration */ +#define NS_PARTITION_START \ + ((SRAM_BASE_NS) + (NS_IMAGE_PRIMARY_PARTITION_OFFSET)) +#define NS_PARTITION_SIZE (FLASH_NS_PARTITION_SIZE) + +/* Secondary partition for new images in case of firmware upgrade */ +#define SECONDARY_PARTITION_START \ + ((SRAM_BASE_NS) + (S_IMAGE_SECONDARY_PARTITION_OFFSET)) +#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) + +#ifdef BL2 +/* Bootloader regions */ +/* Use ITCM to store Bootloader */ +#define BL2_CODE_START (ITCM_BASE_S) +#define BL2_CODE_SIZE (ITCM_SIZE) +#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1) + +/* Bootloader uses same memory as for secure image */ +#define BL2_DATA_START (S_DATA_START) +#define BL2_DATA_SIZE (S_DATA_SIZE) +#define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1) +#endif /* BL2 */ + +/* Shared data area between bootloader and runtime firmware. + * Shared data area is allocated at the beginning of the RAM, it is overlapping + * with TF-M Secure code's MSP stack + */ +#define BOOT_TFM_SHARED_DATA_BASE S_DATA_START +#define BOOT_TFM_SHARED_DATA_SIZE (0x400) +#define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + \ + BOOT_TFM_SHARED_DATA_SIZE - 1) + +#endif /* __REGION_DEFS_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/plat_test.c b/platform/ext/target/mps3/fvp_sse300/plat_test.c new file mode 100644 index 0000000000..d3dd1c5d7f --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/plat_test.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "platform_description.h" +#include "systimer_armv8-m_drv.h" +#include "syscounter_armv8-m_cntrl_drv.h" +#include "tfm_plat_test.h" +#include "device_definition.h" + +#define USERLED_MASK (0x3) +#define BTN_WAIT_INIT_COUNTER_VALUE (10000u) +#define TIMER_RELOAD_VALUE (SystemCoreClock) + +/** + * \brief Store the state of the mocked LED + * + * This variable have to be linked to the data section of the partition + * TFM_SP_CORE_TEST so that in case of in case of isolation within the secure + * domain the Core Test service can access it. + */ +uint32_t led_status + TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_CORE_TEST") + = 0x02u; + +/** + * \brief Simulate user reaction time + */ +static void busy_wait_to_simulate_user(void) +{ + volatile uint32_t counter = BTN_WAIT_INIT_COUNTER_VALUE; + + while (counter) { + --counter; + } +} + +void tfm_plat_test_wait_user_button_pressed(void) +{ + busy_wait_to_simulate_user(); +} + +void tfm_plat_test_wait_user_button_released(void) +{ + busy_wait_to_simulate_user(); +} + +uint32_t tfm_plat_test_get_led_status(void) +{ + return led_status; +} + +void tfm_plat_test_set_led_status(uint32_t status) +{ + led_status = status & USERLED_MASK; +} + +uint32_t tfm_plat_test_get_userled_mask(void) +{ + return USERLED_MASK; +} + +void tfm_plat_test_secure_timer_start(void) +{ + syscounter_armv8_m_cntrl_init(&SYSCOUNTER_CNTRL_ARMV8_M_DEV_S); + + systimer_armv8_m_init(&SYSTIMER0_ARMV8_M_DEV_S); + systimer_armv8_m_set_timer_value(&SYSTIMER0_ARMV8_M_DEV_S, TIMER_RELOAD_VALUE); + systimer_armv8_m_enable_interrupt(&SYSTIMER0_ARMV8_M_DEV_S); +} + +void tfm_plat_test_secure_timer_stop(void) +{ + systimer_armv8_m_uninit(&SYSTIMER0_ARMV8_M_DEV_S); + systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S); +} + +void tfm_plat_test_non_secure_timer_start(void) +{ + systimer_armv8_m_init(&SYSTIMER1_ARMV8_M_DEV_NS); + systimer_armv8_m_set_timer_value(&SYSTIMER1_ARMV8_M_DEV_NS, TIMER_RELOAD_VALUE); + systimer_armv8_m_enable_interrupt(&SYSTIMER1_ARMV8_M_DEV_NS); +} + +void tfm_plat_test_non_secure_timer_stop(void) +{ + systimer_armv8_m_uninit(&SYSTIMER1_ARMV8_M_DEV_NS); + systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER1_ARMV8_M_DEV_NS); +} diff --git a/platform/ext/target/mps3/fvp_sse300/preload.cmake b/platform/ext/target/mps3/fvp_sse300/preload.cmake new file mode 100644 index 0000000000..531e6e4102 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/preload.cmake @@ -0,0 +1,16 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +# preload.cmake is used to set things that related to the platform that are both +# immutable and global, which is to say they should apply to any kind of project +# that uses this platform. In practise this is normally compiler definitions and +# variables related to hardware. + +# Set architecture and CPU +set(TFM_SYSTEM_PROCESSOR cortex-m55) +set(TFM_SYSTEM_ARCHITECTURE armv8.1-m.main) +set(TFM_SYSTEM_DSP OFF) diff --git a/platform/ext/target/mps3/fvp_sse300/services/src/tfm_platform_system.c b/platform/ext/target/mps3/fvp_sse300/services/src/tfm_platform_system.c new file mode 100644 index 0000000000..44fafbccd1 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/services/src/tfm_platform_system.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "tfm_platform_system.h" +#include "cmsis.h" + +void tfm_platform_hal_system_reset(void) +{ + /* Reset the system */ + NVIC_SystemReset(); +} + +enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *in_vec, + psa_outvec *out_vec) +{ + (void)request; + (void)in_vec; + (void)out_vec; + + /* Not needed for this platform */ + return TFM_PLATFORM_ERR_NOT_SUPPORTED; +} + diff --git a/platform/ext/target/mps3/fvp_sse300/spm_hal.c b/platform/ext/target/mps3/fvp_sse300/spm_hal.c new file mode 100644 index 0000000000..45205aa00b --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/spm_hal.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include <stdio.h> +#include "cmsis.h" +#include "tfm_spm_hal.h" +#include "tfm_platform_core_api.h" +#include "target_cfg.h" +#include "Driver_MPC.h" +#include "mpu_armv8m_drv.h" +#include "region_defs.h" +#include "utilities.h" +#include "region.h" + +/* Get address of memory regions to configure MPU */ +extern const struct memory_region_limits memory_regions; + +struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE }; + +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT +#define PARTITION_REGION_PERIPH_START 6 +#define PARTITION_REGION_PERIPH_MAX_NUM 2 + +uint32_t periph_num_count = 0; +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + +enum tfm_plat_err_t tfm_spm_hal_init_isolation_hw(void) +{ + enum tfm_plat_err_t err = TFM_PLAT_ERR_SUCCESS; + + sau_and_idau_cfg(); + + err = ppc_init_cfg(); + if (err != TFM_PLAT_ERR_SUCCESS) { + ERROR_MSG("Error during initial PPC configuration!"); + return err; + } + + err = mpc_init_cfg(); + if (err != TFM_PLAT_ERR_SUCCESS) { + ERROR_MSG("Error during initial MPC configuration!"); + return err; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation( + uint32_t partition_idx, + const struct tfm_spm_partition_platform_data_t *platform_data) +{ +#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1) + bool privileged = tfm_is_partition_privileged(partition_idx); + struct mpu_armv8m_region_cfg_t region_cfg; +#endif + + if (!platform_data) { + return TFM_PLAT_ERR_INVALID_INPUT; + } + +#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1) + if (!privileged) { + region_cfg.region_nr = PARTITION_REGION_PERIPH_START + periph_num_count; + periph_num_count++; + if (periph_num_count >= PARTITION_REGION_PERIPH_MAX_NUM) { + return TFM_PLAT_ERR_MAX_VALUE; + } + region_cfg.region_base = platform_data->periph_start; + region_cfg.region_limit = platform_data->periph_limit; + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX; + region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV; + region_cfg.attr_sh = MPU_ARMV8M_SH_NONE; + region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER; + + mpu_armv8m_disable(&dev_mpu_s); + + if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) + != MPU_ARMV8M_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE, + HARDFAULT_NMI_ENABLE); + } +#endif /* defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1) */ + + if (platform_data->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) { + ppc_configure_to_secure(platform_data->periph_ppc_bank, + platform_data->periph_ppc_mask); + } + return TFM_PLAT_ERR_SUCCESS; +} + +void MPC_Handler(void) +{ + /* Clear MPC interrupt flag and pending MPC IRQ */ + mpc_clear_irq(); + NVIC_ClearPendingIRQ(MPC_IRQn); + + /* Print fault message and block execution */ + ERROR_MSG("Oops... MPC fault!!!"); + + /* Inform TF-M core that isolation boundary has been violated */ + tfm_access_violation_handler(); +} + +void PPC_Handler(void) +{ + /* Clear PPC interrupt flag and pending PPC IRQ */ + ppc_clear_irq(); + NVIC_ClearPendingIRQ(PPC_IRQn); + + /* Print fault message*/ + ERROR_MSG("Oops... PPC fault!!!"); + + /* Inform TF-M core that isolation boundary has been violated */ + tfm_access_violation_handler(); +} + +uint32_t tfm_spm_hal_get_ns_VTOR(void) +{ + return memory_regions.non_secure_code_start; +} + +uint32_t tfm_spm_hal_get_ns_MSP(void) +{ + return *((uint32_t *)memory_regions.non_secure_code_start); +} + +uint32_t tfm_spm_hal_get_ns_entry_point(void) +{ + return *((uint32_t *)(memory_regions.non_secure_code_start+ 4)); +} + +enum tfm_plat_err_t tfm_spm_hal_set_secure_irq_priority(IRQn_Type irq_line, + uint32_t priority) +{ + uint32_t quantized_priority = priority >> (8U - __NVIC_PRIO_BITS); + NVIC_SetPriority(irq_line, quantized_priority); + return TFM_PLAT_ERR_SUCCESS; +} + +void tfm_spm_hal_clear_pending_irq(IRQn_Type irq_line) +{ + NVIC_ClearPendingIRQ(irq_line); +} + +void tfm_spm_hal_enable_irq(IRQn_Type irq_line) +{ + NVIC_EnableIRQ(irq_line); +} + +void tfm_spm_hal_disable_irq(IRQn_Type irq_line) +{ + NVIC_DisableIRQ(irq_line); +} + +enum irq_target_state_t tfm_spm_hal_set_irq_target_state( + IRQn_Type irq_line, + enum irq_target_state_t target_state) +{ + uint32_t result; + + if (target_state == TFM_IRQ_TARGET_STATE_SECURE) { + result = NVIC_ClearTargetState(irq_line); + } else { + result = NVIC_SetTargetState(irq_line); + } + + if (result) { + return TFM_IRQ_TARGET_STATE_NON_SECURE; + } else { + return TFM_IRQ_TARGET_STATE_SECURE; + } +} + +enum tfm_plat_err_t tfm_spm_hal_enable_fault_handlers(void) +{ + return enable_fault_handlers(); +} + +enum tfm_plat_err_t tfm_spm_hal_system_reset_cfg(void) +{ + return system_reset_cfg(); +} + +enum tfm_plat_err_t tfm_spm_hal_init_debug(void) +{ + return init_debug(); +} + +enum tfm_plat_err_t tfm_spm_hal_nvic_interrupt_target_state_cfg(void) +{ + return nvic_interrupt_target_state_cfg(); +} + +enum tfm_plat_err_t tfm_spm_hal_nvic_interrupt_enable(void) +{ + return nvic_interrupt_enable(); +} diff --git a/platform/ext/target/mps3/fvp_sse300/target_cfg.c b/platform/ext/target/mps3/fvp_sse300/target_cfg.c new file mode 100644 index 0000000000..ada8afa0e8 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/target_cfg.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +#include "cmsis.h" +#include "utilities.h" +#include "target_cfg.h" +#include "Driver_SSE300_PPC.h" +#include "Driver_MPC.h" +#include "platform_description.h" +#include "region_defs.h" +#include "tfm_plat_defs.h" +#include "region.h" + +/* Throw out bus error when an access causes security violation */ +#define CMSDK_SECRESPCFG_BUS_ERR_MASK (1UL << 0) + +/* Macros to pick linker symbols */ +#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) + +/* The section names come from the scatter file */ +REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base); +REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base); +REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit); +#ifdef BL2 +REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base); +#endif /* BL2 */ + +const struct memory_region_limits memory_regions = { + .non_secure_code_start = + (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) + + BL2_HEADER_SIZE, + + .non_secure_partition_base = + (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base), + + .non_secure_partition_limit = + (uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) + + NS_PARTITION_SIZE - 1, + + .veneer_base = (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base), + .veneer_limit = (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Limit), + +#ifdef BL2 + .secondary_partition_base = + (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base), + + .secondary_partition_limit = + (uint32_t)®ION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) + + SECONDARY_PARTITION_SIZE - 1, +#endif /* BL2 */ +}; + +/* Configures the RAM region to NS callable in sacfg block's nsccfg register */ +#define RAMNSC 0x2 + +/* Import MPC drivers */ +extern ARM_DRIVER_MPC Driver_ISRAM0_MPC; +extern ARM_DRIVER_MPC Driver_ISRAM1_MPC; +extern ARM_DRIVER_MPC Driver_SRAM_MPC; +extern ARM_DRIVER_MPC Driver_QSPI_MPC; + +/* Import PPC drivers */ +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP2; + +/* Define Peripherals NS address range for the platform */ +#define PERIPHERALS_BASE_NS_START (0x40000000) +#define PERIPHERALS_BASE_NS_END (0x4FFFFFFF) + +/* Enable system reset request for CPU 0 */ +#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U) + +/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field, + * otherwise the processor ignores the write. + */ +#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)) + +/* Debug configuration flags */ +#define SPNIDEN_SEL_STATUS (0x01u << 7) +#define SPNIDEN_STATUS (0x01u << 6) +#define SPIDEN_SEL_STATUS (0x01u << 5) +#define SPIDEN_STATUS (0x01u << 4) +#define NIDEN_SEL_STATUS (0x01u << 3) +#define NIDEN_STATUS (0x01u << 2) +#define DBGEN_SEL_STATUS (0x01u << 1) +#define DBGEN_STATUS (0x01u << 0) + +#define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | \ + NIDEN_SEL_STATUS | DBGEN_SEL_STATUS) + +struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = { + UART0_BASE_NS, + UART0_BASE_NS + 0xFFF, + PPC_SP_DO_NOT_CONFIGURE, + -1 +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io = { + FPGA_IO_BASE_S, + FPGA_IO_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP2, + FPGA_IO_PERIPH_PPCEXP2_POS_MASK +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_timer0 = { + SYSTIMER0_ARMV8_M_BASE_S, + SYSTIMER0_ARMV8_M_BASE_S + 0xFFF, + PPC_SP_PERIPH0, + SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK +}; + +static DRIVER_PPC_SSE300 *const ppc_bank_drivers[] = { + &Driver_PPC_SSE300_MAIN0, + &Driver_PPC_SSE300_MAIN_EXP0, + &Driver_PPC_SSE300_MAIN_EXP1, + &Driver_PPC_SSE300_PERIPH0, + &Driver_PPC_SSE300_PERIPH1, + &Driver_PPC_SSE300_PERIPH_EXP0, + &Driver_PPC_SSE300_PERIPH_EXP1, + &Driver_PPC_SSE300_PERIPH_EXP2, +}; + +#define PPC_BANK_COUNT (sizeof(ppc_bank_drivers)/sizeof(ppc_bank_drivers[0])) + +enum tfm_plat_err_t enable_fault_handlers(void) +{ + /* Explicitly set secure fault priority to the highest */ + NVIC_SetPriority(SecureFault_IRQn, 0); + + /* 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; + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t system_reset_cfg(void) +{ + struct sse300_sysctrl_t *sysctrl = + (struct sse300_sysctrl_t *)SSE300_SYSCTRL_BASE_S; + uint32_t reg_value = SCB->AIRCR; + + /* Enable system reset request for CPU 0, to be triggered via + * NVIC_SystemReset function. + */ + sysctrl->reset_mask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST; + + /* Clear SCB_AIRCR_VECTKEY value */ + reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk); + + /* Enable system reset request only to the secure world */ + reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk); + + SCB->AIRCR = reg_value; + + return TFM_PLAT_ERR_SUCCESS; +} + +/*--------------------- NVIC interrupt NS/S configuration --------------------*/ +enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) +{ + uint8_t i; + + /* Target every interrupt to NS; unimplemented interrupts will be WI */ + for (i = 0; i < (sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0])); i++) { + NVIC->ITNS[i] = 0xFFFFFFFF; + } + + /* Make sure that MPC and PPC are targeted to S state */ + NVIC_ClearTargetState(MPC_IRQn); + NVIC_ClearTargetState(PPC_IRQn); + +#ifdef SECURE_UART1 + /* UART1 is a secure peripheral, so its IRQs have to target S state */ + NVIC_ClearTargetState(UARTRX1_IRQn); + NVIC_ClearTargetState(UARTTX1_IRQn); +#endif + + return TFM_PLAT_ERR_SUCCESS; +} + +/*----------------- NVIC interrupt enabling for S peripherals ----------------*/ +enum tfm_plat_err_t nvic_interrupt_enable(void) +{ + int32_t ret = ARM_DRIVER_OK; + int32_t i = 0; + + /* MPC interrupt enabling */ + mpc_clear_irq(); + ret = Driver_ISRAM0_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_ISRAM1_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for ISRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + NVIC_ClearPendingIRQ(MPC_IRQn); + NVIC_EnableIRQ(MPC_IRQn); + + /* PPC interrupt enabling */ + ppc_clear_irq(); + + for (i = 0; i < PPC_BANK_COUNT; i++) { + ret = ppc_bank_drivers[i]->EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + //ERROR_MSG("Failed to Enable interrupt on PPC bank number %d!", i); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + } + + NVIC_ClearPendingIRQ(PPC_IRQn); + NVIC_EnableIRQ(PPC_IRQn); + +#ifdef PSA_FF_TEST_SECURE_UART2 + NVIC_EnableIRQ(FF_TEST_UART_IRQ); +#endif + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t init_debug(void) +{ + struct sse300_sysctrl_t *sysctrl = + (struct sse300_sysctrl_t *)SSE300_SYSCTRL_BASE_S; + +#if defined(DAUTH_NONE) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 0 */ + sysctrl->secdbgclr = + DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_NS_ONLY) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set the debug enable bits to 1 for NS, and 0 for S mode */ + sysctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS; + sysctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_FULL) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 1 */ + sysctrl->secdbgset = + DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS; +#else + +#if !defined(DAUTH_CHIP_DEFAULT) +#error "No debug authentication setting is provided." +#endif + + /* Set all the debug enable selector bits to 0 */ + sysctrl->secdbgclr = All_SEL_STATUS; + + /* No need to set any enable bits because the value depends on + * input signals. + */ +#endif + return TFM_PLAT_ERR_SUCCESS; +} + +/*------------------- SAU/IDAU configuration functions -----------------------*/ +void sau_and_idau_cfg(void) +{ + struct sse300_sacfg_t *sacfg = (struct sse300_sacfg_t*)SSE300_SACFG_BASE_S; + + /* Enables SAU */ + TZ_SAU_Enable(); + + /* Configures SAU regions to be non-secure */ + SAU->RNR = 0; + SAU->RBAR = (memory_regions.non_secure_partition_base + & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.non_secure_partition_limit + & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + SAU->RNR = 1; + SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (NS_DATA_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Configures veneers region to be non-secure callable */ + SAU->RNR = 2; + SAU->RBAR = (memory_regions.veneer_base & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk) + | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk; + + /* Configure the peripherals space */ + SAU->RNR = 3; + SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk) + | SAU_RLAR_ENABLE_Msk; + + /* Secondary image partition */ + SAU->RNR = 4; + SAU->RBAR = (memory_regions.secondary_partition_base + & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.secondary_partition_limit + & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Allows SAU to define the RAM region as a NSC */ + sacfg->nsccfg |= RAMNSC; +} + +/*------------------- Memory configuration functions -------------------------*/ +enum tfm_plat_err_t mpc_init_cfg(void) +{ + int32_t ret = ARM_DRIVER_OK; + + /* ISRAM0 and ISRAM1 memories allocated for NS data, so whole range set to + * non-secure accesible. */ + ret = Driver_ISRAM0_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_ISRAM0_MPC.ConfigRegion(MPC_ISRAM0_RANGE_BASE_NS, + MPC_ISRAM0_RANGE_LIMIT_NS, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_ISRAM1_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for ISRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_ISRAM1_MPC.ConfigRegion(MPC_ISRAM1_RANGE_BASE_NS, + MPC_ISRAM1_RANGE_LIMIT_NS, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for ISRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Configuring primary and secondary non-secure partition. + * It is ensured in flash_layout.h that these memory regions are located in + * SRAM SRAM device. */ + ret = Driver_SRAM_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM_MPC.ConfigRegion( + memory_regions.non_secure_partition_base, + memory_regions.non_secure_partition_limit, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM_MPC.ConfigRegion( + memory_regions.secondary_partition_base, + memory_regions.secondary_partition_limit, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Lock down the MPC configuration */ + ret = Driver_ISRAM0_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_ISRAM1_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for ISRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Lock down not used MPC's */ + Driver_QSPI_MPC.LockDown(); + + /* Add barriers to assure the MPC configuration is done before continue + * the execution. + */ + __DSB(); + __ISB(); + + return TFM_PLAT_ERR_SUCCESS; +} + +void mpc_clear_irq(void) +{ + Driver_ISRAM0_MPC.ClearInterrupt(); + Driver_ISRAM1_MPC.ClearInterrupt(); + Driver_SRAM_MPC.ClearInterrupt(); +} + +/*------------------- PPC configuration functions -------------------------*/ +enum tfm_plat_err_t ppc_init_cfg(void) +{ + struct sse300_sacfg_t *sacfg = + (struct sse300_sacfg_t*)SSE300_SACFG_BASE_S; + int32_t err = ARM_DRIVER_OK; + + /* Grant non-secure access to peripherals on MAIN EXP0 */ + err |= Driver_PPC_SSE300_MAIN_EXP0.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity( + GPIO0_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity( + GPIO1_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity( + GPIO2_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity( + GPIO3_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity( + USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on MAIN EXP1 */ + err |= Driver_PPC_SSE300_MAIN_EXP1.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity( + DMA0_MAIN_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity( + DMA1_MAIN_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity( + DMA2_MAIN_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity( + DMA3_MAIN_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH0 */ + err |= Driver_PPC_SSE300_PERIPH0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity( + SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity( + SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity( + SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity( + SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity( + WATCHDOG_PERIPH_PPC0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH1 */ + err |= Driver_PPC_SSE300_PERIPH1.Initialize(); + err |= Driver_PPC_SSE300_PERIPH1.ConfigSecurity( + SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH EXP2 */ + err |= Driver_PPC_SSE300_PERIPH_EXP2.Initialize(); + + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + FPGA_I2S_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + FPGA_IO_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART0_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART1_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART2_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART3_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART4_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + UART5_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + CLCD_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant un-privileged access for UART0 in NS domain */ + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigPrivilege( + UART0_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG, + PPC_SSE300_PRIV_AND_NONPRIV_CONFIG); + + /* Initialize not used PPC drivers */ + err |= Driver_PPC_SSE300_MAIN0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP1.Initialize(); + + /* + * Configure the response to a security violation as a + * bus error instead of RAZ/WI + */ + sacfg->secrespcfg |= CMSDK_SECRESPCFG_BUS_ERR_MASK; + + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigSecurity(pos, PPC_SSE300_SECURE_CONFIG); + } +} + +void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigSecurity(pos, PPC_SSE300_NONSECURE_CONFIG); + } +} + +void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigPrivilege(pos, + PPC_SSE300_SECURE_CONFIG, + PPC_SSE300_PRIV_AND_NONPRIV_CONFIG); + } +} + +void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigPrivilege(pos, + PPC_SSE300_SECURE_CONFIG, + PPC_SSE300_PRIV_CONFIG); + } +} + +void ppc_clear_irq(void) +{ + int32_t i = 0; + + for (i = 0; i < PPC_BANK_COUNT; i++) { + ppc_bank_drivers[i]->ClearInterrupt(); + } +} diff --git a/platform/ext/target/mps3/fvp_sse300/target_cfg.h b/platform/ext/target/mps3/fvp_sse300/target_cfg.h new file mode 100644 index 0000000000..f18c8e539c --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/target_cfg.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019-2020 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 __TARGET_CFG_H__ +#define __TARGET_CFG_H__ + +#include <stdint.h> +#include "tfm_peripherals_def.h" +#include "tfm_plat_defs.h" + +#define TFM_DRIVER_STDIO Driver_USART0 +#define NS_DRIVER_STDIO Driver_USART0 + +/** + * \brief Defines the word offsets of Slave Peripheral Protection Controller + * Registers + */ +enum ppc_bank_e +{ + PPC_SP_DO_NOT_CONFIGURE = -1, + PPC_SP_MAIN0 = 0, + PPC_SP_MAIN_EXP0 = 1, + PPC_SP_MAIN_EXP1 = 2, + PPC_SP_PERIPH0 = 3, + PPC_SP_PERIPH1 = 4, + PPC_SP_PERIPH_EXP0 = 5, + PPC_SP_PERIPH_EXP1 = 6, + PPC_SP_PERIPH_EXP2 = 7, +}; + +/** + * \brief Store the addresses of memory regions + */ +struct memory_region_limits { + uint32_t non_secure_code_start; + uint32_t non_secure_partition_base; + uint32_t non_secure_partition_limit; + uint32_t veneer_base; + uint32_t veneer_limit; +#ifdef BL2 + uint32_t secondary_partition_base; + uint32_t secondary_partition_limit; +#endif /* BL2 */ +}; + +/** + * \brief Holds the data necessary to do isolation for a specific peripheral. + */ +struct tfm_spm_partition_platform_data_t { + uint32_t periph_start; + uint32_t periph_limit; + enum ppc_bank_e periph_ppc_bank; + int16_t periph_ppc_mask; +}; + +/** + * \brief Enables the fault handlers BusFault, UsageFault, + * MemManageFault and SecureFault. + */ +enum tfm_plat_err_t enable_fault_handlers(void); + +/** + * \brief Configures the system reset request properties + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t system_reset_cfg(void); + +/** + * \brief Configures all external interrupts to target the + * NS state, apart for the ones associated to secure + * peripherals (plus MPC and PPC) + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void); + +/** + * \brief This function enable the interrupts associated + * to the secure peripherals (plus MPC and PPC) + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t nvic_interrupt_enable(void); + +/** + * \brief Configures the system debug properties. + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t init_debug(void); + +/** + * \brief Configures the Memory Protection Controller. + * + * \return Returns error code. + */ +enum tfm_plat_err_t mpc_init_cfg(void); + +/** + * \brief Clear MPC interrupt. + */ +void mpc_clear_irq(void); + +/** + * \brief Configures the Peripheral Protection Controller. + */ +enum tfm_plat_err_t ppc_init_cfg(void); + +/** + * \brief Restict peripheral access to secure access only + * + * \note The function does not configure privilege + */ +void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Allow non-secure access to peripheral + * + * \note The function does not configure privilege + */ +void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Enable secure unprivileged access to peripheral + */ +void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Clear secure unprivileged access to peripheral + */ +void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Clears PPC interrupt. + */ +void ppc_clear_irq(void); + +/** + * \brief Configures SAU and IDAU. + */ +void sau_and_idau_cfg(void); + +#endif /* __TARGET_CFG_H__ */ diff --git a/platform/ext/target/mps3/fvp_sse300/tfm_hal_isolation.c b/platform/ext/target/mps3/fvp_sse300/tfm_hal_isolation.c new file mode 100644 index 0000000000..b5d27ed676 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/tfm_hal_isolation.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "cmsis.h" +#include "Driver_Common.h" +#include "mpu_armv8m_drv.h" +#include "region.h" +#include "target_cfg.h" +#include "tfm_hal_isolation.h" + +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT +#if TFM_LVL != 3 +#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) + +#define MPU_REGION_VENEERS 0 +#define MPU_REGION_TFM_UNPRIV_CODE 1 +#define MPU_REGION_TFM_UNPRIV_DATA 2 +#define MPU_REGION_NS_STACK 3 +#define PARTITION_REGION_RO 4 +#define PARTITION_REGION_RW_STACK 5 + +REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base); +REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit); +REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base); +REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit); +REGION_DECLARE(Image$$, TFM_UNPRIV_DATA, $$RW$$Base); +REGION_DECLARE(Image$$, TFM_UNPRIV_DATA, $$ZI$$Limit); +REGION_DECLARE(Image$$, TFM_APP_CODE_START, $$Base); +REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base); +REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base); +REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base); +REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base); +REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Limit); + +const struct mpu_armv8m_region_cfg_t region_cfg[] = { + /* Veneer region */ + { + MPU_REGION_VENEERS, + (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base), + (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Limit), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, + MPU_ARMV8M_XN_EXEC_OK, + MPU_ARMV8M_AP_RO_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + }, + /* TFM Core unprivileged code region */ + { + MPU_REGION_TFM_UNPRIV_CODE, + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base), + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, + MPU_ARMV8M_XN_EXEC_OK, + MPU_ARMV8M_AP_RO_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + }, + /* TFM Core unprivileged data region */ + { + MPU_REGION_TFM_UNPRIV_DATA, + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_DATA, $$RW$$Base), + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_DATA, $$ZI$$Limit), + MPU_ARMV8M_MAIR_ATTR_DATA_IDX, + MPU_ARMV8M_XN_EXEC_NEVER, + MPU_ARMV8M_AP_RW_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + }, + /* NSPM PSP */ + { + MPU_REGION_NS_STACK, + (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base), + (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit), + MPU_ARMV8M_MAIR_ATTR_DATA_IDX, + MPU_ARMV8M_XN_EXEC_NEVER, + MPU_ARMV8M_AP_RW_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + }, + /* RO region */ + { + PARTITION_REGION_RO, + (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base), + (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, + MPU_ARMV8M_XN_EXEC_OK, + MPU_ARMV8M_AP_RO_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + }, + /* RW, ZI and stack as one region */ + { + PARTITION_REGION_RW_STACK, + (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base), + (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base), + MPU_ARMV8M_MAIR_ATTR_DATA_IDX, + MPU_ARMV8M_XN_EXEC_NEVER, + MPU_ARMV8M_AP_RW_PRIV_UNPRIV, + MPU_ARMV8M_SH_NONE + } +}; +#endif /* TFM_LVL != 3 */ +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + +enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void) +{ + /* Set up isolation boundaries between SPE and NSPE */ + sau_and_idau_cfg(); + + if (mpc_init_cfg() != TFM_PLAT_ERR_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + + if (ppc_init_cfg() != TFM_PLAT_ERR_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + + /* Set up static isolation boundaries inside SPE */ +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT +#if TFM_LVL != 3 + int32_t i; + struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE }; + + mpu_armv8m_clean(&dev_mpu_s); + + for (i = 0; i < ARRAY_SIZE(region_cfg); i++) { + if (mpu_armv8m_region_enable(&dev_mpu_s, + (struct mpu_armv8m_region_cfg_t *)®ion_cfg[i]) + != MPU_ARMV8M_OK) { + return TFM_HAL_ERROR_GENERIC; + } + } + + mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE, + HARDFAULT_NMI_ENABLE); +#endif /* TFM_LVL != 3 */ +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + + return TFM_HAL_SUCCESS; +} diff --git a/platform/ext/target/mps3/fvp_sse300/tfm_peripherals_def.h b/platform/ext/target/mps3/fvp_sse300/tfm_peripherals_def.h new file mode 100644 index 0000000000..ca169b0a32 --- /dev/null +++ b/platform/ext/target/mps3/fvp_sse300/tfm_peripherals_def.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PERIPHERALS_DEF_H__ +#define __TFM_PERIPHERALS_DEF_H__ + +#include "platform_irq.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TFM_TIMER0_IRQ (TIMER0_IRQn) +#define TFM_TIMER1_IRQ (TIMER1_IRQn) + +struct tfm_spm_partition_platform_data_t; + +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_timer0; + +#define TFM_PERIPHERAL_STD_UART (&tfm_peripheral_std_uart) +#define TFM_PERIPHERAL_FPGA_IO (&tfm_peripheral_fpga_io) +#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0) + +#ifdef PSA_API_TEST_IPC +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_FF_TEST_UART_REGION; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_FF_TEST_WATCHDOG_REGION; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_FF_TEST_NVMEM_REGION; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO; +#define FF_TEST_UART_REGION (&tfm_peripheral_FF_TEST_UART_REGION) +#define FF_TEST_WATCHDOG_REGION (&tfm_peripheral_FF_TEST_WATCHDOG_REGION) +#define FF_TEST_NVMEM_REGION (&tfm_peripheral_FF_TEST_NVMEM_REGION) +#define FF_TEST_SERVER_PARTITION_MMIO (&tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO) +#define FF_TEST_DRIVER_PARTITION_MMIO (&tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO) +#endif /* PSA_API_TEST_IPC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PERIPHERALS_DEF_H__ */ |