diff options
55 files changed, 12558 insertions, 44 deletions
diff --git a/configs/ConfigCoreIPC.cmake b/configs/ConfigCoreIPC.cmake index 120f7d3146..3b85b45f56 100644 --- a/configs/ConfigCoreIPC.cmake +++ b/configs/ConfigCoreIPC.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2018-2019, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/configs/ConfigCoreIPCTfmLevel2.cmake b/configs/ConfigCoreIPCTfmLevel2.cmake index 0237f5f47f..f19626ceb8 100644 --- a/configs/ConfigCoreIPCTfmLevel2.cmake +++ b/configs/ConfigCoreIPCTfmLevel2.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/configs/ConfigDefault.cmake b/configs/ConfigDefault.cmake index 009fa55810..d43d48b994 100644 --- a/configs/ConfigDefault.cmake +++ b/configs/ConfigDefault.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2017-2019, Arm Limited. All rights reserved. +# Copyright (c) 2017-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/configs/ConfigRegression.cmake b/configs/ConfigRegression.cmake index 0bba434f9a..dae7bcad0c 100644 --- a/configs/ConfigRegression.cmake +++ b/configs/ConfigRegression.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2017-2019, Arm Limited. All rights reserved. +# Copyright (c) 2017-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/configs/ConfigRegressionIPC.cmake b/configs/ConfigRegressionIPC.cmake index 2f65b6b6a2..1485b00eda 100644 --- a/configs/ConfigRegressionIPC.cmake +++ b/configs/ConfigRegressionIPC.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/configs/ConfigRegressionIPCTfmLevel2.cmake b/configs/ConfigRegressionIPCTfmLevel2.cmake index 963a88118c..162d224005 100644 --- a/configs/ConfigRegressionIPCTfmLevel2.cmake +++ b/configs/ConfigRegressionIPCTfmLevel2.cmake @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN519") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN519.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN539") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN539.cmake") +elseif(${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2") + set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/fvp_sse300_mps2.cmake") elseif(${TARGET_PLATFORM} STREQUAL "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "LPC55S69") diff --git a/docs/readme.rst b/docs/readme.rst index 51657c5353..c0d6d0a457 100644 --- a/docs/readme.rst +++ b/docs/readme.rst @@ -88,6 +88,11 @@ Further documents can be found in the ``docs`` folder. ################### Platforms supported ################### + - Cortex-M55 system: + + - `Fast model FVP_SSE300_MPS2. + <https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps>`_ + - Cortex-M33 system: - `FPGA image loaded on MPS2 board. diff --git a/docs/user_guides/tfm_build_instruction.rst b/docs/user_guides/tfm_build_instruction.rst index d19077ffe4..8ed8c2db0b 100644 --- a/docs/user_guides/tfm_build_instruction.rst +++ b/docs/user_guides/tfm_build_instruction.rst @@ -250,6 +250,8 @@ line arguments: ``-DTARGET_PLATFORM=AN519`` - Arm SSE-123 Example Subsystem for MPS2+ (AN539) ``-DTARGET_PLATFORM=AN539`` + - Cortex-M55 SSE-300 subsystem for MPS2+ FVP + ``-DTARGET_PLATFORM=FVP_SSE300_MPS2`` - Musca-A test chip board (Cortex-M33 SSE-200 subsystem) ``-DTARGET_PLATFORM=MUSCA_A`` - Musca-B1 test chip board (Cortex-M33 SSE-200 subsystem) diff --git a/docs/user_guides/tfm_build_instruction_iar.rst b/docs/user_guides/tfm_build_instruction_iar.rst index 847587a4b3..b62d51d747 100644 --- a/docs/user_guides/tfm_build_instruction_iar.rst +++ b/docs/user_guides/tfm_build_instruction_iar.rst @@ -12,7 +12,7 @@ Notes for building with IARARM IAR Embedded Workbench for ARM (EWARM) versions 8.42 or later are required. Currently the MUSCA_B1, MUSCA_S1 and SSE-200_AWS targets are not supported with IARARM, - due to lack of testing. + due to lack of testing. The FVP_SSE300_MPS2 target is currently not supported by IARARM. bash needs to be installed and used by cmake for the build steps. diff --git a/docs/user_guides/tfm_integration_guide.rst b/docs/user_guides/tfm_integration_guide.rst index 3c4aa8e16d..d320a0e088 100644 --- a/docs/user_guides/tfm_integration_guide.rst +++ b/docs/user_guides/tfm_integration_guide.rst @@ -22,6 +22,7 @@ The hardware platforms currently supported are: - Soft Macro Model (SMM) Cortex-M33 SSE-200 subsystem for MPS2+ (AN521) - Cortex-M23 IoT Kit subsystem for MPS2+ (AN519) - Arm SSE-123 Example Subsystem for MPS2+ (AN539) +- Cortex-M55 SSE-300 subsystem for MPS2+ FVP - Musca-A test chip board (Cortex-M33 SSE-200 subsystem) - Musca-B1 test chip board (Cortex-M33 SSE-200 subsystem) - Musca-S1 test chip board (Cortex-M33 SSE-200 subsystem) diff --git a/docs/user_guides/tfm_secure_boot.rst b/docs/user_guides/tfm_secure_boot.rst index 54c84d9f8f..a62d836759 100644 --- a/docs/user_guides/tfm_secure_boot.rst +++ b/docs/user_guides/tfm_secure_boot.rst @@ -218,33 +218,35 @@ overwriting, swapping, non-swapping or loading into RAM and executing from there) are supported by the platforms. The table below shows which of these modes are supported by which platforms: -+-------------+-----------------+----------------------------------------------------------+ -| | Without BL2 [1]_| With BL2 [2]_ | -+=============+=================+===============+==========+=============+=================+ -| | XIP | XIP | XIP | XIP | Not XIP | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| | | Overwrite [3]_| Swap [4]_| No-swap [5]_| RAM loading [6]_| -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| AN521 | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| AN519 | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| AN539 | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| LPC55S69 | No | No | No | No | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| Musca-A | No | No | No | No | Yes | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| Musca-B1 | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| Musca-S1 | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| AN524 | Yes | No | No | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| PSoC64 | Yes | No | No | No | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ -| SSE-200_AWS | Yes | Yes | Yes | Yes | No | -+-------------+-----------------+---------------+----------+-------------+-----------------+ ++------------------+-----------------+----------------------------------------------------------+ +| | Without BL2 [1]_| With BL2 [2]_ | ++==================+=================+===============+==========+=============+=================+ +| | XIP | XIP | XIP | XIP | Not XIP | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| | | Overwrite [3]_| Swap [4]_| No-swap [5]_| RAM loading [6]_| ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| AN521 | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| AN519 | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| AN539 | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| FVP_SSE300_MPS2 | NO | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| LPC55S69 | No | No | No | No | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| Musca-A | No | No | No | No | Yes | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| Musca-B1 | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| Musca-S1 | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| AN524 | Yes | No | No | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| PSoC64 | Yes | No | No | No | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ +| SSE-200_AWS | Yes | Yes | Yes | Yes | No | ++------------------+-----------------+---------------+----------+-------------+-----------------+ .. [1] To disable BL2, please turn off the ``BL2`` compiler switch in the build configuration file (``bl2/ext/mcuboot/MCUBootConfig.cmake``) or diff --git a/platform/ext/fvp_sse300_mps2.cmake b/platform/ext/fvp_sse300_mps2.cmake new file mode 100644 index 0000000000..f9c2848fdc --- /dev/null +++ b/platform/ext/fvp_sse300_mps2.cmake @@ -0,0 +1,196 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +#This file gathers all fvp_sse300_mps2 specific files in the application. + +#sse300 has a v8.1-M.Main processor +include("Common/CpuArmv81mml") + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(FVP_SSE300_DIR ${PLATFORM_DIR}/target/mps2/fvp_sse300) + +#Specify the location of platform specific build dependencies. +#FIXME use CMAKE_C_COMPILER_ID here instead? +if(COMPILER STREQUAL "ARMCLANG") + set (S_SCATTER_FILE_NAME "${PLATFORM_DIR}/common/armclang/tfm_common_s.sct") + set (BL2_SCATTER_FILE_NAME "${FVP_SSE300_DIR}/device/source/armclang/fvp_sse300_mps2_bl2.sct") + set (NS_SCATTER_FILE_NAME "${FVP_SSE300_DIR}/device/source/armclang/fvp_sse300_mps2_ns.sct") + if (DEFINED CMSIS_5_DIR) + # not all project defines CMSIS_5_DIR, only the ones that use it. + set (RTX_LIB_PATH "${CMSIS_5_DIR}/CMSIS/RTOS2/RTX/Library/ARM/RTX_V8MMN.lib") + endif() +elseif(COMPILER STREQUAL "GNUARM") + message(FATAL_ERROR "No GNUARM support yet for target '${TARGET_PLATFORM}'.") +elseif(COMPILER STREQUAL "IARARM") + message(FATAL_ERROR "No IARARM support yet for target '${TARGET_PLATFORM}'.") +else() + message(FATAL_ERROR "Invalid compiler specified: '${COMPILER}'.") +endif() +set (FLASH_LAYOUT "${FVP_SSE300_DIR}/partition/flash_layout.h") +set (PLATFORM_LINK_INCLUDES "${FVP_SSE300_DIR}/partition") + +if (BL2) + set (BL2_LINKER_CONFIG ${BL2_SCATTER_FILE_NAME}) + if (${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "RAM_LOADING") + message(FATAL_ERROR "ERROR: RAM_LOADING upgrade strategy is not supported on target '${TARGET_PLATFORM}'.") + endif() + #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/template/tfm_rotpk.c + # instead independently loaded from secure code as a blob. + if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048") + add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048) + endif() + if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072") + add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072) + endif() +else() + message(FATAL_ERROR "BL2 is mandatory on target '${TARGET_PLATFORM}'.") +endif() + +embedded_include_directories(PATH "${PLATFORM_DIR}/cmsis" ABSOLUTE) +embedded_include_directories(PATH "${PLATFORM_DIR}/target/mps2" ABSOLUTE) +embedded_include_directories(PATH "${PLATFORM_DIR}/../include" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}/partition" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}/device/include" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}/device/config" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}/cmsis_drivers/config" ABSOLUTE) +embedded_include_directories(PATH "${FVP_SSE300_DIR}/native_drivers" ABSOLUTE) + +#Gather all source files we need. +if (NOT DEFINED BUILD_CMSIS_CORE) + message(FATAL_ERROR "Configuration variable BUILD_CMSIS_CORE (true|false) is undefined!") +elseif(BUILD_CMSIS_CORE) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/device/source/system_core_init.c") +endif() + +if (NOT DEFINED BUILD_RETARGET) + message(FATAL_ERROR "Configuration variable BUILD_RETARGET (true|false) is undefined!") +elseif(BUILD_RETARGET) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/device/source/device_definition.c") +endif() + +if (NOT DEFINED BUILD_UART_STDOUT) + message(FATAL_ERROR "Configuration variable BUILD_UART_STDOUT (true|false) is undefined!") +elseif(BUILD_UART_STDOUT) + if (NOT DEFINED SECURE_UART1) + message(FATAL_ERROR "Configuration variable SECURE_UART1 (true|false) is undefined!") + elseif(SECURE_UART1) + add_definitions(-DSECURE_UART1) + endif() + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/uart_stdout.c") + embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE) + set(BUILD_NATIVE_DRIVERS true) + set(BUILD_CMSIS_DRIVERS true) +endif() + +if (NOT DEFINED BUILD_NATIVE_DRIVERS) + message(FATAL_ERROR "Configuration variable BUILD_NATIVE_DRIVERS (true|false) is undefined!") +elseif(BUILD_NATIVE_DRIVERS) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/native_drivers/uart_cmsdk_drv.c") + + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/native_drivers/mpc_sie_drv.c" + "${FVP_SSE300_DIR}/native_drivers/ppc_sse300_drv.c") +endif() + +if (NOT DEFINED BUILD_TIME) + message(FATAL_ERROR "Configuration variable BUILD_TIME (true|false) is undefined!") +elseif(BUILD_TIME) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/native_drivers/systimer_armv8-m_drv.c") +endif() + +if (NOT DEFINED BUILD_STARTUP) + message(FATAL_ERROR "Configuration variable BUILD_STARTUP (true|false) is undefined!") +elseif(BUILD_STARTUP) + if(CMAKE_C_COMPILER_ID STREQUAL "ARMCLANG") + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/device/source/startup_fvp_sse300_mps2_s.c") + list(APPEND ALL_SRC_C_NS "${FVP_SSE300_DIR}/device/source/startup_fvp_sse300_mps2_ns.c") + list(APPEND ALL_SRC_C_BL2 "${FVP_SSE300_DIR}/device/source/startup_fvp_sse300_mps2_bl2.c") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNUARM") + message(FATAL_ERROR "No GNUARM support yet for target '${TARGET_PLATFORM}'.") + else() + message(FATAL_ERROR "No startup file is available for compiler '${CMAKE_C_COMPILER_ID}'.") + endif() +endif() + +if (NOT DEFINED BUILD_TARGET_CFG) + message(FATAL_ERROR "Configuration variable BUILD_TARGET_CFG (true|false) is undefined!") +elseif(BUILD_TARGET_CFG) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/target_cfg.c") + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/spm_hal.c") + list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/common/template/attest_hal.c") + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/native_drivers/mpu_armv8m_drv.c") + if (TFM_PARTITION_PLATFORM) + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/services/src/tfm_platform_system.c") + endif() + list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/common/tfm_platform.c") + embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE) +endif() + +if (NOT DEFINED BUILD_PLAT_TEST) + message(FATAL_ERROR "Configuration variable BUILD_PLAT_TEST (true|false) is undefined!") +elseif(BUILD_PLAT_TEST) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/plat_test.c") +endif() + +if (NOT DEFINED BUILD_BOOT_HAL) + message(FATAL_ERROR "Configuration variable BUILD_BOOT_HAL (true|false) is undefined!") +elseif(BUILD_BOOT_HAL) + + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/boot_hal.c") + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/boot_hal.c") +endif() + +if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS) + message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!") +elseif(BUILD_TARGET_HARDWARE_KEYS) + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/tfm_initial_attestation_key_material.c") + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/tfm_rotpk.c") + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/crypto_keys.c") +endif() + +if (NOT DEFINED BUILD_TARGET_NV_COUNTERS) + message(FATAL_ERROR "Configuration variable BUILD_TARGET_NV_COUNTERS (true|false) is undefined!") +elseif(BUILD_TARGET_NV_COUNTERS) + # NOTE: This non-volatile counters implementation is a dummy + # implementation. Platform vendors have to implement the + # API ONLY if the target has non-volatile counters. + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/template/nv_counters.c") + set(TARGET_NV_COUNTERS_ENABLE ON) + # Sets SST_ROLLBACK_PROTECTION flag to compile in the SST services + # rollback protection code as the target supports nv counters. + set(SST_ROLLBACK_PROTECTION ON) +endif() + +if (NOT DEFINED BUILD_CMSIS_DRIVERS) + message(FATAL_ERROR "Configuration variable BUILD_CMSIS_DRIVERS (true|false) is undefined!") +elseif(BUILD_CMSIS_DRIVERS) + list(APPEND ALL_SRC_C_S "${FVP_SSE300_DIR}/cmsis_drivers/Driver_MPC.c" + "${FVP_SSE300_DIR}/cmsis_drivers/Driver_Flash.c" + "${FVP_SSE300_DIR}/cmsis_drivers/Driver_SSE300_PPC.c") + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/cmsis_drivers/Driver_USART.c") + embedded_include_directories(PATH "${FVP_SSE300_DIR}/cmsis_drivers" ABSOLUTE) + embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE) +endif() + +if (NOT DEFINED BUILD_FLASH) + message(FATAL_ERROR "Configuration variable BUILD_FLASH (true|false) is undefined!") +elseif(BUILD_FLASH) + list(APPEND ALL_SRC_C "${FVP_SSE300_DIR}/cmsis_drivers/Driver_Flash.c") + # There is no real flash memory for code on MPS2 fvp. Instead data SRAMs are used for code + # storage: SSRAM2 and SSRAM3. The Driver_Flash driver just emulates a flash interface and behaviour on + # top of the SRAM memory. + # As the SST area is going to be in RAM, it is required to set SST_CREATE_FLASH_LAYOUT + # to be sure the SST service knows that when it starts the SST area does not contain any + # valid SST flash layout and it needs to create one. The same for ITS. + set(SST_CREATE_FLASH_LAYOUT ON) + set(SST_RAM_FS OFF) + set(ITS_CREATE_FLASH_LAYOUT ON) + set(ITS_RAM_FS OFF) + embedded_include_directories(PATH "${FVP_SSE300_DIR}/cmsis_drivers" ABSOLUTE) + embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE) +endif() diff --git a/platform/ext/target/mps2/fvp_sse300/boot_hal.c b/platform/ext/target/mps2/fvp_sse300/boot_hal.c new file mode 100644 index 0000000000..d5a804db91 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/boot_hal.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "cmsis.h" +#include "region.h" + +REGION_DECLARE(Image$$, ER_DATA, $$Base)[]; +REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[]; + +__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" + ); +} diff --git a/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_Flash.c b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_Flash.c new file mode 100644 index 0000000000..25966e5eb5 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,284 @@ +/* + * 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 SSRAM2_BASE_S +#define FLASH0_BASE_NS SSRAM2_BASE_NS +#define FLASH0_SIZE SSRAM2_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 + * + * There is no real flash memory for code on MPS2 board. Instead a code SRAM is + * used for code storage: ZBT SSRAM1. 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/mps2/fvp_sse300/cmsis_drivers/Driver_MPC.c b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_MPC.c new file mode 100644 index 0000000000..53a46180e8 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_MPC.c @@ -0,0 +1,2019 @@ +/* + * 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 "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_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_ISRAM2_MPC) +/* Ranges controlled by this ISRAM2_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM2_RANGE_S = { + .base = MPC_ISRAM2_RANGE_BASE_S, + .limit = MPC_ISRAM2_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM2_RANGE_NS = { + .base = MPC_ISRAM2_RANGE_BASE_NS, + .limit = MPC_ISRAM2_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM2_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_ISRAM2_RANGE_LIST[MPC_ISRAM2_RANGE_LIST_LEN] = { + &MPC_ISRAM2_RANGE_S, + &MPC_ISRAM2_RANGE_NS + }; + +/* ISRAM2_MPC Driver wrapper functions */ +static int32_t ISRAM2_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM2_DEV, + MPC_ISRAM2_RANGE_LIST, + MPC_ISRAM2_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM2_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM2_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM2_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM2_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM2_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_ISRAM2_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t ISRAM2_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_ISRAM2_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM2_DEV); + + return error_trans(ret); +} + +static void ISRAM2_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM2_DEV); +} + +static void ISRAM2_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM2_DEV); +} + +static uint32_t ISRAM2_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM2_DEV); +} + +static int32_t ISRAM2_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM2_DEV); +} + +/* ISRAM2_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM2_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM2_MPC_Initialize, + .Uninitialize = ISRAM2_MPC_Uninitialize, + .GetBlockSize = ISRAM2_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM2_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM2_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM2_MPC_ConfigRegion, + .GetRegionConfig = ISRAM2_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM2_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM2_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM2_MPC_ClearInterrupt, + .InterruptState = ISRAM2_MPC_InterruptState, + .LockDown = ISRAM2_MPC_LockDown, +}; +#endif /* RTE_ISRAM2_MPC */ + +#if (RTE_ISRAM3_MPC) +/* Ranges controlled by this ISRAM3_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM3_RANGE_S = { + .base = MPC_ISRAM3_RANGE_BASE_S, + .limit = MPC_ISRAM3_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM3_RANGE_NS = { + .base = MPC_ISRAM3_RANGE_BASE_NS, + .limit = MPC_ISRAM3_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM3_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_ISRAM3_RANGE_LIST[MPC_ISRAM3_RANGE_LIST_LEN] = { + &MPC_ISRAM3_RANGE_S, + &MPC_ISRAM3_RANGE_NS + }; + +/* ISRAM3_MPC Driver wrapper functions */ +static int32_t ISRAM3_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM3_DEV, + MPC_ISRAM3_RANGE_LIST, + MPC_ISRAM3_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM3_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM3_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM3_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM3_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM3_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_ISRAM3_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t ISRAM3_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_ISRAM3_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM3_DEV); + + return error_trans(ret); +} + +static void ISRAM3_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM3_DEV); +} + + +static void ISRAM3_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM3_DEV); +} + +static uint32_t ISRAM3_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM3_DEV); +} + +static int32_t ISRAM3_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM3_DEV); +} + +/* ISRAM3_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM3_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM3_MPC_Initialize, + .Uninitialize = ISRAM3_MPC_Uninitialize, + .GetBlockSize = ISRAM3_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM3_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM3_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM3_MPC_ConfigRegion, + .GetRegionConfig = ISRAM3_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM3_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM3_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM3_MPC_ClearInterrupt, + .InterruptState = ISRAM3_MPC_InterruptState, + .LockDown = ISRAM3_MPC_LockDown, +}; +#endif /* RTE_ISRAM3_MPC */ + +#if (RTE_CODE_SRAM_MPC) +/* Ranges controlled by this CODE_SRAM_MPC */ +static const struct mpc_sie_memory_range_t MPC_CODE_SRAM_RANGE_S = { + .base = MPC_CODE_SRAM_RANGE_BASE_S, + .limit = MPC_CODE_SRAM_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_CODE_SRAM_RANGE_NS = { + .base = MPC_CODE_SRAM_RANGE_BASE_NS, + .limit = MPC_CODE_SRAM_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_CODE_SRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_CODE_SRAM_RANGE_LIST[MPC_CODE_SRAM_RANGE_LIST_LEN] = { + &MPC_CODE_SRAM_RANGE_S, + &MPC_CODE_SRAM_RANGE_NS + }; + +/* CODE_SRAM_MPC Driver wrapper functions */ +static int32_t CODE_SRAM_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_CODE_SRAM_DEV, + MPC_CODE_SRAM_RANGE_LIST, + MPC_CODE_SRAM_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t CODE_SRAM_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_CODE_SRAM_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_CODE_SRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_CODE_SRAM_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t CODE_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_CODE_SRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t CODE_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_CODE_SRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_CODE_SRAM_DEV); + + return error_trans(ret); +} + +static void CODE_SRAM_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_CODE_SRAM_DEV); +} + + +static void CODE_SRAM_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_CODE_SRAM_DEV); +} + +static uint32_t CODE_SRAM_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_CODE_SRAM_DEV); +} + +static int32_t CODE_SRAM_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_CODE_SRAM_DEV); +} + +/* CODE_SRAM_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_CODE_SRAM_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = CODE_SRAM_MPC_Initialize, + .Uninitialize = CODE_SRAM_MPC_Uninitialize, + .GetBlockSize = CODE_SRAM_MPC_GetBlockSize, + .GetCtrlConfig = CODE_SRAM_MPC_GetCtrlConfig, + .SetCtrlConfig = CODE_SRAM_MPC_SetCtrlConfig, + .ConfigRegion = CODE_SRAM_MPC_ConfigRegion, + .GetRegionConfig = CODE_SRAM_MPC_GetRegionConfig, + .EnableInterrupt = CODE_SRAM_MPC_EnableInterrupt, + .DisableInterrupt = CODE_SRAM_MPC_DisableInterrupt, + .ClearInterrupt = CODE_SRAM_MPC_ClearInterrupt, + .InterruptState = CODE_SRAM_MPC_InterruptState, + .LockDown = CODE_SRAM_MPC_LockDown, +}; +#endif /* RTE_CODE_SRAM_MPC */ + +#if (RTE_SSRAM1_MPC) +/* Ranges controlled by this SSRAM1_MPC */ +static const struct mpc_sie_memory_range_t MPC_SSRAM1_RANGE_S = { + .base = MPC_SSRAM1_RANGE_BASE_S, + .limit = MPC_SSRAM1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_SSRAM1_RANGE_NS = { + .base = MPC_SSRAM1_RANGE_BASE_NS, + .limit = MPC_SSRAM1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM1_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_SSRAM1_RANGE_LIST[MPC_SSRAM1_RANGE_LIST_LEN] = { + &MPC_SSRAM1_RANGE_S, + &MPC_SSRAM1_RANGE_NS + }; + +/* SSRAM1_MPC Driver wrapper functions */ +static int32_t SSRAM1_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_SSRAM1_DEV, + MPC_SSRAM1_RANGE_LIST, + MPC_SSRAM1_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t SSRAM1_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_SSRAM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_SSRAM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_SSRAM1_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t SSRAM1_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_SSRAM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t SSRAM1_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_SSRAM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_SSRAM1_DEV); + + return error_trans(ret); +} + +static void SSRAM1_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_SSRAM1_DEV); +} + + +static void SSRAM1_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_SSRAM1_DEV); +} + +static uint32_t SSRAM1_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_SSRAM1_DEV); +} + +static int32_t SSRAM1_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_SSRAM1_DEV); +} + +/* SSRAM1_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_SSRAM1_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = SSRAM1_MPC_Initialize, + .Uninitialize = SSRAM1_MPC_Uninitialize, + .GetBlockSize = SSRAM1_MPC_GetBlockSize, + .GetCtrlConfig = SSRAM1_MPC_GetCtrlConfig, + .SetCtrlConfig = SSRAM1_MPC_SetCtrlConfig, + .ConfigRegion = SSRAM1_MPC_ConfigRegion, + .GetRegionConfig = SSRAM1_MPC_GetRegionConfig, + .EnableInterrupt = SSRAM1_MPC_EnableInterrupt, + .DisableInterrupt = SSRAM1_MPC_DisableInterrupt, + .ClearInterrupt = SSRAM1_MPC_ClearInterrupt, + .InterruptState = SSRAM1_MPC_InterruptState, + .LockDown = SSRAM1_MPC_LockDown, +}; +#endif /* RTE_SSRAM1_MPC */ + +#if (RTE_SSRAM2_MPC) +/* Ranges controlled by this SSRAM2_MPC */ +static const struct mpc_sie_memory_range_t MPC_SSRAM2_RANGE_S = { + .base = MPC_SSRAM2_RANGE_BASE_S, + .limit = MPC_SSRAM2_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_SSRAM2_RANGE_NS = { + .base = MPC_SSRAM2_RANGE_BASE_NS, + .limit = MPC_SSRAM2_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM2_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_SSRAM2_RANGE_LIST[MPC_SSRAM2_RANGE_LIST_LEN] = { + &MPC_SSRAM2_RANGE_S, + &MPC_SSRAM2_RANGE_NS + }; + +/* SSRAM2_MPC Driver wrapper functions */ +static int32_t SSRAM2_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_SSRAM2_DEV, + MPC_SSRAM2_RANGE_LIST, + MPC_SSRAM2_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t SSRAM2_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_SSRAM2_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_SSRAM2_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_SSRAM2_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t SSRAM2_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_SSRAM2_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t SSRAM2_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_SSRAM2_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_SSRAM2_DEV); + + return error_trans(ret); +} + +static void SSRAM2_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_SSRAM2_DEV); +} + + +static void SSRAM2_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_SSRAM2_DEV); +} + +static uint32_t SSRAM2_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_SSRAM2_DEV); +} + +static int32_t SSRAM2_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_SSRAM2_DEV); +} + +/* SSRAM2_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_SSRAM2_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = SSRAM2_MPC_Initialize, + .Uninitialize = SSRAM2_MPC_Uninitialize, + .GetBlockSize = SSRAM2_MPC_GetBlockSize, + .GetCtrlConfig = SSRAM2_MPC_GetCtrlConfig, + .SetCtrlConfig = SSRAM2_MPC_SetCtrlConfig, + .ConfigRegion = SSRAM2_MPC_ConfigRegion, + .GetRegionConfig = SSRAM2_MPC_GetRegionConfig, + .EnableInterrupt = SSRAM2_MPC_EnableInterrupt, + .DisableInterrupt = SSRAM2_MPC_DisableInterrupt, + .ClearInterrupt = SSRAM2_MPC_ClearInterrupt, + .InterruptState = SSRAM2_MPC_InterruptState, + .LockDown = SSRAM2_MPC_LockDown, +}; +#endif /* RTE_SSRAM2_MPC */ + +#if (RTE_SSRAM3_MPC) +/* Ranges controlled by this SSRAM3_MPC */ +static const struct mpc_sie_memory_range_t MPC_SSRAM3_RANGE_S = { + .base = MPC_SSRAM3_RANGE_BASE_S, + .limit = MPC_SSRAM3_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_SSRAM3_RANGE_NS = { + .base = MPC_SSRAM3_RANGE_BASE_NS, + .limit = MPC_SSRAM3_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM3_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_SSRAM3_RANGE_LIST[MPC_SSRAM3_RANGE_LIST_LEN] = { + &MPC_SSRAM3_RANGE_S, + &MPC_SSRAM3_RANGE_NS + }; + +/* SSRAM3_MPC Driver wrapper functions */ +static int32_t SSRAM3_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_SSRAM3_DEV, + MPC_SSRAM3_RANGE_LIST, + MPC_SSRAM3_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t SSRAM3_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_SSRAM3_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_SSRAM3_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_SSRAM3_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t SSRAM3_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_SSRAM3_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t SSRAM3_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_SSRAM3_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_SSRAM3_DEV); + + return error_trans(ret); +} + +static void SSRAM3_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_SSRAM3_DEV); +} + + +static void SSRAM3_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_SSRAM3_DEV); +} + +static uint32_t SSRAM3_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_SSRAM3_DEV); +} + +static int32_t SSRAM3_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_SSRAM3_DEV); +} + +/* SSRAM3_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_SSRAM3_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = SSRAM3_MPC_Initialize, + .Uninitialize = SSRAM3_MPC_Uninitialize, + .GetBlockSize = SSRAM3_MPC_GetBlockSize, + .GetCtrlConfig = SSRAM3_MPC_GetCtrlConfig, + .SetCtrlConfig = SSRAM3_MPC_SetCtrlConfig, + .ConfigRegion = SSRAM3_MPC_ConfigRegion, + .GetRegionConfig = SSRAM3_MPC_GetRegionConfig, + .EnableInterrupt = SSRAM3_MPC_EnableInterrupt, + .DisableInterrupt = SSRAM3_MPC_DisableInterrupt, + .ClearInterrupt = SSRAM3_MPC_ClearInterrupt, + .InterruptState = SSRAM3_MPC_InterruptState, + .LockDown = SSRAM3_MPC_LockDown, +}; +#endif /* RTE_SSRAM3_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); +} + +/* QSPI1_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_EFLASH0_MPC) +/* Ranges controlled by this EFLASH0_MPC */ +static const struct mpc_sie_memory_range_t MPC_EFLASH0_RANGE_S = { + .base = MPC_EFLASH0_RANGE_BASE_S, + .limit = MPC_EFLASH0_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_EFLASH0_RANGE_NS = { + .base = MPC_EFLASH0_RANGE_BASE_NS, + .limit = MPC_EFLASH0_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_EFLASH0_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_EFLASH0_RANGE_LIST[MPC_EFLASH0_RANGE_LIST_LEN]= + {&MPC_EFLASH0_RANGE_S, &MPC_EFLASH0_RANGE_NS}; + +/* EFLASH0_MPC Driver wrapper functions */ +static int32_t EFLASH0_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_EFLASH0_DEV, + MPC_EFLASH0_RANGE_LIST, + MPC_EFLASH0_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t EFLASH0_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_EFLASH0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_EFLASH0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_EFLASH0_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t EFLASH0_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_EFLASH0_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t EFLASH0_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_EFLASH0_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_EFLASH0_DEV); + + return error_trans(ret); +} + +static void EFLASH0_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_EFLASH0_DEV); +} + + +static void EFLASH0_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_EFLASH0_DEV); +} + +static uint32_t EFLASH0_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_EFLASH0_DEV); +} + +static int32_t EFLASH0_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_EFLASH0_DEV); +} + +/* EFLASH0_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_EFLASH0_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = EFLASH0_MPC_Initialize, + .Uninitialize = EFLASH0_MPC_Uninitialize, + .GetBlockSize = EFLASH0_MPC_GetBlockSize, + .GetCtrlConfig = EFLASH0_MPC_GetCtrlConfig, + .SetCtrlConfig = EFLASH0_MPC_SetCtrlConfig, + .ConfigRegion = EFLASH0_MPC_ConfigRegion, + .GetRegionConfig = EFLASH0_MPC_GetRegionConfig, + .EnableInterrupt = EFLASH0_MPC_EnableInterrupt, + .DisableInterrupt = EFLASH0_MPC_DisableInterrupt, + .ClearInterrupt = EFLASH0_MPC_ClearInterrupt, + .InterruptState = EFLASH0_MPC_InterruptState, + .LockDown = EFLASH0_MPC_LockDown, +}; +#endif /* RTE_EFLASH0_MPC */ + +#if (RTE_EFLASH1_MPC) +/* Ranges controlled by this EFLASH1_MPC */ +static const struct mpc_sie_memory_range_t MPC_EFLASH1_RANGE_S = { + .base = MPC_EFLASH1_RANGE_BASE_S, + .limit = MPC_EFLASH1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_EFLASH1_RANGE_NS = { + .base = MPC_EFLASH1_RANGE_BASE_NS, + .limit = MPC_EFLASH1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_EFLASH1_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_EFLASH1_RANGE_LIST[MPC_EFLASH1_RANGE_LIST_LEN]= + {&MPC_EFLASH1_RANGE_S, &MPC_EFLASH1_RANGE_NS}; + +/* EFLASH1_MPC Driver wrapper functions */ +static int32_t EFLASH1_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_EFLASH1_DEV, + MPC_EFLASH1_RANGE_LIST, + MPC_EFLASH1_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t EFLASH1_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_EFLASH1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_EFLASH1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_EFLASH1_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t EFLASH1_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_EFLASH1_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t EFLASH1_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_EFLASH1_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_EFLASH1_DEV); + + return error_trans(ret); +} + +static void EFLASH1_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_EFLASH1_DEV); +} + + +static void EFLASH1_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_EFLASH1_DEV); +} + +static uint32_t EFLASH1_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_EFLASH1_DEV); +} + +static int32_t EFLASH1_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_EFLASH1_DEV); +} + +/* EFLASH1_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_EFLASH1_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = EFLASH1_MPC_Initialize, + .Uninitialize = EFLASH1_MPC_Uninitialize, + .GetBlockSize = EFLASH1_MPC_GetBlockSize, + .GetCtrlConfig = EFLASH1_MPC_GetCtrlConfig, + .SetCtrlConfig = EFLASH1_MPC_SetCtrlConfig, + .ConfigRegion = EFLASH1_MPC_ConfigRegion, + .GetRegionConfig = EFLASH1_MPC_GetRegionConfig, + .EnableInterrupt = EFLASH1_MPC_EnableInterrupt, + .DisableInterrupt = EFLASH1_MPC_DisableInterrupt, + .ClearInterrupt = EFLASH1_MPC_ClearInterrupt, + .InterruptState = EFLASH1_MPC_InterruptState, + .LockDown = EFLASH1_MPC_LockDown, +}; +#endif /* RTE_EFLASH1_MPC */ + +#if (RTE_BRAM_MPC) +/* Ranges controlled by this BRAM_MPC */ +static const struct mpc_sie_memory_range_t MPC_BRAM_RANGE_S = { + .base = MPC_BRAM_RANGE_BASE_S, + .limit = MPC_BRAM_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_BRAM_RANGE_NS = { + .base = MPC_BRAM_RANGE_BASE_NS, + .limit = MPC_BRAM_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_BRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_BRAM_RANGE_LIST[MPC_BRAM_RANGE_LIST_LEN]= { + &MPC_BRAM_RANGE_S, + &MPC_BRAM_RANGE_NS + }; + +/* BRAM_MPC Driver wrapper functions */ +static int32_t BRAM_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_BRAM_DEV, + MPC_BRAM_RANGE_LIST, + MPC_BRAM_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t BRAM_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_BRAM_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_BRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_BRAM_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t BRAM_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_BRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t BRAM_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_BRAM_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_BRAM_DEV); + + return error_trans(ret); +} + +static void BRAM_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_BRAM_DEV); +} + + +static void BRAM_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_BRAM_DEV); +} + +static uint32_t BRAM_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_BRAM_DEV); +} + +static int32_t BRAM_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_BRAM_DEV); +} + +/* BRAM_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_BRAM_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = BRAM_MPC_Initialize, + .Uninitialize = BRAM_MPC_Uninitialize, + .GetBlockSize = BRAM_MPC_GetBlockSize, + .GetCtrlConfig = BRAM_MPC_GetCtrlConfig, + .SetCtrlConfig = BRAM_MPC_SetCtrlConfig, + .ConfigRegion = BRAM_MPC_ConfigRegion, + .GetRegionConfig = BRAM_MPC_GetRegionConfig, + .EnableInterrupt = BRAM_MPC_EnableInterrupt, + .DisableInterrupt = BRAM_MPC_DisableInterrupt, + .ClearInterrupt = BRAM_MPC_ClearInterrupt, + .InterruptState = BRAM_MPC_InterruptState, + .LockDown = BRAM_MPC_LockDown, +}; +#endif /* RTE_BRAM_MPC */ + +#if (RTE_VM0_MPC) +/* Ranges controlled by this VM0_MPC */ +static const struct mpc_sie_memory_range_t MPC_VM0_RANGE_S = { + .base = MPC_VM0_RANGE_BASE_S, + .limit = MPC_VM0_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_VM0_RANGE_NS = { + .base = MPC_VM0_RANGE_BASE_NS, + .limit = MPC_VM0_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_VM0_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_VM0_RANGE_LIST[MPC_VM0_RANGE_LIST_LEN] = { + &MPC_VM0_RANGE_S, + &MPC_VM0_RANGE_NS + }; + +/* VM0_MPC Driver wrapper functions */ +static int32_t VM0_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_VM0_DEV, + MPC_VM0_RANGE_LIST, + MPC_VM0_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t VM0_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t VM0_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_VM0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t VM0_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_VM0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t VM0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_VM0_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t VM0_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_VM0_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t VM0_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_VM0_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t VM0_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_VM0_DEV); + + return error_trans(ret); +} + +static void VM0_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_VM0_DEV); +} + + +static void VM0_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_VM0_DEV); +} + +static uint32_t VM0_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_VM0_DEV); +} + +static int32_t VM0_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_VM0_DEV); +} + +/* VM0_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_VM0_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = VM0_MPC_Initialize, + .Uninitialize = VM0_MPC_Uninitialize, + .GetBlockSize = VM0_MPC_GetBlockSize, + .GetCtrlConfig = VM0_MPC_GetCtrlConfig, + .SetCtrlConfig = VM0_MPC_SetCtrlConfig, + .ConfigRegion = VM0_MPC_ConfigRegion, + .GetRegionConfig = VM0_MPC_GetRegionConfig, + .EnableInterrupt = VM0_MPC_EnableInterrupt, + .DisableInterrupt = VM0_MPC_DisableInterrupt, + .ClearInterrupt = VM0_MPC_ClearInterrupt, + .InterruptState = VM0_MPC_InterruptState, + .LockDown = VM0_MPC_LockDown, +}; +#endif /* RTE_VM0_MPC */ + +#if (RTE_VM1_MPC) +/* Ranges controlled by this VM1_MPC */ +static const struct mpc_sie_memory_range_t MPC_VM1_RANGE_S = { + .base = MPC_VM1_RANGE_BASE_S, + .limit = MPC_VM1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_VM1_RANGE_NS = { + .base = MPC_VM1_RANGE_BASE_NS, + .limit = MPC_VM1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_VM1_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t* + MPC_VM1_RANGE_LIST[MPC_VM1_RANGE_LIST_LEN] = { + &MPC_VM1_RANGE_S, + &MPC_VM1_RANGE_NS + }; + +/* VM1_MPC Driver wrapper functions */ +static int32_t VM1_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_VM1_DEV, + MPC_VM1_RANGE_LIST, + MPC_VM1_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t VM1_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t VM1_MPC_GetBlockSize(uint32_t *blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_VM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t VM1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_VM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t VM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_VM1_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t VM1_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_VM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t *)attr); + + return error_trans(ret); +} + +static int32_t VM1_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_VM1_DEV, base, limit, + (enum mpc_sie_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t VM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_VM1_DEV); + + return error_trans(ret); +} + +static void VM1_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_VM1_DEV); +} + + +static void VM1_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_VM1_DEV); +} + +static uint32_t VM1_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_VM1_DEV); +} + +static int32_t VM1_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_VM1_DEV); +} + +/* VM1_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_VM1_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = VM1_MPC_Initialize, + .Uninitialize = VM1_MPC_Uninitialize, + .GetBlockSize = VM1_MPC_GetBlockSize, + .GetCtrlConfig = VM1_MPC_GetCtrlConfig, + .SetCtrlConfig = VM1_MPC_SetCtrlConfig, + .ConfigRegion = VM1_MPC_ConfigRegion, + .GetRegionConfig = VM1_MPC_GetRegionConfig, + .EnableInterrupt = VM1_MPC_EnableInterrupt, + .DisableInterrupt = VM1_MPC_DisableInterrupt, + .ClearInterrupt = VM1_MPC_ClearInterrupt, + .InterruptState = VM1_MPC_InterruptState, + .LockDown = VM1_MPC_LockDown, +}; +#endif /* RTE_VM1_MPC */ diff --git a/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.c b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.c new file mode 100644 index 0000000000..c16cc4aa0a --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.h b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_SSE300_PPC.h new file mode 100644 index 0000000000..c07fed07f4 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/cmsis_drivers/Driver_USART.c b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/Driver_USART.c new file mode 100644 index 0000000000..cb3a14ad3e --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/cmsis_drivers/config/RTE_Device.h b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/config/RTE_Device.h new file mode 100644 index 0000000000..92661543e2 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/config/RTE_Device.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 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. + */ + +#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 1 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] + +// <e> MPC (Memory Protection Controller) [Driver_VM0_MPC] +// <i> Configuration settings for Driver_VM0_MPC in component ::Drivers:MPC +#define RTE_VM0_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_VM0_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_VM1_MPC] +// <i> Configuration settings for Driver_VM1_MPC in component ::Drivers:MPC +#define RTE_VM1_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_VM1_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_SSRAM2_MPC] +// <i> Configuration settings for Driver_SSRAM2_MPC in component ::Drivers:MPC +#define RTE_SSRAM2_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_SSRAM2_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_SSRAM3_MPC] +// <i> Configuration settings for Driver_SSRAM3_MPC in component ::Drivers:MPC +#define RTE_SSRAM3_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_SSRAM3_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_MAIN_EXP2] +// <i> Configuration settings for Driver_PPC_SSE300_MAIN_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP2 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP2] + +// <e> PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP3] +// <i> Configuration settings for Driver_PPC_SSE300_MAIN_EXP3 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP3 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_MAIN_EXP3] + +// <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> PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP3] +// <i> Configuration settings for Driver_PPC_SSE300_PERIPH_EXP3 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP3 1 +// </e> PPC (Peripheral Protection Controller) [Driver_PPC_SSE300_PERIPH_EXP3] + +// <e> Flash device emulated by BRAM [Driver_Flash0] +// <i> Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 +// </e> Flash device emulated by BRAM [Driver_Flash0] + +#endif /* __RTE_DEVICE_H */ diff --git a/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h new file mode 100644 index 0000000000..ba3639413d --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/cmsis_drivers/config/cmsis_driver_config.h @@ -0,0 +1,51 @@ +/* + * 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 ARM_UART0_DEV_NS + +#ifdef RTE_USART1 +#ifdef SECURE_UART1 +#define UART1_CMSDK_DEV ARM_UART1_DEV_S +#else +#define UART1_CMSDK_DEV ARM_UART1_DEV_NS +#endif +#endif + +#define MPC_VM0_DEV MPC_VM0_DEV_S +#define MPC_VM1_DEV MPC_VM1_DEV_S +#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#define MPC_SSRAM3_DEV MPC_SSRAM3_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/mps2/fvp_sse300/device/config/device_cfg.h b/platform/ext/target/mps2/fvp_sse300/device/config/device_cfg.h new file mode 100644 index 0000000000..cdc20a0e80 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/config/device_cfg.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 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. + */ + +#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_VM0_S +#define MPC_VM1_S +#define MPC_SSRAM2_S +#define MPC_SSRAM3_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_S +#define UART0_CMSDK_NS +#define UART1_CMSDK_S +#define UART1_CMSDK_NS + +/* System Timer Armv8-M */ +#define SYSTIMER0_ARMV8_M_S +#define SYSTIMER0_ARMV8_M_NS +#define SYSTIMER1_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/mps2/fvp_sse300/device/include/cmsis.h b/platform/ext/target/mps2/fvp_sse300/device/include/cmsis.h new file mode 100644 index 0000000000..dbd93f43d8 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/device/include/device_definition.h b/platform/ext/target/mps2/fvp_sse300/device/include/device_definition.h new file mode 100644 index 0000000000..c83f0e6995 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/include/device_definition.h @@ -0,0 +1,241 @@ +/* + * 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 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" + +/* ======= Defines peripheral configuration structures ======= */ +/* CMSDK GPIO driver structures */ +#ifdef GPIO0_CMSDK_S +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_S; +#endif +#ifdef GPIO0_CMSDK_NS +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_NS; +#endif + +#ifdef GPIO1_CMSDK_S +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO1_CMSDK_DEV_S; +#endif +#ifdef GPIO1_CMSDK_NS +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO1_CMSDK_DEV_NS; +#endif + +#ifdef GPIO2_CMSDK_S +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO2_CMSDK_DEV_S; +#endif +#ifdef GPIO2_CMSDK_NS +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO2_CMSDK_DEV_NS; +#endif + +#ifdef GPIO3_CMSDK_S +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO3_CMSDK_DEV_S; +#endif +#ifdef GPIO3_CMSDK_NS +#include "gpio_cmsdk_drv.h" +extern struct gpio_cmsdk_dev_t GPIO3_CMSDK_DEV_NS; +#endif + +/* ARM MPS2 IO FPGAIO driver structures */ +#ifdef ARM_MPS2_IO_FPGAIO_S +#include "arm_mps2_io_drv.h" +extern struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV_S; +#endif +#ifdef ARM_MPS2_IO_FPGAIO_NS +#include "arm_mps2_io_drv.h" +extern struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV_NS; +#endif + +/* ARM MPS2 IO SCC driver structures */ +#ifdef ARM_MPS2_IO_SCC_S +#include "arm_mps2_io_drv.h" +extern struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV_S; +#endif +#ifdef ARM_MPS2_IO_SCC_NS +#include "arm_mps2_io_drv.h" +extern struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV_NS; +#endif + +/* UART CMSDK driver structures */ +#ifdef UART0_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART0_DEV_S; +#endif +#ifdef UART0_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART0_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 + +/* 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_VM0_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_VM0_DEV_S; +#endif + +#ifdef MPC_VM1_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_VM1_DEV_S; +#endif + +#ifdef MPC_SSRAM2_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_SSRAM2_DEV_S; +#endif + +#ifdef MPC_SSRAM3_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_SSRAM3_DEV_S; +#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 + +#endif /* __DEVICE_DEFINITION_H__ */ diff --git a/platform/ext/target/mps2/fvp_sse300/device/include/platform_description.h b/platform/ext/target/mps2/fvp_sse300/device/include/platform_description.h new file mode 100644 index 0000000000..8ec0197d32 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/device/include/platform_irq.h b/platform/ext/target/mps2/fvp_sse300/device/include/platform_irq.h new file mode 100644 index 0000000000..7a90b8b8e6 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/include/platform_irq.h @@ -0,0 +1,91 @@ +/* + * 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_IRQN_H__ +#define __PLATFORM_IRQN_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 */ + SLOWCLK_Timer_IRQn = 2, /* SLOWCLK Timer Interrupt */ + TIMER0_IRQn = 3, /* TIMER 0 Interrupt */ + TIMER1_IRQn = 4, /* TIMER 1 Interrupt */ + TIMER2_IRQn = 5, /* TIMER 2 Interrupt */ + /* Reserved = 8:6, Reserved */ + 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 */ + /* Reserved = 13 Reserved */ + MGMT_PPU_IRQn = 14, /* MGMT PPU Interrupt */ + SYS_PPU_IRQn = 15, /* SYS PPU Interrupt */ + CPU0_PPU_IRQn = 16, /* CPU0 PPU Interrupt */ + /* Reserved = 25:17 Reserved */ + DEBUG_PPU_IRQn = 26, /* DEBUG PPU Interrupt */ + TIMER3_IRQn = 27, /* TIMER 3 Interrupt */ + CTI_REQ0_IRQn = 28, /* CTI request 0 */ + CTI_REQ1_IRQn = 29, /* CTI request 1 */ + /* Reserved = 31:30 Reserved */ + + /* External interrupts */ + UARTRX0_IRQn = 32, /* UART 0 RX Interrupt */ + UARTTX0_IRQn = 33, /* UART 0 TX Interrupt */ + UARTRX1_IRQn = 34, /* UART 1 RX Interrupt */ + UARTTX1_IRQn = 35, /* UART 1 TX Interrupt */ + UARTRX2_IRQn = 36, /* UART 2 RX Interrupt */ + UARTTX2_IRQn = 37, /* UART 2 TX Interrupt */ + /* Reserved = 46:38 Reserved */ + UARTOVF_IRQn = 47, /* UART Overflow Interrupt */ + ETHERNET_IRQn = 48, /* SMSC 91C111 Etherne Interrupt */ + I2S0_IRQn = 49, /* I2S 0 Interrupt */ + TOUCH_SCREEN_IRQn = 50, /* Touch Screen Interrupt */ + SPI0_IRQn = 51, /* SPI 0 (SPI Header) Interrupt */ + SPI1_IRQn = 52, /* SPI 1 (CLCD) Interrupt */ + SPI2_IRQn = 53, /* SPI 2 (ADC) Interrupt */ + /* Reserved = 55:54 Reserved */ + DMA0_ERROR_IRQn = 56, /* DMA 0 Error Interrupt */ + DMA0_TC_IRQn = 57, /* DMA 0 Terminal Count Interrupt */ + DMA0_IRQn = 58, /* DMA 0 Combined Interrupt */ + DMA1_ERROR_IRQn = 59, /* DMA 1 Error Interrupt */ + DMA1_TC_IRQn = 60, /* DMA 1 Terminal Count Interrupt */ + DMA1_IRQn = 61, /* DMA 1 Combined Interrupt */ + DMA2_ERROR_IRQn = 62, /* DMA 2 Error Interrupt */ + DMA2_TC_IRQn = 63, /* DMA 2 Terminal Count Interrupt */ + DMA2_IRQn = 64, /* DMA 2 Combined Interrupt */ + DMA3_ERROR_IRQn = 65, /* DMA 3 Error Interrupt */ + DMA3_TC_IRQn = 66, /* DMA 3 Terminal Count Interrupt */ + DMA3_IRQn = 67, /* DMA 3 Combined Interrupt */ + GPIO0_IRQn = 68, /* GPIO 0 Combined Interrupt */ + GPIO1_IRQn = 69, /* GPIO 1 Combined Interrupt */ + GPIO2_IRQn = 70, /* GPIO 2 Combined Interrupt */ + GPIO3_IRQn = 71, /* GPIO 3 Combined Interrupt */ + /* Reserved = 95:72 Reserved */ +}IRQn_Type; + +#endif /* __PLATFORM_IRQN_H__ */ diff --git a/platform/ext/target/mps2/fvp_sse300/device/include/platform_regs.h b/platform/ext/target/mps2/fvp_sse300/device/include/platform_regs.h new file mode 100644 index 0000000000..a3ec626b62 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/include/platform_regs.h @@ -0,0 +1,482 @@ +/* + * 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 VGA_MAIN_PPCEXP0_POS_MASK (1UL << 0) +#define GPIO0_MAIN_PPCEXP0_POS_MASK (1UL << 1) +#define GPIO1_MAIN_PPCEXP0_POS_MASK (1UL << 2) +#define GPIO2_MAIN_PPCEXP0_POS_MASK (1UL << 3) +#define GPIO3_MAIN_PPCEXP0_POS_MASK (1UL << 4) +/* 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_SSRAM2_PERIPH_PPCEXP0_POS_MASK (1UL << 1) +#define MPC_SSRAM3_PERIPH_PPCEXP0_POS_MASK (1UL << 2) +/* End PERIPH PPCEXP0 peripherals definition */ + +/* PERIPH PPCEXP1 peripherals definition */ +#define SPI0_PERIPH_PPCEXP1_POS_MASK (1UL << 0) +#define SPI1_PERIPH_PPCEXP1_POS_MASK (1UL << 1) +#define SPI2_PERIPH_PPCEXP1_POS_MASK (1UL << 2) +#define UART0_PERIPH_PPCEXP1_POS_MASK (1UL << 5) +#define UART1_PERIPH_PPCEXP1_POS_MASK (1UL << 6) +#define UART2_PERIPH_PPCEXP1_POS_MASK (1UL << 7) +#define UART3_PERIPH_PPCEXP1_POS_MASK (1UL << 8) +#define UART4_PERIPH_PPCEXP1_POS_MASK (1UL << 9) +#define I2C_0_PERIPH_PPCEXP1_POS_MASK (1UL << 10) +#define I2C_1_PERIPH_PPCEXP1_POS_MASK (1UL << 11) +/* End PERIPH PPCEXP1 peripherals definition */ + +/* PERIPH PPCEXP2 peripherals definition */ +#define FPGA_SCC_PERIPH_PPCEXP2_POS_MASK (1UL << 0) +#define FPGA_AUDIO_PERIPH_PPCEXP2_POS_MASK (1UL << 1) +#define FPGA_IO_PERIPH_PPCEXP2_POS_MASK (1UL << 2) +/* 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_indentity; /* 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/mps2/fvp_sse300/device/include/system_core_init.h b/platform/ext/target/mps2/fvp_sse300/device/include/system_core_init.h new file mode 100644 index 0000000000..26e2cbd1cb --- /dev/null +++ b/platform/ext/target/mps2/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_CLK_H__ +#define __SYSTEM_CORE_CLK_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_CLK_H__ */ diff --git a/platform/ext/target/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_bl2.sct b/platform/ext/target/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_bl2.sct new file mode 100644 index 0000000000..f15c2969f9 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_bl2.sct @@ -0,0 +1,51 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -xc + +/* + * 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/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_ns.sct b/platform/ext/target/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_ns.sct new file mode 100644 index 0000000000..091c510026 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/armclang/fvp_sse300_mps2_ns.sct @@ -0,0 +1,51 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -xc + +/* + * 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/mps2/fvp_sse300/device/source/device_definition.c b/platform/ext/target/mps2/fvp_sse300/device/source/device_definition.c new file mode 100644 index 0000000000..5b57b7c655 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/device_definition.c @@ -0,0 +1,577 @@ +/* + * 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 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" + + +/* CMSDK GPIO driver structures */ +#ifdef GPIO0_CMSDK_S +static const struct gpio_cmsdk_dev_cfg_t GPIO0_CMSDK_DEV_CFG_S = { + .base = GPIO0_CMSDK_BASE_S}; +struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_S = {&(GPIO0_CMSDK_DEV_CFG_S)}; +#endif +#ifdef GPIO0_CMSDK_NS +static const struct gpio_cmsdk_dev_cfg_t GPIO0_CMSDK_DEV_CFG_NS = { + .base = GPIO0_CMSDK_BASE_NS}; +struct gpio_cmsdk_dev_t GPIO0_CMSDK_DEV_NS = {&(GPIO0_CMSDK_DEV_CFG_NS)}; +#endif + +#ifdef GPIO1_CMSDK_S +static const struct gpio_cmsdk_dev_cfg_t GPIO1_CMSDK_DEV_CFG_S = { + .base = GPIO1_CMSDK_BASE_S}; +struct gpio_cmsdk_dev_t GPIO1_CMSDK_DEV_S = {&(GPIO1_CMSDK_DEV_CFG_S)}; +#endif +#ifdef GPIO1_CMSDK_NS +static const struct gpio_cmsdk_dev_cfg_t GPIO1_CMSDK_DEV_CFG_NS = { + .base = GPIO1_CMSDK_BASE_NS}; +struct gpio_cmsdk_dev_t GPIO1_CMSDK_DEV_NS = {&(GPIO1_CMSDK_DEV_CFG_NS)}; +#endif + +#ifdef GPIO2_CMSDK_S +static const struct gpio_cmsdk_dev_cfg_t GPIO2_CMSDK_DEV_CFG_S = { + .base = GPIO2_CMSDK_BASE_S}; +struct gpio_cmsdk_dev_t GPIO2_CMSDK_DEV_S = {&(GPIO2_CMSDK_DEV_CFG_S)}; +#endif +#ifdef GPIO2_CMSDK_NS +static const struct gpio_cmsdk_dev_cfg_t GPIO2_CMSDK_DEV_CFG_NS = { + .base = GPIO2_CMSDK_BASE_NS}; +struct gpio_cmsdk_dev_t GPIO2_CMSDK_DEV_NS = {&(GPIO2_CMSDK_DEV_CFG_NS)}; +#endif + +#ifdef GPIO3_CMSDK_S +static const struct gpio_cmsdk_dev_cfg_t GPIO3_CMSDK_DEV_CFG_S = { + .base = GPIO3_CMSDK_BASE_S}; +struct gpio_cmsdk_dev_t GPIO3_CMSDK_DEV_S = {&(GPIO3_CMSDK_DEV_CFG_S)}; +#endif +#ifdef GPIO3_CMSDK_NS +static const struct gpio_cmsdk_dev_cfg_t GPIO3_CMSDK_DEV_CFG_NS = { + .base = GPIO3_CMSDK_BASE_NS}; +struct gpio_cmsdk_dev_t GPIO3_CMSDK_DEV_NS = {&(GPIO3_CMSDK_DEV_CFG_NS)}; +#endif + +/* ARM MPS2 IO FPGAIO driver structures */ +#ifdef ARM_MPS2_IO_FPGAIO_S +static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_FPGAIO_DEV_CFG_S = { + .base = MPS2_IO_FPGAIO_BASE_S, + .type = ARM_MPS2_IO_TYPE_FPGAIO}; +struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV_S = + {&(ARM_MPS2_IO_FPGAIO_DEV_CFG_S)}; +#endif +#ifdef ARM_MPS2_IO_FPGAIO_NS +static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_FPGAIO_DEV_CFG_NS = { + .base = MPS2_IO_FPGAIO_BASE_NS, + .type = ARM_MPS2_IO_TYPE_FPGAIO}; +struct arm_mps2_io_dev_t ARM_MPS2_IO_FPGAIO_DEV_NS = + {&(ARM_MPS2_IO_FPGAIO_DEV_CFG_NS)}; +#endif + +/* ARM MPS2 IO SCC driver structures */ +#ifdef ARM_MPS2_IO_SCC_S +static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_SCC_DEV_CFG_S = { + /* + * MPS2 IO SCC and FPGAIO register addresses match with an offset of 4. + */ + .base = MPS2_IO_SCC_BASE_S + 4, + .type = ARM_MPS2_IO_TYPE_SCC}; +struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV_S = {&(ARM_MPS2_IO_SCC_DEV_CFG_S)}; +#endif +#ifdef ARM_MPS2_IO_SCC_NS +static const struct arm_mps2_io_dev_cfg_t ARM_MPS2_IO_SCC_DEV_CFG_NS = { + .base = MPS2_IO_SCC_BASE_NS + 4, + .type = ARM_MPS2_IO_TYPE_SCC}; +struct arm_mps2_io_dev_t ARM_MPS2_IO_SCC_DEV_NS = + {&(ARM_MPS2_IO_SCC_DEV_CFG_NS)}; +#endif + +/* UART CMSDK driver structures */ +#ifdef UART0_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_S = { + .base = UART0_CMSDK_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_S = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART0_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_CMSDK_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_NS = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART0_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_CMSDK_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_S = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +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_CMSDK_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_NS = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +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_CMSDK_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_S = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +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_CMSDK_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART2_CMSDK_DEV_DATA_NS = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART2_DEV_NS = { + &(UART2_CMSDK_DEV_CFG_NS), + &(UART2_CMSDK_DEV_DATA_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 SIE 300 driver structures */ +#ifdef MPC_VM0_S +static const struct mpc_sie_dev_cfg_t MPC_VM0_DEV_CFG_S = { + .base = MPC_VM0_BASE_S}; +static struct mpc_sie_dev_data_t MPC_VM0_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_VM0_DEV_S = { + &(MPC_VM0_DEV_CFG_S), + &(MPC_VM0_DEV_DATA_S)}; +#endif + +#ifdef MPC_VM1_S +static const struct mpc_sie_dev_cfg_t MPC_VM1_DEV_CFG_S = { + .base = MPC_VM1_BASE_S}; +static struct mpc_sie_dev_data_t MPC_VM1_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_VM1_DEV_S = { + &(MPC_VM1_DEV_CFG_S), + &(MPC_VM1_DEV_DATA_S)}; +#endif + +#ifdef MPC_SSRAM2_S +static const struct mpc_sie_dev_cfg_t MPC_SSRAM2_DEV_CFG_S = { + .base = MPC_SSRAM2_BASE_S}; +static struct mpc_sie_dev_data_t MPC_SSRAM2_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_SSRAM2_DEV_S = { + &(MPC_SSRAM2_DEV_CFG_S), + &(MPC_SSRAM2_DEV_DATA_S)}; +#endif + +#ifdef MPC_SSRAM3_S +static const struct mpc_sie_dev_cfg_t MPC_SSRAM3_DEV_CFG_S = { + .base = MPC_SSRAM3_BASE_S}; +static struct mpc_sie_dev_data_t MPC_SSRAM3_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .is_initialized = false }; +struct mpc_sie_dev_t MPC_SSRAM3_DEV_S = { + &(MPC_SSRAM3_DEV_CFG_S), + &(MPC_SSRAM3_DEV_DATA_S)}; +#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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 = 0, + .sacfg_sp_ppc = 0, + .nsacfg_nsp_ppc = 0, + .int_bit_mask = 0, + .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 diff --git a/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_bl2.c b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_bl2.c new file mode 100644 index 0000000000..e36715d066 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_bl2.c @@ -0,0 +1,230 @@ +/* + * 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(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(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S0_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(SPI0_Handler) +DEFAULT_IRQ_HANDLER(SPI1_Handler) +DEFAULT_IRQ_HANDLER(SPI2_Handler) +DEFAULT_IRQ_HANDLER(DMA0_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA0_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA0_Handler) +DEFAULT_IRQ_HANDLER(DMA1_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA1_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA1_Handler) +DEFAULT_IRQ_HANDLER(DMA2_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA2_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA2_Handler) +DEFAULT_IRQ_HANDLER(DMA3_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA3_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_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 */ + UARTRX0_Handler, /* 32: UART 0 RX Handler */ + UARTTX0_Handler, /* 33: UART 0 TX Handler */ + UARTRX1_Handler, /* 34: UART 1 RX Handler */ + UARTTX1_Handler, /* 35: UART 1 TX Handler */ + UARTRX2_Handler, /* 36: UART 2 RX Handler */ + UARTTX2_Handler, /* 37: UART 2 TX Handler */ + 0, /* 38: Reserved */ + 0, /* 39: Reserved */ + 0, /* 40: Reserved */ + 0, /* 41: Reserved */ + 0, /* 42: Reserved */ + 0, /* 43: Reserved */ + 0, /* 44: Reserved */ + 0, /* 45: Reserved */ + 0, /* 46: Reserved */ + UARTOVF_Handler, /* 47: UART 0,1,2 Overflow Handler */ + ETHERNET_Handler, /* 48: SMSC 91C111 Etherne Interrupt */ + I2S0_Handler, /* 49: I2S0 Handler */ + TOUCH_SCREEN_Handler, /* 50: Touch Screen Interrupt */ + SPI0_Handler, /* 51: SPI 0 (SPI Header) Interrupt */ + SPI1_Handler, /* 52: SPI 1 (CLCD) Interrupt */ + SPI2_Handler, /* 53: SPI 2 (ADC) Interrupt */ + 0, /* 54: Reserved */ + 0, /* 55: Reserved */ + DMA0_ERROR_Handler, /* 56: DMA 0 Error Handler */ + DMA0_TC_Handler, /* 57: DMA 0 Terminal Count Handler */ + DMA0_Handler, /* 58: DMA 0 Combined Handler */ + DMA1_ERROR_Handler, /* 59: DMA 1 Error Handler */ + DMA1_TC_Handler, /* 60: DMA 1 Terminal Count Handler */ + DMA1_Handler, /* 61: DMA 1 Combined Handler */ + DMA2_ERROR_Handler, /* 62: DMA 2 Error Handler */ + DMA2_TC_Handler, /* 63: DMA 2 Terminal Count Handler */ + DMA2_Handler, /* 64: DMA 2 Combined Handler */ + DMA3_ERROR_Handler, /* 65: DMA 3 Error Handler */ + DMA3_TC_Handler, /* 66: DMA 3 Terminal Count Handler */ + DMA3_Handler, /* 67: DMA 3 Combined Handler */ + GPIO0_Handler, /* 68: GPIO 0 Combined Handler */ + GPIO1_Handler, /* 69: GPIO 1 Combined Handler */ + GPIO2_Handler, /* 70: GPIO 2 Combined Handler */ + GPIO3_Handler, /* 71: GPIO 3 Combined Handler */ +}; + +#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/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_ns.c b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_ns.c new file mode 100644 index 0000000000..22c05f16c5 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_ns.c @@ -0,0 +1,244 @@ +/* + * 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 + *----------------------------------------------------------------------------*/ + +#define __MSP_INITIAL_SP Image$$ARM_LIB_STACK_MSP$$ZI$$Limit +#define __MSP_STACK_LIMIT 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(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(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S0_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(SPI0_Handler) +DEFAULT_IRQ_HANDLER(SPI1_Handler) +DEFAULT_IRQ_HANDLER(SPI2_Handler) +DEFAULT_IRQ_HANDLER(DMA0_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA0_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA0_Handler) +DEFAULT_IRQ_HANDLER(DMA1_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA1_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA1_Handler) +DEFAULT_IRQ_HANDLER(DMA2_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA2_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA2_Handler) +DEFAULT_IRQ_HANDLER(DMA3_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA3_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_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 */ + UARTRX0_Handler, /* 32: UART 0 RX Handler */ + UARTTX0_Handler, /* 33: UART 0 TX Handler */ + UARTRX1_Handler, /* 34: UART 1 RX Handler */ + UARTTX1_Handler, /* 35: UART 1 TX Handler */ + UARTRX2_Handler, /* 36: UART 2 RX Handler */ + UARTTX2_Handler, /* 37: UART 2 TX Handler */ + 0, /* 38: Reserved */ + 0, /* 39: Reserved */ + 0, /* 40: Reserved */ + 0, /* 41: Reserved */ + 0, /* 42: Reserved */ + 0, /* 43: Reserved */ + 0, /* 44: Reserved */ + 0, /* 45: Reserved */ + 0, /* 46: Reserved */ + UARTOVF_Handler, /* 47: UART 0,1,2 Overflow Handler */ + ETHERNET_Handler, /* 48: SMSC 91C111 Etherne Interrupt */ + I2S0_Handler, /* 49: I2S0 Handler */ + TOUCH_SCREEN_Handler, /* 50: Touch Screen Interrupt */ + SPI0_Handler, /* 51: SPI 0 (SPI Header) Interrupt */ + SPI1_Handler, /* 52: SPI 1 (CLCD) Interrupt */ + SPI2_Handler, /* 53: SPI 2 (ADC) Interrupt */ + 0, /* 54: Reserved */ + 0, /* 55: Reserved */ + DMA0_ERROR_Handler, /* 56: DMA 0 Error Handler */ + DMA0_TC_Handler, /* 57: DMA 0 Terminal Count Handler */ + DMA0_Handler, /* 58: DMA 0 Combined Handler */ + DMA1_ERROR_Handler, /* 59: DMA 1 Error Handler */ + DMA1_TC_Handler, /* 60: DMA 1 Terminal Count Handler */ + DMA1_Handler, /* 61: DMA 1 Combined Handler */ + DMA2_ERROR_Handler, /* 62: DMA 2 Error Handler */ + DMA2_TC_Handler, /* 63: DMA 2 Terminal Count Handler */ + DMA2_Handler, /* 64: DMA 2 Combined Handler */ + DMA3_ERROR_Handler, /* 65: DMA 3 Error Handler */ + DMA3_TC_Handler, /* 66: DMA 3 Terminal Count Handler */ + DMA3_Handler, /* 67: DMA 3 Combined Handler */ + GPIO0_Handler, /* 68: GPIO 0 Combined Handler */ + GPIO1_Handler, /* 69: GPIO 1 Combined Handler */ + GPIO2_Handler, /* 70: GPIO 2 Combined Handler */ + GPIO3_Handler, /* 71: GPIO 3 Combined Handler */ +}; + +#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/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_s.c b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_s.c new file mode 100644 index 0000000000..8f3a1addcb --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/startup_fvp_sse300_mps2_s.c @@ -0,0 +1,243 @@ +/* + * 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 + *----------------------------------------------------------------------------*/ + +#define __MSP_INITIAL_SP Image$$ARM_LIB_STACK_MSP$$ZI$$Limit +#define __MSP_STACK_LIMIT 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(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(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S0_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(SPI0_Handler) +DEFAULT_IRQ_HANDLER(SPI1_Handler) +DEFAULT_IRQ_HANDLER(SPI2_Handler) +DEFAULT_IRQ_HANDLER(DMA0_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA0_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA0_Handler) +DEFAULT_IRQ_HANDLER(DMA1_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA1_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA1_Handler) +DEFAULT_IRQ_HANDLER(DMA2_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA2_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA2_Handler) +DEFAULT_IRQ_HANDLER(DMA3_ERROR_Handler) +DEFAULT_IRQ_HANDLER(DMA3_TC_Handler) +DEFAULT_IRQ_HANDLER(DMA3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_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 */ + UARTRX0_Handler, /* 32: UART 0 RX Handler */ + UARTTX0_Handler, /* 33: UART 0 TX Handler */ + UARTRX1_Handler, /* 34: UART 1 RX Handler */ + UARTTX1_Handler, /* 35: UART 1 TX Handler */ + UARTRX2_Handler, /* 36: UART 2 RX Handler */ + UARTTX2_Handler, /* 37: UART 2 TX Handler */ + 0, /* 38: Reserved */ + 0, /* 39: Reserved */ + 0, /* 40: Reserved */ + 0, /* 41: Reserved */ + 0, /* 42: Reserved */ + 0, /* 43: Reserved */ + 0, /* 44: Reserved */ + 0, /* 45: Reserved */ + 0, /* 46: Reserved */ + UARTOVF_Handler, /* 47: UART 0,1,2 Overflow Handler */ + ETHERNET_Handler, /* 48: SMSC 91C111 Etherne Interrupt */ + I2S0_Handler, /* 49: I2S0 Handler */ + TOUCH_SCREEN_Handler, /* 50: Touch Screen Interrupt */ + SPI0_Handler, /* 51: SPI 0 (SPI Header) Interrupt */ + SPI1_Handler, /* 52: SPI 1 (CLCD) Interrupt */ + SPI2_Handler, /* 53: SPI 2 (ADC) Interrupt */ + 0, /* 54: Reserved */ + 0, /* 55: Reserved */ + DMA0_ERROR_Handler, /* 56: DMA 0 Error Handler */ + DMA0_TC_Handler, /* 57: DMA 0 Terminal Count Handler */ + DMA0_Handler, /* 58: DMA 0 Combined Handler */ + DMA1_ERROR_Handler, /* 59: DMA 1 Error Handler */ + DMA1_TC_Handler, /* 60: DMA 1 Terminal Count Handler */ + DMA1_Handler, /* 61: DMA 1 Combined Handler */ + DMA2_ERROR_Handler, /* 62: DMA 2 Error Handler */ + DMA2_TC_Handler, /* 63: DMA 2 Terminal Count Handler */ + DMA2_Handler, /* 64: DMA 2 Combined Handler */ + DMA3_ERROR_Handler, /* 65: DMA 3 Error Handler */ + DMA3_TC_Handler, /* 66: DMA 3 Terminal Count Handler */ + DMA3_Handler, /* 67: DMA 3 Combined Handler */ + GPIO0_Handler, /* 68: GPIO 0 Combined Handler */ + GPIO1_Handler, /* 69: GPIO 1 Combined Handler */ + GPIO2_Handler, /* 70: GPIO 2 Combined Handler */ + GPIO3_Handler, /* 71: GPIO 3 Combined Handler */ +}; + +#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/mps2/fvp_sse300/device/source/system_core_init.c b/platform/ext/target/mps2/fvp_sse300/device/source/system_core_init.c new file mode 100644 index 0000000000..de67079bbb --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/device/source/system_core_init.c @@ -0,0 +1,74 @@ +/* + * 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 (25000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (XTAL) + +/*---------------------------------------------------------------------------- + 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 + +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__MVE_USED) && (__MVE_USED == 1U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); /* enable CP11 Full Access */ +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif +} diff --git a/platform/ext/target/mps2/fvp_sse300/native_drivers/mpc_sie_drv.c b/platform/ext/target/mps2/fvp_sse300/native_drivers/mpc_sie_drv.c new file mode 100644 index 0000000000..23dbf50acf --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h b/platform/ext/target/mps2/fvp_sse300/native_drivers/mpc_sie_drv.h new file mode 100644 index 0000000000..927d0a80d5 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/mpu_armv8m_drv.c b/platform/ext/target/mps2/fvp_sse300/native_drivers/mpu_armv8m_drv.c new file mode 100644 index 0000000000..3121224e23 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/mpu_armv8m_drv.h b/platform/ext/target/mps2/fvp_sse300/native_drivers/mpu_armv8m_drv.h new file mode 100644 index 0000000000..d427604f38 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/ppc_sse300_drv.c b/platform/ext/target/mps2/fvp_sse300/native_drivers/ppc_sse300_drv.c new file mode 100644 index 0000000000..38d068d745 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/ppc_sse300_drv.h b/platform/ext/target/mps2/fvp_sse300/native_drivers/ppc_sse300_drv.h new file mode 100644 index 0000000000..a3f7e1d700 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/systimer_armv8-m_drv.c b/platform/ext/target/mps2/fvp_sse300/native_drivers/systimer_armv8-m_drv.c new file mode 100644 index 0000000000..c7b4b153ac --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/mps2/fvp_sse300/native_drivers/systimer_armv8-m_drv.h new file mode 100644 index 0000000000..d14d2f79e2 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/uart_cmsdk_drv.c b/platform/ext/target/mps2/fvp_sse300/native_drivers/uart_cmsdk_drv.c new file mode 100644 index 0000000000..c3d1230052 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/native_drivers/uart_cmsdk_drv.h b/platform/ext/target/mps2/fvp_sse300/native_drivers/uart_cmsdk_drv.h new file mode 100644 index 0000000000..2d3278ef65 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/partition/flash_layout.h b/platform/ext/target/mps2/fvp_sse300/partition/flash_layout.h new file mode 100644 index 0000000000..63d658cd70 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/partition/flash_layout.h @@ -0,0 +1,224 @@ +/* + * 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_mps2 with BL2 (multiple image boot): + * + * 0x0000_0000 Secure image primary slot (384 KB) + * 0x0006_0000 Non-secure image primary slot (256 KB) + * 0x000A_0000 Secure image secondary slot (384 KB) + * 0x0010_0000 Non-secure image secondary slot (256 KB) + * 0x0014_0000 Scratch area (384 KB) + * 0x001A_0000 Secure Storage Area (20 KB) + * 0x001A_5000 Internal Trusted Storage Area (16 KB) + * 0x001A_9000 NV counters area (4 KB) + * 0x001A_A000 Unused + * + * Flash layout on fvp_sse300_mps2 with BL2 (single image boot): + * + * 0x0000_0000 Primary image area (640 KB): + * 0x0000_0000 Secure image primary + * 0x0006_0000 Non-secure image primary + * 0x000A_0000 Secondary image area (640 KB): + * 0x000A_0000 Secure image secondary + * 0x0010_0000 Non-secure image secondary + * 0x0014_0000 Scratch area (640 KB) + * 0x001E_0000 Secure Storage Area (20 KB) + * 0x001E_5000 Internal Trusted Storage Area (16 KB) + * 0x001E_9000 NV counters area (4 KB) + * 0x001E_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 (0x40000) /* NS partition: 256 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 (SSRAM2_SIZE) + +/* Flash layout info for BL2 bootloader */ +/* Same as FLASH0_BASE_S */ +#define FLASH_BASE_ADDRESS (SSRAM2_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_S_PARTITION_SIZE + \ + FLASH_NS_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 > SSRAM2_SIZE) +#error "Secondary image overlaps to SSRAM3 device, which is not supported!" +#endif + +/* Secure Storage (SST) Service definitions */ +#define FLASH_SST_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + \ + FLASH_AREA_SCRATCH_SIZE) +#define FLASH_SST_AREA_SIZE (0x5000) /* 20 KB */ + +/* Internal Trusted Storage (ITS) Service definitions */ +#define FLASH_ITS_AREA_OFFSET (FLASH_SST_AREA_OFFSET + \ + FLASH_SST_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 + +/* Secure Storage (SST) Service definitions + * Note: Further documentation of these definitions can be found in the + * TF-M SST Integration Guide. + */ +#define SST_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 SST_FLASH_AREA_ADDR FLASH_SST_AREA_OFFSET +/* Dedicated flash area for SST */ +#define SST_FLASH_AREA_SIZE FLASH_SST_AREA_SIZE +#define SST_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE +/* Number of SST_SECTOR_SIZE per block */ +#define SST_SECTORS_PER_BLOCK (0x1) +/* Specifies the smallest flash programmable unit in bytes */ +#define SST_FLASH_PROGRAM_UNIT (0x1) +/* The maximum asset size to be stored in the SST area */ +#define SST_MAX_ASSET_SIZE (2048) +/* The maximum number of assets to be stored in the SST area */ +#define SST_NUM_ASSETS (10) + +/* 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_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) +/* The maximum asset size to be stored in the ITS area */ +#define ITS_MAX_ASSET_SIZE (512) +/* The maximum number of assets to be stored in the ITS area */ +#define ITS_NUM_ASSETS (10) + +/* 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/mps2/fvp_sse300/partition/platform_base_address.h b/platform/ext/target/mps2/fvp_sse300/partition/platform_base_address.h new file mode 100644 index 0000000000..c8bc75f523 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/partition/platform_base_address.h @@ -0,0 +1,159 @@ +/* + * 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 Diadem 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 DTCM_BASE_NS 0x20000000 /* Data TCM Non-Secure base address */ +#define VM0_BASE_NS 0x21000000 /* Volatile Memory Bank 0 Non-Secure base address */ +#define VM1_BASE_NS 0x21040000 /* Volatile Memory Bank 1 Non-Secure base address */ +#define SSRAM2_BASE_NS 0x28000000 /* SSRAM2 Non-Secure base address */ +#define SSRAM3_BASE_NS 0x28200000 /* SSRAM3 Non-Secure base address */ +#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 */ +#define GPIO0_CMSDK_BASE_NS 0x40100000 /* GPIO0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x40101000 /* GPIO1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x40102000 /* GPIO2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x40103000 /* GPIO3 Non-Secure base address */ +#define DMA0_PL080_BASE_NS 0x40110000 /* DMA0 PL080 Non-Secure base address */ +#define DMA1_PL080_BASE_NS 0x40111000 /* DMA1 PL080 Non-Secure base address */ +#define DMA2_PL080_BASE_NS 0x40112000 /* DMA2 PL080 Non-Secure base address */ +#define DMA3_PL080_BASE_NS 0x40113000 /* DMA3 PL080 Non-Secure base address */ +#define UART0_CMSDK_BASE_NS 0x40200000 /* UART0 Non-Secure base address */ +#define UART1_CMSDK_BASE_NS 0x40201000 /* UART1 Non-Secure base address */ +#define UART2_CMSDK_BASE_NS 0x40202000 /* UART2 Non-Secure base address */ +#define UART3_CMSDK_BASE_NS 0x40203000 /* Dummy Stub */ +#define UART4_CMSDK_BASE_NS 0x40204000 /* Dummy Stub */ +#define SPI_0_BASE_NS 0x40205000 /* Dummy Stub */ +#define SPI_1_BASE_NS 0x40206000 /* PL022 SPI for LCD - Partial Modelled */ +#define I2C_0_BASE_NS 0x40207000 /* SBCon I2C (Touch) - Partial Modelled */ +#define I2C_1_BASE_NS 0x40208000 /* SBCon I2C (Audio Conf) - Dummy Stub */ +#define SPI_2_BASE_NS 0x40209000 /* Dummy Stub */ +#define MPS2_IO_SCC_BASE_NS 0x40300000 /* MPS2 SCC IO Non-Secure base address */ +#define I2S0_BASE_NS 0x40301000 /* Dummy Stub */ +#define MPS2_IO_FPGAIO_BASE_NS 0x40302000 /* MPS2 FPGA GPIO (System Ctrl + I/O) Non-Secure base address */ +#define VGA_BASE_NS 0x41000000 /* VGA Console and Image Non-Secure base address */ +#define SMSC_BASE_NS 0x42000000 /* SMSC 91C111 Ethernet controller */ +#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 0 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 1 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 */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define DTCM_BASE_S 0x30000000 /* Data TCM Secure base address */ +#define VM0_BASE_S 0x31000000 /* Volatile Memory Bank 0 Secure base address */ +#define VM1_BASE_S 0x31040000 /* Volatile Memory Bank 1 Secure base address */ +#define SSRAM2_BASE_S 0x38000000 /* SSRAM2 Secure base address */ +#define SSRAM3_BASE_S 0x38200000 /* SSRAM3 Secure base address */ +#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_VM0_BASE_S 0x50083000 /* VM0 Memory Protection Controller Secure base address */ +#define MPC_VM1_BASE_S 0x50084000 /* VM1 Memory Protection Controller Secure base address */ +#define GPIO0_CMSDK_BASE_S 0x50100000 /* GPIO0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x50101000 /* GPIO1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x50102000 /* GPIO2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x50103000 /* GPIO3 Secure base address */ +#define DMA0_PL080_BASE_S 0x50110000 /* DMA0 PL080 Secure base address */ +#define DMA1_PL080_BASE_S 0x50111000 /* DMA1 PL080 Secure base address */ +#define DMA2_PL080_BASE_S 0x50112000 /* DMA2 PL080 Secure base address */ +#define DMA3_PL080_BASE_S 0x50113000 /* DMA3 PL080 Secure base address */ +#define UART0_CMSDK_BASE_S 0x50200000 /* UART0 Secure base address */ +#define UART1_CMSDK_BASE_S 0x50201000 /* UART1 Secure base address */ +#define UART2_CMSDK_BASE_S 0x50202000 /* UART2 Secure base address */ +#define UART3_CMSDK_BASE_S 0x50203000 /* Dummy Stub */ +#define UART4_CMSDK_BASE_S 0x50204000 /* Dummy Stub */ +#define SPI_0_BASE_S 0x50205000 /* Dummy Stub */ +#define SPI_1_BASE_S 0x50206000 /* PL022 SPI for LCD - Partial Modelled */ +#define I2C_0_BASE_S 0x50207000 /* SBCon I2C (Touch) - Partial Modelled */ +#define I2C_1_BASE_S 0x50208000 /* SBCon I2C (Audio Conf) - Dummy Stub */ +#define SPI_2_BASE_S 0x50209000 /* Dummy Stub */ +#define MPS2_IO_SCC_BASE_S 0x50300000 /* MPS2 SCC IO Secure base address */ +#define I2S_FPGA_BASE_S 0x50301000 /* Dummy Stub */ +#define MPS2_IO_FPGAIO_BASE_S 0x50302000 /* MPS2 FPGA GPIO (System Ctrl + I/O) Non-Secure base address */ +#define VGA_BASE_S 0x51000000 /* VGA Console and Image Non-Secure base address */ +#define SMSC_BASE_S 0x52000000 /* SMSC 91C111 Ethernet controller */ +#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 MPC_SSRAM2_BASE_S 0x58008000 /* SSRAM2 Memory Protection Controller Secure base address */ +#define MPC_SSRAM3_BASE_S 0x58009000 /* SSRAM3 Memory Protection Controller 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 */ + +/* 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 (0x00040000) /* 256 KiB */ +#define DTCM_SIZE (0x00040000) /* 256 KiB */ +#define VM0_SIZE (0x00040000) /* 256 KiB */ +#define VM1_SIZE (0x00040000) /* 256 KiB */ +#define SSRAM2_SIZE (0x00200000) /* 2 MB */ +#define SSRAM3_SIZE (0x00200000) /* 2 MB */ + +/* VM0 -- 256 kB*/ +#define MPC_VM0_RANGE_BASE_NS (VM0_BASE_NS) +#define MPC_VM0_RANGE_LIMIT_NS (VM0_BASE_NS + VM0_SIZE-1) +#define MPC_VM0_RANGE_BASE_S (VM0_BASE_S) +#define MPC_VM0_RANGE_LIMIT_S (VM0_BASE_S + VM0_SIZE-1) + +/* VM1 -- 256 kB*/ +#define MPC_VM1_RANGE_BASE_NS (VM1_BASE_NS) +#define MPC_VM1_RANGE_LIMIT_NS (VM1_BASE_NS + VM1_SIZE-1) +#define MPC_VM1_RANGE_BASE_S (VM1_BASE_S) +#define MPC_VM1_RANGE_LIMIT_S (VM1_BASE_S + VM1_SIZE-1) + +/* SSRAM2 -- 2 MB*/ +#define MPC_SSRAM2_RANGE_BASE_NS (SSRAM2_BASE_NS) +#define MPC_SSRAM2_RANGE_LIMIT_NS (SSRAM2_BASE_NS + SSRAM2_SIZE-1) +#define MPC_SSRAM2_RANGE_BASE_S (SSRAM2_BASE_S) +#define MPC_SSRAM2_RANGE_LIMIT_S (SSRAM2_BASE_S + SSRAM2_SIZE-1) + +/* SSRAM3 -- 2 MB*/ +#define MPC_SSRAM3_RANGE_BASE_NS (SSRAM3_BASE_NS) +#define MPC_SSRAM3_RANGE_LIMIT_NS (SSRAM3_BASE_NS + SSRAM3_SIZE-1) +#define MPC_SSRAM3_RANGE_BASE_S (SSRAM3_BASE_S) +#define MPC_SSRAM3_RANGE_LIMIT_S (SSRAM3_BASE_S + SSRAM3_SIZE-1) + +#endif /* __PLATFORM_BASE_ADDRESS_H_ */ diff --git a/platform/ext/target/mps2/fvp_sse300/partition/region_defs.h b/platform/ext/target/mps2/fvp_sse300/partition/region_defs.h new file mode 100644 index 0000000000..9f9d506161 --- /dev/null +++ b/platform/ext/target/mps2/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 32 KB on SSE300_MPS2 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 ((SSRAM2_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 (DTCM_BASE_S) +#define S_DATA_SIZE (DTCM_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 (SSRAM2_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 VM0 */ +#define NS_DATA_START (VM0_BASE_NS) +#define NS_DATA_SIZE (VM0_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 \ + ((SSRAM2_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 \ + ((SSRAM2_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/mps2/fvp_sse300/plat_test.c b/platform/ext/target/mps2/fvp_sse300/plat_test.c new file mode 100644 index 0000000000..bdcbd48e49 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/plat_test.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "platform_description.h" +#include "device_definition.h" +#include "systimer_armv8-m_drv.h" +#include "tfm_plat_test.h" + +#include "smm_mps2.h" + +#define TIMER_RELOAD_VALUE (16*1024*1024) +#define USERLED_MASK (0x3) +#define MPS2_USERPB0_BASE (0x50302008) +#define MPS2_USERPB0_MASK (0x1) + +void tfm_plat_test_wait_user_button_pressed(void) +{ + volatile uint32_t *p_btn = (volatile uint32_t *) MPS2_USERPB0_BASE; + + /* Wait until user button 0 is pressed */ + while (!(*p_btn & MPS2_USERPB0_MASK)) { + ; + } +} + +void tfm_plat_test_wait_user_button_released(void) +{ + volatile uint32_t *p_btn = (volatile uint32_t *) MPS2_USERPB0_BASE; + + /* Wait until user button 0 is released */ + while ((*p_btn & MPS2_USERPB0_MASK)) { + ; + } +} + +uint32_t tfm_plat_test_get_led_status(void) +{ + struct arm_mps2_fpgaio_t *fpgaio = SEC_MPS2_FPGAIO; + return fpgaio->LED; +} + +void tfm_plat_test_set_led_status(uint32_t status) +{ + struct arm_mps2_fpgaio_t *fpgaio = SEC_MPS2_FPGAIO; + fpgaio->LED = status; +} + +uint32_t tfm_plat_test_get_userled_mask(void) +{ + return USERLED_MASK; +} + +void tfm_plat_test_secure_timer_start(void) +{ + 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/mps2/fvp_sse300/services/src/tfm_platform_system.c b/platform/ext/target/mps2/fvp_sse300/services/src/tfm_platform_system.c new file mode 100644 index 0000000000..44fafbccd1 --- /dev/null +++ b/platform/ext/target/mps2/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/mps2/fvp_sse300/spm_hal.c b/platform/ext/target/mps2/fvp_sse300/spm_hal.c new file mode 100644 index 0000000000..206e621920 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/spm_hal.c @@ -0,0 +1,323 @@ +/* + * 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/spm_api.h" +#include "tfm/spm_db.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 "secure_utilities.h" +#include "region.h" + +#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) + + + +/* 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 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 +#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; +} + +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT +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 + } + }; + +static enum spm_err_t tfm_spm_mpu_init(void) +{ + int32_t i; + + 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 SPM_ERR_INVALID_CONFIG; + } + } + + mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE, + HARDFAULT_NMI_ENABLE); + + return SPM_ERR_OK; +} + +enum tfm_plat_err_t tfm_spm_hal_setup_isolation_hw(void) +{ + if (tfm_spm_mpu_init() != SPM_ERR_OK) { + ERROR_MSG("Failed to set up initial MPU configuration! Halting."); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + return TFM_PLAT_ERR_SUCCESS; +} +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + +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/mps2/fvp_sse300/target_cfg.c b/platform/ext/target/mps2/fvp_sse300/target_cfg.c new file mode 100644 index 0000000000..a275839b52 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/target_cfg.c @@ -0,0 +1,626 @@ +/* + * 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 "secure_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_VM0_MPC; +extern ARM_DRIVER_MPC Driver_VM1_MPC; +extern ARM_DRIVER_MPC Driver_SSRAM2_MPC; +extern ARM_DRIVER_MPC Driver_SSRAM3_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_MAIN_EXP2; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP3; +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; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP3; + +/* 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_CMSDK_BASE_NS, + UART0_CMSDK_BASE_NS + 0xFFF, + PPC_SP_DO_NOT_CONFIGURE, + -1 +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_uart1 = { + UART1_CMSDK_BASE_S, + UART1_CMSDK_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, + UART1_PERIPH_PPCEXP1_POS_MASK +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io = { + MPS2_IO_FPGAIO_BASE_S, + MPS2_IO_FPGAIO_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_MAIN_EXP2, + &Driver_PPC_SSE300_MAIN_EXP3, + &Driver_PPC_SSE300_PERIPH0, + &Driver_PPC_SSE300_PERIPH1, + &Driver_PPC_SSE300_PERIPH_EXP0, + &Driver_PPC_SSE300_PERIPH_EXP1, + &Driver_PPC_SSE300_PERIPH_EXP2, + &Driver_PPC_SSE300_PERIPH_EXP3, +}; + +#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_VM0_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for VM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_VM1_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for VM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SSRAM2_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for SSRAM2!"); + 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; + + /* VM0 and VM1 memories allocated for NS data, so whole range set to + * non-secure accesible. */ + ret = Driver_VM0_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for VM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_VM0_MPC.ConfigRegion(MPC_VM0_RANGE_BASE_NS, + MPC_VM0_RANGE_LIMIT_NS, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for VM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_VM1_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for VM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_VM1_MPC.ConfigRegion(MPC_VM1_RANGE_BASE_NS, + MPC_VM1_RANGE_LIMIT_NS, + ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Configure MPC for VM1!"); + 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 + * SSRAM2 device. */ + ret = Driver_SSRAM2_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SSRAM2!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SSRAM2_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 SSRAM2!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SSRAM2_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 SSRAM2!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Lock down the MPC configuration */ + ret = Driver_VM0_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for VM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_VM1_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for VM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SSRAM2_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for SSRAM2!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Initialize and lock down not used MPC driver */ + ret = Driver_SSRAM3_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SSRAM3!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_SSRAM3_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for SSRAM3!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* 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_VM0_MPC.ClearInterrupt(); + Driver_VM1_MPC.ClearInterrupt(); + Driver_SSRAM2_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( + VGA_MAIN_PPCEXP0_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + 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); + + /* 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); + + /* 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 EXP1 */ + err |= Driver_PPC_SSE300_PERIPH_EXP1.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP1.ConfigSecurity( + UART0_PERIPH_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP1.ConfigSecurity( + UART1_PERIPH_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP1.ConfigSecurity( + UART2_PERIPH_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + + /* Grant un-privileged access for UART0 in NS domain */ + err |= Driver_PPC_SSE300_PERIPH_EXP1.ConfigPrivilege( + UART0_PERIPH_PPCEXP1_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG, + PPC_SSE300_PRIV_AND_NONPRIV_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_SCC_PERIPH_PPCEXP2_POS_MASK, + PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity( + FPGA_AUDIO_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); + + /* Initialize not used PPC drivers */ + err |= Driver_PPC_SSE300_MAIN0.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP2.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP3.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP3.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/mps2/fvp_sse300/target_cfg.h b/platform/ext/target/mps2/fvp_sse300/target_cfg.h new file mode 100644 index 0000000000..fef71d3ee7 --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/target_cfg.h @@ -0,0 +1,160 @@ +/* + * 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_MAIN_EXP2 = 3, + PPC_SP_MAIN_EXP3 = 4, + PPC_SP_PERIPH0 = 5, + PPC_SP_PERIPH1 = 6, + PPC_SP_PERIPH_EXP0 = 7, + PPC_SP_PERIPH_EXP1 = 8, + PPC_SP_PERIPH_EXP2 = 9, + PPC_SP_PERIPH_EXP3 = 10, +}; + +/** + * \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; + int16_t 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/mps2/fvp_sse300/tfm_peripherals_def.h b/platform/ext/target/mps2/fvp_sse300/tfm_peripherals_def.h new file mode 100644 index 0000000000..b8d52e037e --- /dev/null +++ b/platform/ext/target/mps2/fvp_sse300/tfm_peripherals_def.h @@ -0,0 +1,52 @@ +/* + * 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) +#define FF_TEST_UART_IRQ (UARTTX2_IRQn) +#define FF_TEST_UART_IRQ_Handler UARTTX2_Handler + +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_uart1; +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_UART1 (&tfm_peripheral_uart1) +#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__ */ diff --git a/test/suites/its/CMakeLists.inc b/test/suites/its/CMakeLists.inc index 8b30f072a8..b4e64f7680 100644 --- a/test/suites/its/CMakeLists.inc +++ b/test/suites/its/CMakeLists.inc @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -34,10 +34,13 @@ elseif (ENABLE_INTERNAL_TRUSTED_STORAGE_SERVICE_TESTS) "${ITS_TEST_DIR}/secure/psa_its_s_reliability_testsuite.c" "${ITS_TEST_DIR}/its_tests_common.c") - if (NOT ITS_RAM_FS AND NOT (REFERENCE_PLATFORM OR ${TARGET_PLATFORM} STREQUAL "AN524")) - # Show flash warning message only when the RAM FS is not in use or the tests are compiled to - # be executed in the reference plaforms (AN519 and AN521) & AN524. The reference platforms and AN524 - # use RAM memory to emulated a flash device as they do not have one. + if (NOT ITS_RAM_FS + AND + NOT (REFERENCE_PLATFORM + OR ${TARGET_PLATFORM} STREQUAL "AN524" + OR ${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2")) + # Show flash warning message only when the RAM FS is not in use and the target platform contains a flash device. + # The reference platforms, AN524 and FVP_SSE300_MPS2 use RAM memory to emulate the flash. set_property(SOURCE ${ALL_SRC_C_S} APPEND PROPERTY COMPILE_DEFINITIONS ITS_SHOW_FLASH_WARNING) set_property(SOURCE ${ALL_SRC_C_NS} APPEND PROPERTY COMPILE_DEFINITIONS ITS_SHOW_FLASH_WARNING) endif() diff --git a/test/suites/sst/CMakeLists.inc b/test/suites/sst/CMakeLists.inc index 63c2349f02..852720c5fa 100644 --- a/test/suites/sst/CMakeLists.inc +++ b/test/suites/sst/CMakeLists.inc @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2017-2019, Arm Limited. All rights reserved. +# Copyright (c) 2017-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -45,10 +45,13 @@ elseif (ENABLE_SECURE_STORAGE_SERVICE_TESTS) set_property(SOURCE ${ALL_SRC_C_NS} APPEND PROPERTY COMPILE_DEFINITIONS TFM_NS_CLIENT_IDENTIFICATION) endif() - if (NOT SST_RAM_FS AND NOT (REFERENCE_PLATFORM OR ${TARGET_PLATFORM} STREQUAL "AN524")) - # Show flash warning message only when the RAM FS is not in use or the tests are compiled to - # be executed in the reference plaforms (AN519, AN521 and AN539) & AN524. The reference platforms - # and AN524 use RAM memory to emulated a flash device as they do not have one. + if (NOT SST_RAM_FS + AND + NOT (REFERENCE_PLATFORM + OR ${TARGET_PLATFORM} STREQUAL "AN524" + OR ${TARGET_PLATFORM} STREQUAL "FVP_SSE300_MPS2")) + # Show flash warning message only when the RAM FS is not in use and the target platform contains a flash device. + # The reference platforms, AN524 and FVP_SSE300_MPS2 use RAM memory to emulate the flash. set_property(SOURCE ${ALL_SRC_C_S} APPEND PROPERTY COMPILE_DEFINITIONS SST_SHOW_FLASH_WARNING) set_property(SOURCE ${ALL_SRC_C_NS} APPEND PROPERTY COMPILE_DEFINITIONS SST_SHOW_FLASH_WARNING) endif() |