diff options
author | Marton Berke <marton.berke@arm.com> | 2019-07-02 13:43:07 +0200 |
---|---|---|
committer | Marton Berke <marton.berke@arm.com> | 2019-09-10 14:09:07 +0200 |
commit | 6fd21f14138d055cbf4b278b5e3370d0d08a99d7 (patch) | |
tree | eabeda25c4b7885a42f49b006bf65e1189494e61 | |
parent | 3a43440eebaef75555ae2b737a58b3c8eb59049c (diff) | |
download | trusted-firmware-m-6fd21f14138d055cbf4b278b5e3370d0d08a99d7.tar.gz |
Platform: Add support for MPS2 AN539 FPGA board
Adds AN539 platform support files. Adds a new target platform to
the build system: "AN539".
Change-Id: I27336502f9526b0e5476d0d594c2d24fb73e72dc
Signed-off-by: Marton Berke <marton.berke@arm.com>
71 files changed, 14651 insertions, 3 deletions
diff --git a/CommonConfig.cmake b/CommonConfig.cmake index 259136b521..4ddd9be1e3 100644 --- a/CommonConfig.cmake +++ b/CommonConfig.cmake @@ -117,7 +117,7 @@ set (TFM_LEGACY_API ON) option(TFM_PARTITION_AUDIT_LOG "Enable the TF-M Audit Log partition" ON) option(TFM_PARTITION_PLATFORM "Enable the TF-M Platform partition" ON) -if(${TARGET_PLATFORM} STREQUAL "AN521" OR ${TARGET_PLATFORM} STREQUAL "AN519") +if(${TARGET_PLATFORM} STREQUAL "AN521" OR ${TARGET_PLATFORM} STREQUAL "AN519" OR ${TARGET_PLATFORM} STREQUAL "AN539") set (REFERENCE_PLATFORM ON) endif() diff --git a/configs/ConfigCoreIPC.cmake b/configs/ConfigCoreIPC.cmake index 16b032b9da..8064664e47 100644 --- a/configs/ConfigCoreIPC.cmake +++ b/configs/ConfigCoreIPC.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigCoreIPCTfmLevel2.cmake b/configs/ConfigCoreIPCTfmLevel2.cmake index 11b316fb59..176b962e8b 100644 --- a/configs/ConfigCoreIPCTfmLevel2.cmake +++ b/configs/ConfigCoreIPCTfmLevel2.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigCoreTest.cmake b/configs/ConfigCoreTest.cmake index 72700f1d76..4621c1ad8d 100644 --- a/configs/ConfigCoreTest.cmake +++ b/configs/ConfigCoreTest.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigDefault.cmake b/configs/ConfigDefault.cmake index b1e3bb77d0..a755bb7cce 100644 --- a/configs/ConfigDefault.cmake +++ b/configs/ConfigDefault.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigRegression.cmake b/configs/ConfigRegression.cmake index aecb0ef739..06d90721a0 100644 --- a/configs/ConfigRegression.cmake +++ b/configs/ConfigRegression.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set (PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigRegressionIPC.cmake b/configs/ConfigRegressionIPC.cmake index ed8c7abf13..1df578f310 100644 --- a/configs/ConfigRegressionIPC.cmake +++ b/configs/ConfigRegressionIPC.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/configs/ConfigRegressionIPCTfmLevel2.cmake b/configs/ConfigRegressionIPCTfmLevel2.cmake index 992e6aef8b..3eb465c19e 100644 --- a/configs/ConfigRegressionIPCTfmLevel2.cmake +++ b/configs/ConfigRegressionIPCTfmLevel2.cmake @@ -19,6 +19,8 @@ elseif(${TARGET_PLATFORM} STREQUAL "AN521") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps2AN521.cmake") 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 "AN524") set(PLATFORM_CMAKE_FILE "${TFM_ROOT_DIR}/platform/ext/Mps3AN524.cmake") elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A") diff --git a/docs/user_guides/tfm_secure_boot.rst b/docs/user_guides/tfm_secure_boot.rst index a10d7d3c04..9aed8dd80c 100644 --- a/docs/user_guides/tfm_secure_boot.rst +++ b/docs/user_guides/tfm_secure_boot.rst @@ -213,6 +213,8 @@ modes are supported by which platforms: +----------+-----------------+---------------+----------+-------------+-----------------+ | AN519 | Yes | Yes | Yes | Yes | No | +----------+-----------------+---------------+----------+-------------+-----------------+ +| AN539 | Yes | Yes | Yes | Yes | No | ++----------+-----------------+---------------+----------+-------------+-----------------+ | Musca-A | No | No | No | No | Yes | +----------+-----------------+---------------+----------+-------------+-----------------+ | Musca-B1 | Yes | No | No | Yes | No | diff --git a/platform/ext/Mps2AN539.cmake b/platform/ext/Mps2AN539.cmake new file mode 100644 index 0000000000..7a94d8ca6e --- /dev/null +++ b/platform/ext/Mps2AN539.cmake @@ -0,0 +1,204 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2019, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +#This file gathers all MPS2/AN539 specific files in the application. + +#MPS2/AN539 has a Cortex-M23 CPU. +include("Common/CpuM23") + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(AN539_DIR ${PLATFORM_DIR}/target/mps2/an539) + +#Specify the location of platform specific build dependencies. +if(COMPILER STREQUAL "ARMCLANG") + set (BL2_SCATTER_FILE_NAME "${AN539_DIR}/device/source/armclang/an539_mps2_bl2.sct") + set (S_SCATTER_FILE_NAME "${PLATFORM_DIR}/common/armclang/tfm_common_s.sct") + set (NS_SCATTER_FILE_NAME "${AN539_DIR}/device/source/armclang/an539_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_V8MBN.lib") + endif() +elseif(COMPILER STREQUAL "GNUARM") + set (BL2_SCATTER_FILE_NAME "${AN539_DIR}/device/source/gcc/an539_mps2_bl2.ld") + set (S_SCATTER_FILE_NAME "${PLATFORM_DIR}/common/gcc/tfm_common_s.ld") + set (NS_SCATTER_FILE_NAME "${AN539_DIR}/device/source/gcc/an539_mps2_ns.ld") + if (DEFINED CMSIS_5_DIR) + # Not all projects define CMSIS_5_DIR, only the ones that use it. + set (RTX_LIB_PATH "${CMSIS_5_DIR}/CMSIS/RTOS2/RTX/Library/GCC/libRTX_V8MBN.a") + endif() +else() + message(FATAL_ERROR "No startup file is available for compiler '${CMAKE_C_COMPILER_ID}'.") +endif() +set (FLASH_LAYOUT "${AN539_DIR}/partition/flash_layout.h") +set (PLATFORM_LINK_INCLUDES "${AN539_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/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() +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 "${AN539_DIR}" ABSOLUTE) +embedded_include_directories(PATH "${AN539_DIR}/partition" ABSOLUTE) +embedded_include_directories(PATH "${AN539_DIR}/device/include" ABSOLUTE) +embedded_include_directories(PATH "${AN539_DIR}/device/config" ABSOLUTE) +embedded_include_directories(PATH "${AN539_DIR}/cmsis_drivers/config" ABSOLUTE) +embedded_include_directories(PATH "${AN539_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 "${AN539_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 "${AN539_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) + 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 "${AN539_DIR}/native_drivers/uart_cmsdk_drv.c") + + list(APPEND ALL_SRC_C_S "${AN539_DIR}/native_drivers/mpc_sie200_drv.c" + "${AN539_DIR}/native_drivers/ppc_sse123_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 "${AN539_DIR}/native_drivers/systimer_armv8-m_drv.c") + list(APPEND ALL_SRC_C "${AN539_DIR}/native_drivers/syscounter_armv8-m_cntrl_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_ASM_S "${AN539_DIR}/device/source/armclang/startup_cmsdk_an539_mps2_s.s") + list(APPEND ALL_SRC_ASM_NS "${AN539_DIR}/device/source/armclang/startup_cmsdk_an539_mps2_ns.s") + list(APPEND ALL_SRC_ASM_BL2 "${AN539_DIR}/device/source/armclang/startup_cmsdk_an539_mps2_bl2.s") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNUARM") + list(APPEND ALL_SRC_ASM_S "${AN539_DIR}/device/source/gcc/startup_cmsdk_an539_mps2_s.S") + list(APPEND ALL_SRC_ASM_NS "${AN539_DIR}/device/source/gcc/startup_cmsdk_an539_mps2_ns.S") + list(APPEND ALL_SRC_ASM_BL2 "${AN539_DIR}/device/source/gcc/startup_cmsdk_an539_mps2_bl2.S") + set_property(SOURCE "${ALL_SRC_ASM_S}" "${ALL_SRC_ASM_NS}" "${ALL_SRC_ASM_BL2}" APPEND + PROPERTY COMPILE_DEFINITIONS "__STARTUP_CLEAR_BSS_MULTIPLE" "__STARTUP_COPY_MULTIPLE") + 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 "${AN539_DIR}/target_cfg.c") + list(APPEND ALL_SRC_C_S "${AN539_DIR}/spm_hal.c") + list(APPEND ALL_SRC_C_S "${AN539_DIR}/attest_hal.c") + list(APPEND ALL_SRC_C_S "${AN539_DIR}/native_drivers/mpu_armv8m_drv.c") + if (TFM_PARTITION_PLATFORM) + list(APPEND ALL_SRC_C_S "${AN539_DIR}/services/src/tfm_platform_system.c") + endif() + embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE) +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/tfm_initial_attestation_key_material.c") + list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c") + list(APPEND ALL_SRC_C "${AN539_DIR}/dummy_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 "${AN539_DIR}/dummy_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 "${AN539_DIR}/cmsis_drivers/Driver_MPC.c" + "${AN539_DIR}/cmsis_drivers/Driver_Flash.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_AHB_EXP0.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_APB.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_APB_EXP0.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_APB_EXP1.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_APB_EXP2.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_APB_EXP3.c" + "${AN539_DIR}/cmsis_drivers/Driver_SSE123_PPC_Common.c") + list(APPEND ALL_SRC_C "${AN539_DIR}/cmsis_drivers/Driver_USART.c") + embedded_include_directories(PATH "${AN539_DIR}/cmsis_drivers" ABSOLUTE) + embedded_include_directories(PATH "${PLATFORM_DIR}/driver" 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 "${AN539_DIR}/plat_test.c") +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 "${AN539_DIR}/cmsis_drivers/Driver_Flash.c") + # There is no real flash memory for code on MPS2 board. Instead a code SRAM is used for code + # storage: SSRAM1. 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. + set(SST_CREATE_FLASH_LAYOUT ON) + set(SST_RAM_FS OFF) + embedded_include_directories(PATH "${AN539_DIR}/cmsis_drivers" ABSOLUTE) + embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE) +endif() + +if (NOT DEFINED BUILD_BOOT_SEED) + message(FATAL_ERROR "Configuration variable BUILD_BOOT_SEED (true|false) is undefined!") +elseif(BUILD_BOOT_SEED) + list(APPEND ALL_SRC_C "${AN539_DIR}/dummy_boot_seed.c") +endif() + +if (NOT DEFINED BUILD_DEVICE_ID) + message(FATAL_ERROR "Configuration variable BUILD_DEVICE_ID (true|false) is undefined!") +elseif(BUILD_DEVICE_ID) + list(APPEND ALL_SRC_C "${AN539_DIR}/dummy_device_id.c") +endif() diff --git a/platform/ext/target/mps2/an539/attest_hal.c b/platform/ext/target/mps2/an539/attest_hal.c new file mode 100644 index 0000000000..d4d2407680 --- /dev/null +++ b/platform/ext/target/mps2/an539/attest_hal.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "platform/include/tfm_attest_hal.h" +#include <stdint.h> + +/* Example verification service URL for initial attestation token */ +static const char verification_service_url[] = "www.trustedfirmware.org"; + +/* Example profile definition document for initial attestation token */ +static const char attestation_profile_definition[] = "PSA_IOT_PROFILE_1"; + +enum tfm_security_lifecycle_t tfm_attest_hal_get_security_lifecycle(void) +{ + return TFM_SLC_SECURED; +} + +const char * +tfm_attest_hal_get_verification_service(uint32_t *size) +{ + *size = sizeof(verification_service_url) - 1; + + return verification_service_url; +} + +const char * +tfm_attest_hal_get_profile_definition(uint32_t *size) +{ + *size = sizeof(attestation_profile_definition) - 1; + + return attestation_profile_definition; +} diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_Flash.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_Flash.c new file mode 100644 index 0000000000..359405f2a3 --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,283 @@ +/* + * 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 + * + * 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" + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) ((void)arg) +#endif + +#define FLASH0_BASE_S 0x10000000 +#define FLASH0_BASE_NS 0x00000000 +#define FLASH0_SIZE 0x00400000 /* 4 MB */ +#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/an539/cmsis_drivers/Driver_MPC.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_MPC.c new file mode 100644 index 0000000000..5894ad863f --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_MPC.c @@ -0,0 +1,1750 @@ +/* + * 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 "cmsis_driver_config.h" +#include "RTE_Device.h" + +/* driver version */ +#define ARM_MPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 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_sie200_error_t). + * + * \return Returns CMSIS error code. + */ +static int32_t error_trans(enum mpc_sie200_error_t err) +{ + switch(err) { + case MPC_SIE200_ERR_NONE: + return ARM_DRIVER_OK; + case MPC_SIE200_INVALID_ARG: + return ARM_DRIVER_ERROR_PARAMETER; + case MPC_SIE200_NOT_INIT: + return ARM_MPC_ERR_NOT_INIT; + case MPC_SIE200_ERR_NOT_IN_RANGE: + return ARM_MPC_ERR_NOT_IN_RANGE; + case MPC_SIE200_ERR_NOT_ALIGNED: + return ARM_MPC_ERR_NOT_ALIGNED; + case MPC_SIE200_ERR_INVALID_RANGE: + return ARM_MPC_ERR_INVALID_RANGE; + case MPC_SIE200_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_sie200_memory_range_t MPC_ISRAM0_RANGE_S = { + .base = MPC_ISRAM0_RANGE_BASE_S, + .limit = MPC_ISRAM0_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_ISRAM0_RANGE_NS = { + .base = MPC_ISRAM0_RANGE_BASE_NS, + .limit = MPC_ISRAM0_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM0_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_ISRAM0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_ISRAM0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_ISRAM0_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_ISRAM0_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_ISRAM0_DEV); + + return error_trans(ret); +} + +static void ISRAM0_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_ISRAM0_DEV); +} + + +static void ISRAM0_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_ISRAM0_DEV); +} + +static uint32_t ISRAM0_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_ISRAM0_DEV); +} + +static int32_t ISRAM0_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_ISRAM0_DEV); +} + +/* ISRAM0_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_ISRAM0_MPC; +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_sie200_memory_range_t MPC_ISRAM1_RANGE_S = { + .base = MPC_ISRAM1_RANGE_BASE_S, + .limit = MPC_ISRAM1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_ISRAM1_RANGE_NS = { + .base = MPC_ISRAM1_RANGE_BASE_NS, + .limit = MPC_ISRAM1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM1_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_ISRAM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_ISRAM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_ISRAM1_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_ISRAM1_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_ISRAM1_DEV); + + return error_trans(ret); +} + +static void ISRAM1_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_ISRAM1_DEV); +} + + +static void ISRAM1_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_ISRAM1_DEV); +} + +static uint32_t ISRAM1_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_ISRAM1_DEV); +} + +static int32_t ISRAM1_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_ISRAM1_DEV); +} + +/* ISRAM1_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_ISRAM1_MPC; +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_sie200_memory_range_t MPC_ISRAM2_RANGE_S = { + .base = MPC_ISRAM2_RANGE_BASE_S, + .limit = MPC_ISRAM2_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_ISRAM2_RANGE_NS = { + .base = MPC_ISRAM2_RANGE_BASE_NS, + .limit = MPC_ISRAM2_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM2_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_ISRAM2_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_ISRAM2_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_ISRAM2_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_ISRAM2_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM2_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_ISRAM2_DEV); + + return error_trans(ret); +} + +static void ISRAM2_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_ISRAM2_DEV); +} + +static void ISRAM2_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_ISRAM2_DEV); +} + +static uint32_t ISRAM2_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_ISRAM2_DEV); +} + +static int32_t ISRAM2_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_ISRAM2_DEV); +} + +/* ISRAM2_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_ISRAM2_MPC; +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_sie200_memory_range_t MPC_ISRAM3_RANGE_S = { + .base = MPC_ISRAM3_RANGE_BASE_S, + .limit = MPC_ISRAM3_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_ISRAM3_RANGE_NS = { + .base = MPC_ISRAM3_RANGE_BASE_NS, + .limit = MPC_ISRAM3_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM3_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_ISRAM3_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_ISRAM3_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_ISRAM3_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_ISRAM3_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t ISRAM3_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_ISRAM3_DEV); + + return error_trans(ret); +} + +static void ISRAM3_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_ISRAM3_DEV); +} + + +static void ISRAM3_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_ISRAM3_DEV); +} + +static uint32_t ISRAM3_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_ISRAM3_DEV); +} + +static int32_t ISRAM3_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_ISRAM3_DEV); +} + +/* ISRAM3_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_ISRAM3_MPC; +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_sie200_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_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_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_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_CODE_SRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_CODE_SRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_CODE_SRAM_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_CODE_SRAM_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t CODE_SRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_CODE_SRAM_DEV); + + return error_trans(ret); +} + +static void CODE_SRAM_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_CODE_SRAM_DEV); +} + + +static void CODE_SRAM_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_CODE_SRAM_DEV); +} + +static uint32_t CODE_SRAM_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_CODE_SRAM_DEV); +} + +static int32_t CODE_SRAM_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_CODE_SRAM_DEV); +} + +/* CODE_SRAM_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_CODE_SRAM_MPC; +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_sie200_memory_range_t MPC_SSRAM1_RANGE_S = { + .base = MPC_SSRAM1_RANGE_BASE_S, + .limit = MPC_SSRAM1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_SSRAM1_RANGE_NS = { + .base = MPC_SSRAM1_RANGE_BASE_NS, + .limit = MPC_SSRAM1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM1_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_SSRAM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_SSRAM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_SSRAM1_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_SSRAM1_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_SSRAM1_DEV); + + return error_trans(ret); +} + +static void SSRAM1_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_SSRAM1_DEV); +} + + +static void SSRAM1_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_SSRAM1_DEV); +} + +static uint32_t SSRAM1_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_SSRAM1_DEV); +} + +static int32_t SSRAM1_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_SSRAM1_DEV); +} + +/* SSRAM1_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_SRAM1_MPC; +ARM_DRIVER_MPC Driver_SRAM1_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_sie200_memory_range_t MPC_SSRAM2_RANGE_S = { + .base = MPC_SSRAM2_RANGE_BASE_S, + .limit = MPC_SSRAM2_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_SSRAM2_RANGE_NS = { + .base = MPC_SSRAM2_RANGE_BASE_NS, + .limit = MPC_SSRAM2_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM2_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_SSRAM2_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_SSRAM2_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_SSRAM2_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_SSRAM2_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM2_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_SSRAM2_DEV); + + return error_trans(ret); +} + +static void SSRAM2_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_SSRAM2_DEV); +} + + +static void SSRAM2_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_SSRAM2_DEV); +} + +static uint32_t SSRAM2_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_SSRAM2_DEV); +} + +static int32_t SSRAM2_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_SSRAM2_DEV); +} + +/* SSRAM2_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_SRAM2_MPC; +ARM_DRIVER_MPC Driver_SRAM2_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_sie200_memory_range_t MPC_SSRAM3_RANGE_S = { + .base = MPC_SSRAM3_RANGE_BASE_S, + .limit = MPC_SSRAM3_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_SSRAM3_RANGE_NS = { + .base = MPC_SSRAM3_RANGE_BASE_NS, + .limit = MPC_SSRAM3_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_SSRAM3_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_SSRAM3_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_SSRAM3_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_SSRAM3_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_SSRAM3_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t SSRAM3_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_SSRAM3_DEV); + + return error_trans(ret); +} + +static void SSRAM3_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_SSRAM3_DEV); +} + + +static void SSRAM3_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_SSRAM3_DEV); +} + +static uint32_t SSRAM3_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_SSRAM3_DEV); +} + +static int32_t SSRAM3_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_SSRAM3_DEV); +} + +/* SSRAM3_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_SSRAM3_MPC; +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_sie200_memory_range_t MPC_QSPI_RANGE_S = { + .base = MPC_QSPI_RANGE_BASE_S, + .limit = MPC_QSPI_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_QSPI_RANGE_NS = { + .base = MPC_QSPI_RANGE_BASE_NS, + .limit = MPC_QSPI_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_QSPI_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_QSPI_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_QSPI_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_QSPI_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_QSPI_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_QSPI_DEV); + + return error_trans(ret); +} + +static void QSPI_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_QSPI_DEV); +} + + +static void QSPI_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_QSPI_DEV); +} + +static uint32_t QSPI_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_QSPI_DEV); +} + +static int32_t QSPI_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_QSPI_DEV); +} + +/* QSPI1_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_QSPI_MPC; +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_sie200_memory_range_t MPC_EFLASH0_RANGE_S = { + .base = MPC_EFLASH0_RANGE_BASE_S, + .limit = MPC_EFLASH0_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_EFLASH0_RANGE_NS = { + .base = MPC_EFLASH0_RANGE_BASE_NS, + .limit = MPC_EFLASH0_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_EFLASH0_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_EFLASH0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_EFLASH0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_EFLASH0_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_EFLASH0_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t EFLASH0_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_EFLASH0_DEV); + + return error_trans(ret); +} + +static void EFLASH0_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_EFLASH0_DEV); +} + + +static void EFLASH0_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_EFLASH0_DEV); +} + +static uint32_t EFLASH0_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_EFLASH0_DEV); +} + +static int32_t EFLASH0_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_EFLASH0_DEV); +} + +/* EFLASH0_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_EFLASH0_MPC; +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_sie200_memory_range_t MPC_EFLASH1_RANGE_S = { + .base = MPC_EFLASH1_RANGE_BASE_S, + .limit = MPC_EFLASH1_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_EFLASH1_RANGE_NS = { + .base = MPC_EFLASH1_RANGE_BASE_NS, + .limit = MPC_EFLASH1_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_EFLASH1_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_EFLASH1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_EFLASH1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_EFLASH1_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_EFLASH1_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t EFLASH1_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_EFLASH1_DEV); + + return error_trans(ret); +} + +static void EFLASH1_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_EFLASH1_DEV); +} + + +static void EFLASH1_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_EFLASH1_DEV); +} + +static uint32_t EFLASH1_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_EFLASH1_DEV); +} + +static int32_t EFLASH1_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_EFLASH1_DEV); +} + +/* EFLASH1_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_EFLASH1_MPC; +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_sie200_memory_range_t MPC_BRAM_RANGE_S = { + .base = MPC_BRAM_RANGE_BASE_S, + .limit = MPC_BRAM_RANGE_LIMIT_S, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_SECURE +}; + +static const struct mpc_sie200_memory_range_t MPC_BRAM_RANGE_NS = { + .base = MPC_BRAM_RANGE_BASE_NS, + .limit = MPC_BRAM_RANGE_LIMIT_NS, + .range_offset = 0, + .attr = MPC_SIE200_SEC_ATTR_NONSECURE +}; + +#define MPC_BRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_block_size(&MPC_BRAM_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_GetCtrlConfig(uint32_t *ctrl_val) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_get_ctrl(&MPC_BRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_get_region_config(&MPC_BRAM_DEV, base, limit, + (enum mpc_sie200_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_sie200_error_t ret; + + ret = mpc_sie200_config_region(&MPC_BRAM_DEV, base, limit, + (enum mpc_sie200_sec_attr_t)attr); + + return error_trans(ret); +} + +static int32_t BRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie200_error_t ret; + + ret = mpc_sie200_irq_enable(&MPC_BRAM_DEV); + + return error_trans(ret); +} + +static void BRAM_MPC_DisableInterrupt(void) +{ + mpc_sie200_irq_disable(&MPC_BRAM_DEV); +} + + +static void BRAM_MPC_ClearInterrupt(void) +{ + mpc_sie200_clear_irq(&MPC_BRAM_DEV); +} + +static uint32_t BRAM_MPC_InterruptState(void) +{ + return mpc_sie200_irq_state(&MPC_BRAM_DEV); +} + +static int32_t BRAM_MPC_LockDown(void) +{ + return mpc_sie200_lock_down(&MPC_BRAM_DEV); +} + +/* BRAM_MPC Driver CMSIS access structure */ +extern ARM_DRIVER_MPC Driver_BRAM_MPC; +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 */ diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC.h b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC.h new file mode 100644 index 0000000000..e2a4c40f7a --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC.h @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#ifndef __PPC_SSE123_DRIVER_H__ +#define __PPC_SSE123_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_SSE123_SecAttr { + PPC_SSE123_SECURE_CONFIG = 0, /*!< Secure access */ + PPC_SSE123_NONSECURE_CONFIG, /*!< Non-secure access */ +} PPC_SSE123_SecAttr; + +/* Privilege attribute used to configure the peripheral */ +typedef enum _PPC_SSE123_PrivAttr { + PPC_SSE123_PRIV_AND_NONPRIV_CONFIG = 0, /*!< Privilege and non-privilege + * access */ + PPC_SSE123_PRIV_CONFIG, /*!< Privilege only access */ +} PPC_SSE123_PrivAttr; + +/* Function documentation */ +/** + SPCTRL - Secure Privilege Control Block + NSPCTRL - Non-Secure Privilege Control Block + + \fn ARM_DRIVER_VERSION PPC_SSE123_GetVersion(void) + \brief Get driver version. + \return \ref ARM_DRIVER_VERSION + + \fn int32_t PPC_SSE123_Initialize(void) + \brief Initializes PPC Interface. + \return Returns SSE-123 PPC error code. + + \fn int32_t PPC_SSE123_Uninitialize(void) + \brief De-initializes PPC Interface. + \return Returns SSE-123 PPC error code. + + \fn int32_t PPC_SSE123_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) + \brief Configures a peripheral controlled by the given PPC in the given + security domain with privileged and unprivileged access + or privileged access only. + \param[in] periph: Peripheral position in SPCTRL and NSPCTRL registers. + \param[in] sec_attr: Secure attribute value. + \param[in] priv_attr: Privilege attribute value. + \return Returns SSE-123 PPC error code. + + \fn bool PPC_SSE123_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 position in SPCTRL and NSPCTRL 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_SSE123_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) + \brief Configures a peripheral controlled by the given PPC with secure + or non-secure access only + \param[in] periph: Peripheral position in SPCTRL and NSPCTRL registers. + \param[in] sec_attr: Secure attribute value. + \return Returns SSE-123 PPC error code. + + \fn bool PPC_SSE123_IsPeriphSecure (uint32_t periph) + \brief Checks if the peripheral is configured to be secure. + \param[in] periph: Peripheral position in SPCTRL and NSPCTRL registers. + \return Returns true if the peripheral is configured as secure, + false for non-secure. + + \fn int32_t PPC_SSE123_EnableInterrupt (void) + \brief Enables PPC interrupt. + \return Returns SSE-123 PPC error code. + + \fn void PPC_SSE123_DisableInterrupt (void) + \brief Disables PPC interrupt. + + \fn void PPC_SSE123_ClearInterrupt (void) + \brief Clears PPC interrupt. + + \fn bool PPC_SSE123_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_SSE123 { + 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_SSE123_SecAttr sec_attr, PPC_SSE123_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_SSE123_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_SSE123; + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE123_DRIVER_H__ */ diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_AHB_EXP0.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_AHB_EXP0.c new file mode 100644 index 0000000000..60617d970f --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_AHB_EXP0.c @@ -0,0 +1,109 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + + +#if (RTE_PPC_SSE123_AHB_EXP0) + +static SSE123_PPC_Resources AHB_EXP0_PPC_DEV = { + .dev = &PPC_SSE123_AHB_EXP0_DEV, +}; + +/* AHB PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE123_AHB_EXP0_Initialize(void) +{ + return PPC_SSE123_Initialize(&AHB_EXP0_PPC_DEV); +} + +static int32_t PPC_SSE123_AHB_EXP0_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_AHB_EXP0_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&AHB_EXP0_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_AHB_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&AHB_EXP0_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_AHB_EXP0_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&AHB_EXP0_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_AHB_EXP0_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&AHB_EXP0_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_AHB_EXP0_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&AHB_EXP0_PPC_DEV); +} + +static void PPC_SSE123_AHB_EXP0_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&AHB_EXP0_PPC_DEV); +} + +static void PPC_SSE123_AHB_EXP0_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&AHB_EXP0_PPC_DEV); +} + +static bool PPC_SSE123_AHB_EXP0_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&AHB_EXP0_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 AHB EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_AHB_EXP0 = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_AHB_EXP0_Initialize, + .Uninitialize = PPC_SSE123_AHB_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE123_AHB_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_AHB_EXP0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_AHB_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_AHB_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_AHB_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_AHB_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_AHB_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE123_AHB_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_AHB_EXP0 */ + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB.c new file mode 100644 index 0000000000..5b31ee784a --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB.c @@ -0,0 +1,109 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#if (RTE_PPC_SSE123_APB) + +static SSE123_PPC_Resources APB_PPC_DEV = { + .dev = &PPC_SSE123_APB_DEV, +}; + +/* APB Driver wrapper functions */ +static int32_t PPC_SSE123_APB_Initialize(void) +{ + return PPC_SSE123_Initialize(&APB_PPC_DEV); +} + +static int32_t PPC_SSE123_APB_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_APB_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&APB_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_APB_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&APB_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_APB_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&APB_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_APB_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&APB_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_APB_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&APB_PPC_DEV); +} + +static void PPC_SSE123_APB_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&APB_PPC_DEV); +} + +static void PPC_SSE123_APB_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&APB_PPC_DEV); +} + +static bool PPC_SSE123_APB_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&APB_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 APB Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_APB_Initialize, + .Uninitialize = PPC_SSE123_APB_Uninitialize, + .ConfigPrivilege = PPC_SSE123_APB_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_APB_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_APB_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_APB_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_APB_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_APB_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_APB_ClearInterrupt, + .InterruptState = PPC_SSE123_APB_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_APB */ + + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP0.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP0.c new file mode 100644 index 0000000000..3dad5d36ef --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP0.c @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#if (RTE_PPC_SSE123_APB_EXP0) + +static SSE123_PPC_Resources APB_EXP0_PPC_DEV = { + .dev = &PPC_SSE123_APB_EXP0_DEV, +}; + +/* APB PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE123_APB_EXP0_Initialize(void) +{ + return PPC_SSE123_Initialize(&APB_EXP0_PPC_DEV); +} + +static int32_t PPC_SSE123_APB_EXP0_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_APB_EXP0_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&APB_EXP0_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_APB_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&APB_EXP0_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_APB_EXP0_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&APB_EXP0_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_APB_EXP0_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&APB_EXP0_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_APB_EXP0_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&APB_EXP0_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP0_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&APB_EXP0_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP0_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&APB_EXP0_PPC_DEV); +} + +static bool PPC_SSE123_APB_EXP0_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&APB_EXP0_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 APB EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP0 = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_APB_EXP0_Initialize, + .Uninitialize = PPC_SSE123_APB_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE123_APB_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_APB_EXP0_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_APB_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_APB_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_APB_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_APB_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_APB_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE123_APB_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_APB_EXP0 */ + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP1.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP1.c new file mode 100644 index 0000000000..56bc0cb180 --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP1.c @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#if (RTE_PPC_SSE123_APB_EXP1) + +static SSE123_PPC_Resources APB_EXP1_PPC_DEV = { + .dev = &PPC_SSE123_APB_EXP1_DEV, +}; + +/* APB PPCEXP1 Driver wrapper functions */ +static int32_t PPC_SSE123_APB_EXP1_Initialize(void) +{ + return PPC_SSE123_Initialize(&APB_EXP1_PPC_DEV); +} + +static int32_t PPC_SSE123_APB_EXP1_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_APB_EXP1_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&APB_EXP1_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_APB_EXP1_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&APB_EXP1_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_APB_EXP1_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&APB_EXP1_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_APB_EXP1_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&APB_EXP1_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_APB_EXP1_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&APB_EXP1_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP1_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&APB_EXP1_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP1_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&APB_EXP1_PPC_DEV); +} + +static bool PPC_SSE123_APB_EXP1_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&APB_EXP1_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 APB EXP1 Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP1 = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_APB_EXP1_Initialize, + .Uninitialize = PPC_SSE123_APB_EXP1_Uninitialize, + .ConfigPrivilege = PPC_SSE123_APB_EXP1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_APB_EXP1_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_APB_EXP1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_APB_EXP1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_APB_EXP1_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_APB_EXP1_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_APB_EXP1_ClearInterrupt, + .InterruptState = PPC_SSE123_APB_EXP1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_APB_EXP1 */ + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP2.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP2.c new file mode 100644 index 0000000000..2748223762 --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP2.c @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#if (RTE_PPC_SSE123_APB_EXP2) + +static SSE123_PPC_Resources APB_EXP2_PPC_DEV = { + .dev = &PPC_SSE123_APB_EXP2_DEV, +}; + +/* APB PPCEXP2 Driver wrapper functions */ +static int32_t PPC_SSE123_APB_EXP2_Initialize(void) +{ + return PPC_SSE123_Initialize(&APB_EXP2_PPC_DEV); +} + +static int32_t PPC_SSE123_APB_EXP2_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_APB_EXP2_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&APB_EXP2_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_APB_EXP2_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&APB_EXP2_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_APB_EXP2_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&APB_EXP2_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_APB_EXP2_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&APB_EXP2_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_APB_EXP2_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&APB_EXP2_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP2_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&APB_EXP2_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP2_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&APB_EXP2_PPC_DEV); +} + +static bool PPC_SSE123_APB_EXP2_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&APB_EXP2_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 APB EXP2 Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP2 = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_APB_EXP2_Initialize, + .Uninitialize = PPC_SSE123_APB_EXP2_Uninitialize, + .ConfigPrivilege = PPC_SSE123_APB_EXP2_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_APB_EXP2_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_APB_EXP2_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_APB_EXP2_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_APB_EXP2_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_APB_EXP2_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_APB_EXP2_ClearInterrupt, + .InterruptState = PPC_SSE123_APB_EXP2_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_APB_EXP2 */ + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP3.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP3.c new file mode 100644 index 0000000000..ad8358567d --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_APB_EXP3.c @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.h" + +#if (RTE_PPC_SSE123_APB_EXP3) + +static SSE123_PPC_Resources APB_EXP3_PPC_DEV = { + .dev = &PPC_SSE123_APB_EXP3_DEV, +}; + +/* APB PPCEXP3 Driver wrapper functions */ +static int32_t PPC_SSE123_APB_EXP3_Initialize(void) +{ + return PPC_SSE123_Initialize(&APB_EXP3_PPC_DEV); +} + +static int32_t PPC_SSE123_APB_EXP3_Uninitialize(void) +{ + return PPC_SSE123_Uninitialize(); +} + +static int32_t +PPC_SSE123_APB_EXP3_ConfigPrivilege(uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + return PPC_SSE123_ConfigPrivilege(&APB_EXP3_PPC_DEV, periph, sec_attr, + priv_attr); +} + +static bool PPC_SSE123_APB_EXP3_IsPeriphPrivOnly(uint32_t periph) +{ + return PPC_SSE123_IsPeriphPrivOnly(&APB_EXP3_PPC_DEV, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t +PPC_SSE123_APB_EXP3_ConfigSecurity(uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + return PPC_SSE123_ConfigSecurity(&APB_EXP3_PPC_DEV, periph, sec_attr); +} + +static bool PPC_SSE123_APB_EXP3_IsPeriphSecure(uint32_t periph) +{ + return PPC_SSE123_IsPeriphSecure(&APB_EXP3_PPC_DEV, periph); +} + +static int32_t PPC_SSE123_APB_EXP3_EnableInterrupt(void) +{ + return PPC_SSE123_EnableInterrupt(&APB_EXP3_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP3_DisableInterrupt(void) +{ + PPC_SSE123_DisableInterrupt(&APB_EXP3_PPC_DEV); +} + +static void PPC_SSE123_APB_EXP3_ClearInterrupt(void) +{ + PPC_SSE123_ClearInterrupt(&APB_EXP3_PPC_DEV); +} + +static bool PPC_SSE123_APB_EXP3_InterruptState(void) +{ + return PPC_SSE123_InterruptState(&APB_EXP3_PPC_DEV); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-123 APB EXP3 Driver CMSIS access structure */ +DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP3 = { + .GetVersion = PPC_SSE123_GetVersion, + .Initialize = PPC_SSE123_APB_EXP3_Initialize, + .Uninitialize = PPC_SSE123_APB_EXP3_Uninitialize, + .ConfigPrivilege = PPC_SSE123_APB_EXP3_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE123_APB_EXP3_IsPeriphPrivOnly, +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE123_APB_EXP3_ConfigSecurity, + .IsPeriphSecure = PPC_SSE123_APB_EXP3_IsPeriphSecure, + .EnableInterrupt = PPC_SSE123_APB_EXP3_EnableInterrupt, + .DisableInterrupt = PPC_SSE123_APB_EXP3_DisableInterrupt, + .ClearInterrupt = PPC_SSE123_APB_EXP3_ClearInterrupt, + .InterruptState = PPC_SSE123_APB_EXP3_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE123_APB_EXP3 */ + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.c new file mode 100644 index 0000000000..803406912e --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.c @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#include "Driver_SSE123_PPC_Common.h" + +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "RTE_Device.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_SSE123_GetVersion(void) +{ + return DriverVersion; +} + +int32_t PPC_SSE123_Initialize(SSE123_PPC_Resources *ppc_dev) +{ + ppc_sse123_init(ppc_dev->dev); + + return ARM_DRIVER_OK; +} + +int32_t PPC_SSE123_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +int32_t PPC_SSE123_ConfigPrivilege(SSE123_PPC_Resources *ppc_dev, + uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr) +{ + enum ppc_sse123_error_t ret; + + ret = ppc_sse123_config_privilege(ppc_dev->dev, periph, + (enum ppc_sse123_sec_attr_t)sec_attr, + (enum ppc_sse123_priv_attr_t)priv_attr); + + if( ret != PPC_SSE123_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +bool PPC_SSE123_IsPeriphPrivOnly(SSE123_PPC_Resources *ppc_dev, + uint32_t periph) +{ + return ppc_sse123_is_periph_priv_only(ppc_dev->dev, periph); +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +int32_t PPC_SSE123_ConfigSecurity(SSE123_PPC_Resources *ppc_dev, + uint32_t periph, + PPC_SSE123_SecAttr sec_attr) +{ + enum ppc_sse123_error_t ret; + + ret = ppc_sse123_config_security(ppc_dev->dev, periph, + (enum ppc_sse123_sec_attr_t)sec_attr); + + if( ret != PPC_SSE123_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +bool PPC_SSE123_IsPeriphSecure(SSE123_PPC_Resources *ppc_dev, uint32_t periph) +{ + return ppc_sse123_is_periph_secure(ppc_dev->dev, periph); +} + +int32_t PPC_SSE123_EnableInterrupt(SSE123_PPC_Resources *ppc_dev) +{ + enum ppc_sse123_error_t ret; + + ret = ppc_sse123_irq_enable(ppc_dev->dev); + + if( ret != PPC_SSE123_ERR_NONE) { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +void PPC_SSE123_DisableInterrupt(SSE123_PPC_Resources *ppc_dev) +{ + ppc_sse123_irq_disable(ppc_dev->dev); +} + +void PPC_SSE123_ClearInterrupt(SSE123_PPC_Resources *ppc_dev) +{ + ppc_sse123_clear_irq(ppc_dev->dev); +} + +bool PPC_SSE123_InterruptState(SSE123_PPC_Resources *ppc_dev) +{ + return ppc_sse123_irq_state(ppc_dev->dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + + diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.h b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.h new file mode 100644 index 0000000000..dbbf7ddb60 --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_SSE123_PPC_Common.h @@ -0,0 +1,151 @@ +/* + * 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. + */ + +#ifndef __PPC_SSE123_COMMON_H__ +#define __PPC_SSE123_COMMON_H__ + +#include "Driver_Common.h" +#include "Driver_SSE123_PPC.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _SSE123_PPC_Resources { + struct ppc_sse123_dev_t* dev; /* PPC device structure */ +} SSE123_PPC_Resources; + +/** + * \brief Get driver version. + * + * \return \ref ARM_DRIVER_VERSION + */ +ARM_DRIVER_VERSION PPC_SSE123_GetVersion(void); + +/** + * \brief Initializes PPC Interface. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * + * \return Returns SSE-123 PPC error code. + */ +int32_t PPC_SSE123_Initialize(SSE123_PPC_Resources *ppc_dev); + +/** + * \brief De-initializes PPC Interface. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * + * \return Returns SSE-123 PPC error code. + */ +int32_t PPC_SSE123_Uninitialize(void); + +/** + * \brief Configures a peripheral controlled by the given PPC + * in the given security domain with privileged and + * unprivileged access or privileged access only. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * \param[in] periph Peripheral position in SPCTRL and NSPCTRL registers. + * \param[in] sec_attr Secure attribute value. + * \param[in] priv_attr Privilege attribute value. + * + * \return Returns SSE-123 PPC error code. + */ +int32_t PPC_SSE123_ConfigPrivilege(SSE123_PPC_Resources *ppc_dev, + uint32_t periph, + PPC_SSE123_SecAttr sec_attr, + PPC_SSE123_PrivAttr priv_attr); + +/** + * \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] ppc_dev PPC device \ref SSE123_PPC_Resources + * \param[in] periph Peripheral position in SPCTRL and NSPCTRL registers. + * + * \return Returns true if the peripheral is configured as privilege access + * only, false for privilege and unprivilege access mode. + */ +bool PPC_SSE123_IsPeriphPrivOnly(SSE123_PPC_Resources *ppc_dev, + uint32_t periph); + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +/** + * \brief Configures a peripheral controlled by the given PPC with secure + * or non-secure access only + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * \param[in] periph Peripheral position in SPCTRL and NSPCTRL registers. + * \param[in] sec_attr Secure attribute value. + * + * \return Returns SSE-123 PPC error code. + */ +int32_t PPC_SSE123_ConfigSecurity(SSE123_PPC_Resources *ppc_dev, + uint32_t periph, + PPC_SSE123_SecAttr sec_attr); + +/** + * \brief Checks if the peripheral is configured to be secure. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * \param[in] periph Peripheral position in SPCTRL and NSPCTRL registers. + * + * \return Returns true if the peripheral is configured as secure, + * false for non-secure. + */ +bool PPC_SSE123_IsPeriphSecure(SSE123_PPC_Resources *ppc_dev, uint32_t periph); + +/** + * \brief Enables PPC interrupt. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * + * \return Returns SSE-123 PPC error code. + */ +int32_t PPC_SSE123_EnableInterrupt(SSE123_PPC_Resources *ppc_dev); + +/** + * \brief Disables PPC interrupt. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + */ +void PPC_SSE123_DisableInterrupt(SSE123_PPC_Resources *ppc_dev); + +/** + * \brief Clears PPC interrupt. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + */ +void PPC_SSE123_ClearInterrupt(SSE123_PPC_Resources *ppc_dev); + +/** + * \brief Gets PPC interrupt state. + * + * \param[in] ppc_dev PPC device \ref SSE123_PPC_Resources + * + * \return Returns true if the interrupt is active, false otherwise + */ +bool PPC_SSE123_InterruptState(SSE123_PPC_Resources *ppc_dev); + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE123_COMMON_H__ */ diff --git a/platform/ext/target/mps2/an539/cmsis_drivers/Driver_USART.c b/platform/ext/target/mps2/an539/cmsis_drivers/Driver_USART.c new file mode 100644 index 0000000000..cb3a14ad3e --- /dev/null +++ b/platform/ext/target/mps2/an539/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/an539/cmsis_drivers/config/RTE_Device.h b/platform/ext/target/mps2/an539/cmsis_drivers/config/RTE_Device.h new file mode 100644 index 0000000000..f0fa0dcdfd --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/config/RTE_Device.h @@ -0,0 +1,105 @@ +/* + * 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 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART2] +// <i> Configuration settings for Driver_USART2 in component ::Drivers:USART +#define RTE_USART2 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART2] + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART3] +// <i> Configuration settings for Driver_USART3 in component ::Drivers:USART +#define RTE_USART3 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART3] + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART4] +// <i> Configuration settings for Driver_USART4 in component ::Drivers:USART +#define RTE_USART4 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART4] + +// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART5] +// <i> Configuration settings for Driver_USART5 in component ::Drivers:USART +#define RTE_USART5 0 +// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART5] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// <i> Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// <i> Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_SSRAM1_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM2_MPC] +// <i> Configuration settings for Driver_ISRAM2_MPC in component ::Drivers:MPC +#define RTE_SSRAM2_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM2_MPC] + +// <e> MPC (Memory Protection Controller) [Driver_ISRAM3_MPC] +// <i> Configuration settings for Driver_ISRAM3_MPC in component ::Drivers:MPC +#define RTE_SSRAM3_MPC 1 +// </e> MPC (Memory Protection Controller) [Driver_ISRAM3_MPC] + +// <e> PPC (Peripheral Protection Controller) [Driver_AHB_PPCEXP0] +// <i> Configuration settings for Driver_AHB_PPCEXP0 in component ::Drivers:MPC +#define RTE_PPC_SSE123_AHB_EXP0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_AHB_PPCEXP0] + +// <e> PPC (Peripheral Protection Controller) [Driver_APB_PPC0] +// <i> Configuration settings for Driver_APB_PPC0 in component ::Drivers:MPC +#define RTE_PPC_SSE123_APB 1 +// </e> PPC (Peripheral Protection Controller) [Driver_APB_PPC0] + +// <e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP0] +// <i> Configuration settings for Driver_APB_PPCEXP0 in component ::Drivers:MPC +#define RTE_PPC_SSE123_APB_EXP0 1 +// </e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP0] + +// <e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP1] +// <i> Configuration settings for Driver_APB_PPCEXP1 in component ::Drivers:MPC +#define RTE_PPC_SSE123_APB_EXP1 1 +// </e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP1] + +// <e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP2] +// <i> Configuration settings for Driver_APB_PPCEXP2 in component ::Drivers:MPC +#define RTE_PPC_SSE123_APB_EXP2 1 +// </e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP2] + +// <e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP2] +// <i> Configuration settings for Driver_APB_PPCEXP2 in component ::Drivers:MPC +#define RTE_PPC_SSE123_APB_EXP3 1 +// </e> PPC (Peripheral Protection Controller) [Driver_APB_PPCEXP2] + +// <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/an539/cmsis_drivers/config/cmsis_driver_config.h b/platform/ext/target/mps2/an539/cmsis_drivers/config/cmsis_driver_config.h new file mode 100644 index 0000000000..09c0fd2b93 --- /dev/null +++ b/platform/ext/target/mps2/an539/cmsis_drivers/config/cmsis_driver_config.h @@ -0,0 +1,37 @@ +/* + * 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 __CMSIS_DRIVER_CONFIG_H__ +#define __CMSIS_DRIVER_CONFIG_H__ + +#include "platform_description.h" +#include "device_definition.h" + +#define UART0_CMSDK_DEV ARM_UART0_DEV_NS + +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S +#define MPC_SSRAM1_DEV MPC_SSRAM1_DEV_S +#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S + +#define PPC_SSE123_AHB_EXP0_DEV PPC_SSE123_AHB_EXP0_DEV_S +#define PPC_SSE123_APB_DEV PPC_SSE123_APB_DEV_S +#define PPC_SSE123_APB_EXP0_DEV PPC_SSE123_APB_EXP0_DEV_S +#define PPC_SSE123_APB_EXP1_DEV PPC_SSE123_APB_EXP1_DEV_S +#define PPC_SSE123_APB_EXP2_DEV PPC_SSE123_APB_EXP2_DEV_S +#define PPC_SSE123_APB_EXP3_DEV PPC_SSE123_APB_EXP3_DEV_S + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/platform/ext/target/mps2/an539/device/config/device_cfg.h b/platform/ext/target/mps2/an539/device/config/device_cfg.h new file mode 100644 index 0000000000..1537fe60e9 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/config/device_cfg.h @@ -0,0 +1,66 @@ +/* + * 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_ISRAM0_S +#define MPC_SSRAM1_S +#define MPC_SSRAM2_S +#define MPC_SSRAM3_S + +/* ARM Peripheral Protection Controllers (PPC) */ +#define PPC_SSE123_AHB_EXP0_S +#define PPC_SSE123_APB_S +#define PPC_SSE123_APB_EXP0_S +#define PPC_SSE123_APB_EXP1_S +#define PPC_SSE123_APB_EXP2_S +#define PPC_SSE123_APB_EXP3_S + +/* ARM UART CMSDK */ +#define DEFAULT_UART_BAUDRATE 115200 +#define UART0_CMSDK_S +#define UART0_CMSDK_NS + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S + +/** + * Arbitrary scaling values for test purposes + */ +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u + +/* System Timer Armv8-M */ +#define SYSTIMER0_ARMV8_M_S +#define 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/an539/device/include/cmsis.h b/platform/ext/target/mps2/an539/device/include/cmsis.h new file mode 100644 index 0000000000..d3317e5c26 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/cmsis.h @@ -0,0 +1,75 @@ +/* + * 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. + */ + +#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 __CM23_REV 0x0100U /* Core revision r1p0 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 2U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ + +#include "platform_description.h" +#include "platform_irq.h" +#include <core_cm23.h> /*!< ARM Cortex-M23 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/an539/device/include/device_definition.h b/platform/ext/target/mps2/an539/device/include/device_definition.h new file mode 100644 index 0000000000..4432ab35be --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/device_definition.h @@ -0,0 +1,219 @@ +/* + * 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 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 + +#ifdef UART3_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART3_DEV_S; +#endif +#ifdef UART3_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART3_DEV_NS; +#endif + +#ifdef UART4_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART4_DEV_S; +#endif +#ifdef UART4_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t ARM_UART4_DEV_NS; +#endif + +/* SSE-123 PPC driver structures */ +#ifdef PPC_SSE123_AHB_EXP0_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_AHB_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE123_APB_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_APB_DEV_S; +#endif + +#ifdef PPC_SSE123_APB_EXP0_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_APB_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE123_APB_EXP1_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_APB_EXP1_DEV_S; +#endif + +#ifdef PPC_SSE123_APB_EXP2_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_APB_EXP2_DEV_S; +#endif + +#ifdef PPC_SSE123_APB_EXP3_S +#include "ppc_sse123_drv.h" +extern struct ppc_sse123_dev_t PPC_SSE123_APB_EXP3_DEV_S; +#endif + +/* ARM MPC SIE 200 driver structures */ +#ifdef MPC_ISRAM0_S +#include "mpc_sie200_drv.h" +extern struct mpc_sie200_dev_t MPC_ISRAM0_DEV_S; +#endif + +#ifdef MPC_SSRAM1_S +#include "mpc_sie200_drv.h" +extern struct mpc_sie200_dev_t MPC_SSRAM1_DEV_S; +#endif + +#ifdef MPC_SSRAM2_S +#include "mpc_sie200_drv.h" +extern struct mpc_sie200_dev_t MPC_SSRAM2_DEV_S; +#endif + +#ifdef MPC_SSRAM3_S +#include "mpc_sie200_drv.h" +extern struct mpc_sie200_dev_t MPC_SSRAM3_DEV_S; +#endif + +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S +#include "syscounter_armv8-m_cntrl_drv.h" +extern struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS; +#endif + +#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 + +#endif /* __DEVICE_DEFINITION_H__ */ diff --git a/platform/ext/target/mps2/an539/device/include/platform_base_address.h b/platform/ext/target/mps2/an539/device/include/platform_base_address.h new file mode 100644 index 0000000000..b69145717f --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/platform_base_address.h @@ -0,0 +1,141 @@ +/* + * 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 platform_base_address.h + * \brief This file defines all the peripheral base addresses for MPS2 SSE-123 + * AN539 platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H_ +#define __PLATFORM_BASE_ADDRESS_H_ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ZBT_SRAM1_BASE_NS 0x00000000 /* ZBT SRAM1 Non-Secure base address */ +#define ZBT_SRAM2_BASE_NS 0x28000000 /* ZBT SRAM2 Non-Secure base address */ +#define ZBT_SRAM3_BASE_NS 0x28200000 /* ZBT SRAM3 Non-Secure base address */ +#define SYSTEM_TIMER0_BASE_NS 0x40000000 /* System Timer 0 Non-Secure base address */ +#define SYSTEM_TIMER1_BASE_NS 0x40001000 /* System Timer 1 Non-Secure base address */ +#define SSE123_SYSINFO_BASE_NS 0x40020000 /* SSE-123 System info Block Non-Secure base address */ +#define SSE123_NSPCTRL_BASE_NS 0x40080000 /* SSE-123 Non-Secure Priviledge Control Block Non-Secure base address */ +#define SYSTEM_WATCHDOG_BASE_NS 0x40081000 /* System Watchdog Non-Secure base address */ +#define CRYPTOCELL_APBS_BASE_NS 0x40088000 /* CryptoCell APBS I/F Non-Secure base address */ +#define CPU_IO_BASE_NS 0x400F0000 /* CPU IO Non-Secure base address */ +#define GPIO0_BASE_NS 0x40100000 /* GPIO0 Non-Secure base address */ +#define GPIO1_BASE_NS 0x40101000 /* GPIO1 Non-Secure base address */ +#define GPIO2_BASE_NS 0x40102000 /* GPIO2 Non-Secure base address */ +#define GPIO3_BASE_NS 0x40103000 /* GPIO3 Non-Secure base address */ +#define DMA0_PL081_BASE_NS 0x40110000 /* DMA0 PL081 Non-Secure base address */ +#define DMA1_PL081_BASE_NS 0x40111000 /* DMA1 PL081 Non-Secure base address */ +#define UART0_BASE_NS 0x40200000 /* UART0 (J10) Non-Secure base address */ +#define UART1_BASE_NS 0x40201000 /* UART1 (XBEE) Non-Secure base address */ +#define UART2_BASE_NS 0x40202000 /* UART2 (Reserved) Non-Secure base address */ +#define UART3_BASE_NS 0x40203000 /* UART3 (Shield 0) Non-Secure base address */ +#define UART4_BASE_NS 0x40204000 /* UART4 (Shield 1) Non-Secure base address */ +#define SPI0_PL022_BASE_NS 0x40205000 /* SPI0 PL022 (J21) Non-Secure base address */ +#define SPI1_PL022_BASE_NS 0x40206000 /* SPI2 PL022 (CLCD) Non-Secure base address */ +#define I2C0_SBCON_BASE_NS 0x40207000 /* I2C0 (Touchscreen) Non-Secure Base Address */ +#define I2C1_SBCON_BASE_NS 0x40208000 /* I2C1 (Audio) Non-Secure base address */ +#define SPI2_PL022_BASE_NS 0x40209000 /* SPI2 PL022 (ADC) Non-Secure base address */ +#define SPI3_PL022_BASE_NS 0x4020A000 /* SPI3 PL022 (Shield 0) Non-Secure base address */ +#define SPI4_PL022_BASE_NS 0x4020B000 /* SPI4 PL022 (Shield 1) Non-Secure base address */ +#define I2C2_SBCON_BASE_NS 0x4020C000 /* I2C2 (Shield 0) Non-Secure base address */ +#define I2C3_SBCON_BASE_NS 0x4020D000 /* I2C3 (Shield 1) Non-Secure base address */ +#define MPS2_IO_SCC_BASE_NS 0x40300000 /* MPS2 SCC IO Non-Secure base address */ +#define I2S_FPGA_BASE_NS 0x40301000 /* MPS2 FPGA I2S Non-Secure base address */ +#define MPS2_IO_FPGAIO_BASE_NS 0x40302000 /* MPS2 FPGA IO Non-Secure base address */ +#define VGA_CONSOLE_BASE_NS 0x41000000 /* VGA Console Non-Secure base address */ +#define VGA_IMAGE_BASE_NS 0x41100000 /* VGA Image Non-Secure base address */ +#define ETH_SMSC9220_BASE_NS 0x42000000 /* Ethernet SMSC 9220 Non-Secure base address */ +#define FPGA_NSPCTRL_BASE_NS 0x48007000 /* FPGA Non-Secure Priviledge Control Block Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48104000 /* System Counter Read Non-Secure base address */ +#define PSRAM_BASE_NS 0x80000000 /* Parallel SRAM Non-Secure base address */ + +/* Secure memory map addresses */ +#define ZBT_SRAM1_BASE_S 0x10000000 /* ZBT SRAM1 Secure base address */ +#define ZBT_SRAM2_BASE_S 0x38000000 /* ZBT SRAM2 Secure base address */ +#define ZBT_SRAM3_BASE_S 0x38200000 /* ZBT SRAM3 Secure base address */ +#define SYSTEM_TIMER0_BASE_S 0x50000000 /* System Timer 0 Secure base address */ +#define SYSTEM_TIMER1_BASE_S 0x50001000 /* System Timer 1 Secure base address */ +#define SSE123_SYSINFO_BASE_S 0x50020000 /* SSE-123 System info Block Secure base address */ +#define SSE123_SYSCTRL_BASE_S 0x50021000 /* SSE-123 System control Block Secure base address */ +#define SSE123_SYSPPU_BASE_S 0x50022000 /* SSE-123 System Power Policy Unit Secure base address */ +#define SSE123_SPCTRL_BASE_S 0x50080000 /* SSE-123 Secure Priviledge Control Block Secure base address */ +#define SYSTEM_WATCHDOG_BASE_S 0x50081000 /* System Watchdog Secure base address */ +#define MPC_ISRAM_BASE_S 0x50083000 /* Internal SRAM MPC Secure base address */ +#define CRYPTOCELL_APBS_BASE_S 0x50088000 /* CryptoCell APBS I/F Secure base address */ +#define CPU_IO_BASE_S 0x500F0000 /* CPU IO Secure base address */ +#define GPIO0_BASE_S 0x50100000 /* GPIO0 Secure base address */ +#define GPIO1_BASE_S 0x50101000 /* GPIO1 Secure base address */ +#define GPIO2_BASE_S 0x50102000 /* GPIO2 Secure base address */ +#define GPIO3_BASE_S 0x50103000 /* GPIO3 Secure base address */ +#define DMA0_PL081_BASE_S 0x50110000 /* DMA0 PL081 Secure base address */ +#define DMA1_PL081_BASE_S 0x50111000 /* DMA1 PL081 Secure base address */ +#define UART0_BASE_S 0x50200000 /* UART0 (J10) Secure base address */ +#define UART1_BASE_S 0x50201000 /* UART1 (XBEE) Secure base address */ +#define UART2_BASE_S 0x50202000 /* UART2 (Reserved) Secure base address */ +#define UART3_BASE_S 0x50203000 /* UART3 (Shield 0) Secure base address */ +#define UART4_BASE_S 0x50204000 /* UART4 (Shield 1) Secure base address */ +#define SPI0_PL022_BASE_S 0x50205000 /* SPI0 PL022 (J21) Secure base address */ +#define SPI1_PL022_BASE_S 0x50206000 /* SPI2 PL022 (CLCD) Secure base address */ +#define I2C0_SBCON_BASE_S 0x50207000 /* I2C0 (Touchscreen) Secure Base Address */ +#define I2C1_SBCON_BASE_S 0x50208000 /* I2C1 (Audio) -Secure base address */ +#define SPI2_PL022_BASE_S 0x50209000 /* SPI2 PL022 (ADC) Secure base address */ +#define SPI3_PL022_BASE_S 0x5020A000 /* SPI3 PL022 (Shield 0) Secure base address */ +#define SPI4_PL022_BASE_S 0x5020B000 /* SPI4 PL022 (Shield 1) Secure base address */ +#define I2C2_SBCON_BASE_S 0x5020C000 /* I2C2 (Shield 0) Secure base address */ +#define I2C3_SBCON_BASE_S 0x5020D000 /* I2C3 (Shield 1) Secure base address */ +#define MPS2_IO_SCC_BASE_S 0x50300000 /* MPS2 SCC IO Secure base address */ +#define I2S_FPGA_BASE_S 0x50301000 /* MPS2 FPGA I2S Secure base address */ +#define MPS2_IO_FPGAIO_BASE_S 0x50302000 /* MPS2 FPGA IO Secure base address */ +#define VGA_CONSOLE_BASE_S 0x51000000 /* VGA Console Non-Secure base address */ +#define VGA_IMAGE_BASE_S 0x51100000 /* VGA Image Non-Secure base address */ +#define ETH_SMSC9220_BASE_S 0x52000000 /* Ethernet SMSC 9220 Secure base address */ +#define MPC_SSRAM1_BASE_S 0x58100000 /* SSRAM1 MPC Secure base address */ +#define MPC_SSRAM2_BASE_S 0x58008000 /* SSRAM2 MPC Secure base address */ +#define MPC_SSRAM3_BASE_S 0x58009000 /* SSRAM3 MPC Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58104000 /* System Counter Read Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58105000 /* System Counter Control Secure base address */ + +/* Internal SRAM memory */ +/* Internal SRAM - 64 KiB */ +#define MPC_ISRAM0_RANGE_BASE_NS 0x20000000 +#define MPC_ISRAM0_RANGE_LIMIT_NS 0x2000FFFF +#define MPC_ISRAM0_RANGE_BASE_S 0x30000000 +#define MPC_ISRAM0_RANGE_LIMIT_S 0x3000FFFF + +/* External SSRAM memory */ +/* SSRAM1 - 4 MiB */ +#define MPC_SSRAM1_RANGE_BASE_NS 0x00000000 +#define MPC_SSRAM1_RANGE_LIMIT_NS 0x003FFFFF +#define MPC_SSRAM1_RANGE_BASE_S 0x10000000 +#define MPC_SSRAM1_RANGE_LIMIT_S 0x103FFFFF + +/* SSRAM2 - 2 MiB */ +#define MPC_SSRAM2_RANGE_BASE_NS 0x28000000 +#define MPC_SSRAM2_RANGE_LIMIT_NS 0x281FFFFF +#define MPC_SSRAM2_RANGE_BASE_S 0x38000000 +#define MPC_SSRAM2_RANGE_LIMIT_S 0x381FFFFF + +/* SSRAM3 - 2 MiB */ +#define MPC_SSRAM3_RANGE_BASE_NS 0x28200000 +#define MPC_SSRAM3_RANGE_LIMIT_NS 0x283FFFFF +#define MPC_SSRAM3_RANGE_BASE_S 0x38200000 +#define MPC_SSRAM3_RANGE_LIMIT_S 0x383FFFFF + + +#endif /* __PLATFORM_BASE_ADDRESS_H_ */ diff --git a/platform/ext/target/mps2/an539/device/include/platform_description.h b/platform/ext/target/mps2/an539/device/include/platform_description.h new file mode 100644 index 0000000000..ffb8459d20 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/platform_description.h @@ -0,0 +1,26 @@ +/* + * 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. + */ + +#ifndef __PLATFORM_DESCRIPTION_H__ +#define __PLATFORM_DESCRIPTION_H__ + +#include "cmsis.h" +#include "platform_base_address.h" +#include "platform_pins.h" +#include "platform_regs.h" +#include "system_core_init.h" + +#endif /* __PLATFORM_DESCRIPTION_H__ */ diff --git a/platform/ext/target/mps2/an539/device/include/platform_irq.h b/platform/ext/target/mps2/an539/device/include/platform_irq.h new file mode 100644 index 0000000000..ed25651032 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/platform_irq.h @@ -0,0 +1,140 @@ +/* + * 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. + */ + +#ifndef __PLATFORM_IRQN_H__ +#define __PLATFORM_IRQN_H__ + +typedef enum _IRQn_Type { + NonMaskableInt_IRQn = -14, /* Non Maskable Interrupt */ + HardFault_IRQn = -13, /* HardFault Interrupt */ + SVCall_IRQn = -5, /* SV Call 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 */ + /* Reserved = 2, Reserved */ + TIMER0_IRQn = 3, /* TIMER 0 Interrupt */ + TIMER1_IRQn = 4, /* TIMER 1 Interrupt */ + /* Reserved = 5, Reserved */ + CTI_REQ0_IRQn = 6, /* CTI request 0 */ + CTI_REQ1_IRQn = 7, /* CTI request 1 */ + /* Reserved = 8, 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 */ + /* Reserved = 14, Reserved */ + PD_SYS_PPU_IRQn = 15, /* PD SYS PPU */ + /* Reserved = 31:16 Reserved */ + 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 */ + UARTRX3_IRQn = 38, /* UART 3 RX Interrupt */ + UARTTX3_IRQn = 39, /* UART 3 TX Interrupt */ + UARTRX4_IRQn = 40, /* UART 4 RX Interrupt */ + UARTTX4_IRQn = 41, /* UART 4 TX Interrupt */ + UART0_IRQn = 42, /* UART 0 combined Interrupt */ + UART1_IRQn = 43, /* UART 1 combined Interrupt */ + UART2_IRQn = 44, /* UART 2 combined Interrupt */ + UART3_IRQn = 45, /* UART 3 combined Interrupt */ + UART4_IRQn = 46, /* UART 4 combined Interrupt */ + UARTOVF_IRQn = 47, /* UART Overflow Interrupt */ + ETHERNET_IRQn = 48, /* Ethernet Interrupt */ + I2S_IRQn = 49, /* I2S Interrupt */ + TSC_IRQn = 50, /* Touch Screen Interrupt */ + SPI0_IRQn = 51, /* SPI 0 Interrupt */ + SPI1_IRQn = 52, /* SPI 1 Interrupt */ + SPI2_IRQn = 53, /* SPI 2 Interrupt */ + SPI3_IRQn = 54, /* SPI 3 Interrupt */ + SPI4_IRQn = 55, /* SPI 4 Interrupt */ + 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 */ + GPIO0_0_IRQn = 72, /* GPIO0 has 16 pins */ + GPIO0_1_IRQn = 73, + GPIO0_2_IRQn = 74, + GPIO0_3_IRQn = 75, + GPIO0_4_IRQn = 76, + GPIO0_5_IRQn = 77, + GPIO0_6_IRQn = 78, + GPIO0_7_IRQn = 79, + GPIO0_8_IRQn = 80, + GPIO0_9_IRQn = 81, + GPIO0_10_IRQn = 82, + GPIO0_11_IRQn = 83, + GPIO0_12_IRQn = 84, + GPIO0_13_IRQn = 85, + GPIO0_14_IRQn = 86, + GPIO0_15_IRQn = 87, + GPIO1_0_IRQn = 88, /* GPIO1 has 16 pins */ + GPIO1_1_IRQn = 89, + GPIO1_2_IRQn = 90, + GPIO1_3_IRQn = 91, + GPIO1_4_IRQn = 92, + GPIO1_5_IRQn = 93, + GPIO1_6_IRQn = 94, + GPIO1_7_IRQn = 95, + GPIO1_8_IRQn = 96, + GPIO1_9_IRQn = 97, + GPIO1_10_IRQn = 98, + GPIO1_11_IRQn = 99, + GPIO1_12_IRQn = 100, + GPIO1_13_IRQn = 101, + GPIO1_14_IRQn = 102, + GPIO1_15_IRQn = 103, + GPIO2_0_IRQn = 104, /* GPIO2 has 16 pins */ + GPIO2_1_IRQn = 105, + GPIO2_2_IRQn = 106, + GPIO2_3_IRQn = 107, + GPIO2_4_IRQn = 108, + GPIO2_5_IRQn = 109, + GPIO2_6_IRQn = 110, + GPIO2_7_IRQn = 111, + GPIO2_8_IRQn = 112, + GPIO2_9_IRQn = 113, + GPIO2_10_IRQn = 114, + GPIO2_11_IRQn = 115, + GPIO2_12_IRQn = 116, + GPIO2_13_IRQn = 117, + GPIO2_14_IRQn = 118, + GPIO2_15_IRQn = 119, + GPIO3_0_IRQn = 120, /* GPIO3 has 4 pins */ + GPIO3_1_IRQn = 121, + GPIO3_2_IRQn = 122, + GPIO3_3_IRQn = 123, +}IRQn_Type; + +#endif /* __PLATFORM_IRQN_H__ */ diff --git a/platform/ext/target/mps2/an539/device/include/platform_pins.h b/platform/ext/target/mps2/an539/device/include/platform_pins.h new file mode 100644 index 0000000000..649d9a781b --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/platform_pins.h @@ -0,0 +1,112 @@ +/* + * 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 platform_pins.h + * \brief This file defines all the pins for this platform. + */ + +#ifndef __PLATFORM_PINS_H__ +#define __PLATFORM_PINS_H__ + +/* AHB GPIO pin names */ +enum gpio_pin_name_t { + AHB_GPIO0_0 = 0U, + AHB_GPIO0_1 = 1U, + AHB_GPIO0_2 = 2U, + AHB_GPIO0_3 = 3U, + AHB_GPIO0_4 = 4U, + AHB_GPIO0_5 = 5U, + AHB_GPIO0_6 = 6U, + AHB_GPIO0_7 = 7U, + AHB_GPIO0_8 = 8U, + AHB_GPIO0_9 = 9U, + AHB_GPIO0_10 = 10U, + AHB_GPIO0_11 = 11U, + AHB_GPIO0_12 = 12U, + AHB_GPIO0_13 = 13U, + AHB_GPIO0_14 = 14U, + AHB_GPIO0_15 = 15U, + AHB_GPIO1_0 = 0U, + AHB_GPIO1_1 = 1U, + AHB_GPIO1_2 = 2U, + AHB_GPIO1_3 = 3U, + AHB_GPIO1_4 = 4U, + AHB_GPIO1_5 = 5U, + AHB_GPIO1_6 = 6U, + AHB_GPIO1_7 = 7U, + AHB_GPIO1_8 = 8U, + AHB_GPIO1_9 = 9U, + AHB_GPIO1_10 = 10U, + AHB_GPIO1_11 = 11U, + AHB_GPIO1_12 = 12U, + AHB_GPIO1_13 = 13U, + AHB_GPIO1_14 = 14U, + AHB_GPIO1_15 = 15U, + AHB_GPIO2_0 = 0U, + AHB_GPIO2_1 = 1U, + AHB_GPIO2_2 = 2U, + AHB_GPIO2_3 = 3U, + AHB_GPIO2_4 = 4U, + AHB_GPIO2_5 = 5U, + AHB_GPIO2_6 = 6U, + AHB_GPIO2_7 = 7U, + AHB_GPIO2_8 = 8U, + AHB_GPIO2_9 = 9U, + AHB_GPIO2_10 = 10U, + AHB_GPIO2_11 = 11U, + AHB_GPIO2_12 = 12U, + AHB_GPIO2_13 = 13U, + AHB_GPIO2_14 = 14U, + AHB_GPIO2_15 = 15U, + AHB_GPIO3_0 = 0U, + AHB_GPIO3_1 = 1U, + AHB_GPIO3_2 = 2U, + AHB_GPIO3_3 = 3U, +}; + +/* User Buttons */ +#define USER_BUTTON0 AHB_GPIO1_5 +#define USER_BUTTON1 AHB_GPIO1_6 + +/* GPIO shield 0 definition */ +#define SH0_UART_RX AHB_GPIO0_0 +#define SH0_UART_TX AHB_GPIO0_4 +#define SH0_I2C_SCL AHB_GPIO0_5 +#define SH0_I2C_SDA AHB_GPIO0_15 +#define SH0_SPI_SCK AHB_GPIO0_11 +#define SH0_SPI_SS AHB_GPIO0_12 +#define SH0_SPI_MOSI AHB_GPIO0_13 +#define SH0_SPI_MISO AHB_GPIO0_14 + +/* GPIO shield 1 definition */ +#define SH1_UART_RX AHB_GPIO1_10 +#define SH1_UART_TX AHB_GPIO1_14 +#define SH1_I2C_SCL AHB_GPIO1_15 +#define SH1_I2C_SDA AHB_GPIO2_9 +#define SH1_SPI_SS AHB_GPIO2_6 +#define SH1_SPI_MOSI AHB_GPIO2_7 +#define SH1_SPI_MISO AHB_GPIO2_8 +#define SH1_SPI_SCK AHB_GPIO2_12 + +/* GPIO ADC SPI */ +#define ADC_SPI_SS AHB_GPIO1_0 +#define ADC_SPI_MOSI AHB_GPIO1_1 +#define ADC_SPI_MISO AHB_GPIO1_2 +#define ADC_SPI_SCK AHB_GPIO1_3 + + +#endif /* __PLATFORM_PINS_H__ */ diff --git a/platform/ext/target/mps2/an539/device/include/platform_regs.h b/platform/ext/target/mps2/an539/device/include/platform_regs.h new file mode 100644 index 0000000000..64c1c6d428 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/platform_regs.h @@ -0,0 +1,265 @@ +/* + * 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. + */ + +#ifndef __PLATFORM_REGS_H__ +#define __PLATFORM_REGS_H__ + +#include <stdint.h> + +/* System info memory mapped register access structure */ +struct sse123_sysinfo_t { + volatile uint32_t sys_version; /* 0x000 (R/ ) System version */ + volatile uint32_t sys_config; /* 0x004 (R/ ) System configuration */ + volatile uint32_t reserved0[1010]; + 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 */ +}; + +/* System control memory mapped register access structure */ +struct sse123_sysctrl_t { + volatile uint32_t secdbgstat; /* 0x000 (R/ ) Secure Debug Configuration + * Status Register */ + volatile uint32_t secdbgset; /* 0x004 ( /W) Secure Debug Configuration + * Set Register */ + volatile uint32_t secdbgclr; /* 0x008 ( /W) Secure Debug Configuration + * Clear Register */ + volatile uint32_t scsecctrl; /* 0x00C (R/W) System Control Security + * Control Register */ + volatile uint32_t reserved0[2]; + volatile uint32_t clock_ctrl; /* 0x018 (R/W) Clock Control */ + volatile uint32_t reserved1[57]; + volatile uint32_t resetsyndrome; /* 0x100 (R/W) Reset syndrome */ + volatile uint32_t resetmask; /* 0x104 (R/W) Reset MASK */ + volatile uint32_t swreset; /* 0x108 ( /W) Software Reset */ + volatile uint32_t gretreg; /* 0x10C (R/W) General Purpose Retention + * Register */ + volatile uint32_t initsvtor; /* 0x110 (R/W) Initial Secure Reset Vector + * Register For CPU */ + volatile uint32_t reserved2; + volatile uint32_t cpuwait; /* 0x118 (R/W) CPU Boot wait control + * after reset */ + volatile uint32_t nmi_enable; /* 0x11C (R/W) NMI Enable Register */ + volatile uint32_t reserved3; + volatile uint32_t wicbrgctrl; /* 0x124 (R/W) WIC-Bridge Control */ + volatile uint32_t reserved4[938]; + 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 */ + +}; + +/* SPCTRL memory mapped register access structure */ +struct sse123_spctrl_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 reserved1[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 reserved2; + 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 ( /W) Secure PPC IRQ Clear. */ + volatile uint32_t secppcinten; /* 0x028 (R/W) Secure PPC IRQ Enable. */ + volatile uint32_t reserved3; + volatile uint32_t secmscintstat; /* 0x030 (R/ ) Secure MSC IRQ Status. */ + volatile uint32_t secmscintclr; /* 0x034 ( /W) Secure MSC IRQ Clear. */ + volatile uint32_t secmscinten; /* 0x038 (R/W) Secure MSC IRQ Enable. */ + volatile uint32_t reserved4; + volatile uint32_t brgintstat; /* 0x040 (R/ ) Bridge Buffer Error IRQ + * Status */ + volatile uint32_t brgintclr; /* 0x044 ( /W) Bridge Buffer Error IRQ + * Clear */ + volatile uint32_t brginten; /* 0x048 (R/W) Bridge Buffer Error IRQ + * Enable */ + volatile uint32_t reserved5[5]; + volatile uint32_t ahbnsppcexp; /* 0x060 (R/W) Expansion Non-Secure + Access AHB slave Peripheral + Protection Control */ + volatile uint32_t reserved6[3]; + volatile uint32_t apbnsppc; /* 0x070 (R/W) Non-secure Access APB + slave Peripheral Protection + Control */ + volatile uint32_t reserved7[3]; + volatile uint32_t apbnsppcexp0; /* 0x080 (R/W) Expansion 0 NS Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnsppcexp1; /* 0x084 (R/W) Expansion 1 NS Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnsppcexp2; /* 0x088 (R/W) Expansion 2 NS Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnsppcexp3; /* 0x08C (R/W) Expansion 3 NS Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t reserved8[4]; + volatile uint32_t ahbspppcexp; /* 0x0A0 (R/W) Expansion Secure + * Unprivileged Access AHB + * slave Peripheral Protection + * Control */ + volatile uint32_t reserved9[3]; + volatile uint32_t apbspppc; /* 0x0B0 (R/W) Secure Unprivileged Access + * APB slave Peripheral + * Protection Control */ + volatile uint32_t reserved10[3]; + volatile uint32_t apbspppcexp0; /* 0x0C0 (R/W) Expansion 0 Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbspppcexp1; /* 0x0C4 (R/W) Expansion 1 Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbspppcexp2; /* 0x0C8 (R/W) Expansion 2 Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbspppcexp3; /* 0x0CC (R/W) Expansion 3 Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t nsmscexp; /* 0x0D0 (R/W) Expansion MSC Non-Secure + * Configuration */ + volatile uint32_t reserved11[959]; + volatile uint32_t pid4; /* 0xFD0 (R/W) Peripheral ID 4 */ + volatile uint32_t reserved12[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 APB_PPC0_INT_POS_MASK (1UL << 0) +#define APB_PPCEXP0_INT_POS_MASK (1UL << 4) +#define APB_PPCEXP1_INT_POS_MASK (1UL << 5) +#define APB_PPCEXP2_INT_POS_MASK (1UL << 6) +#define APB_PPCEXP3_INT_POS_MASK (1UL << 7) +#define AHB_PPCEXP0_INT_POS_MASK (1UL << 20) + + +/* NSPCTRL memory mapped register access structure */ +struct sse123_nspctrl_t { + volatile uint32_t reserved1[40]; + volatile uint32_t ahbnspppcexp; /* 0x0A0 (R/W) Expansion Non-Secure + * Unprivileged Access AHB + * slave Peripheral Protection + * Control */ + volatile uint32_t reserved2[3]; + volatile uint32_t apbnspppc; /* 0x0B0 (R/W) Non-secure Unprivileged + * Access APB slave Peripheral + * Protection Control */ + volatile uint32_t reserved3[3]; + volatile uint32_t apbnspppcexp0; /* 0x0C0 (R/W) Expansion 0 Non-Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnspppcexp1; /* 0x0C4 (R/W) Expansion 1 Non-Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnspppcexp2; /* 0x0C8 (R/W) Expansion 2 Non-Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t apbnspppcexp3; /* 0x0CC (R/W) Expansion 3 Non-Secure + * Unprivileged Access APB + * slave Peripheral Protection + * Control */ + volatile uint32_t reserved4[960]; + volatile uint32_t pid4; /* 0xFD0 (R/W) 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 */ +}; + +/* APB PPC peripherals definition */ +#define SYSTEM_TIMER0_APB_PPC_POS 0U +#define SYSTEM_TIMER1_APB_PPC_POS 1U +#define SYSTEM_WATCHDOG_APB_PPC_POS 6U +/* End APB PPC peripherals definition */ + +/* ARM APB PPCEXP0 peripherals definition */ +/* End ARM APB PPCEXP0 peripherals definition */ + +/* APB PPCEXP1 peripherals definition */ +#define SSRAM2_MPC_APB_PPCEXP1_POS 1U +#define SSRAM3_MPC_APB_PPCEXP1_POS 2U +/* End APB PPCEXP1 peripherals definition */ + +/* APB PPCEXP2 peripherals definition */ +#define SPI0_APB_PPCEXP2_POS 0U +#define SPI1_APB_PPCEXP2_POS 1U +#define SPI2_APB_PPCEXP2_POS 2U +#define SPI3_APB_PPCEXP2_POS 3U +#define SPI4_APB_PPCEXP2_POS 4U +#define UART0_APB_PPCEXP2_POS 5U +#define UART1_APB_PPCEXP2_POS 6U +#define UART2_APB_PPCEXP2_POS 7U +#define UART3_APB_PPCEXP2_POS 8U +#define UART4_APB_PPCEXP2_POS 9U +#define I2C0_APB_PPCEXP2_POS 10U +#define I2C1_APB_PPCEXP2_POS 11U +#define I2C2_APB_PPCEXP2_POS 12U +#define I2C3_APB_PPCEXP2_POS 13U +/* End APB PPCEXP2 peripherals definition */ + +/* APB PPCEXP3 peripherals definition */ +#define FPGA_SCC_APB_PPCEXP3_POS 0U +#define FPGA_AUDIO_APB_PPCEXP3_POS 1U +#define FPGA_IO_APB_PPCEXP3_POS 2U +/* End APB PPCEXP3 peripherals definition */ + +/* AHB PPCEXP peripherals definition */ +#define VGA_AHB_PPCEXP_POS 0U +#define GPIO0_AHB_PPCEXP_POS 1U +#define GPIO1_AHB_PPCEXP_POS 2U +#define GPIO2_AHB_PPCEXP_POS 3U +#define GPIO3_AHB_PPCEXP_POS 4U +#define PSRAM_ETH_AHB_PPCEXP_POS 5U +#define DMA0_AHB_PPCEXP_POS 8U +#define DMA1_AHB_PPCEXP_POS 9U +/* End AHB PPCEXP peripherals definition */ + +#endif /* __PLATFORM_REGS_H__ */ diff --git a/platform/ext/target/mps2/an539/device/include/system_core_init.h b/platform/ext/target/mps2/an539/device/include/system_core_init.h new file mode 100644 index 0000000000..ce3e5cd409 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/include/system_core_init.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009-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. + */ + +/* + * This file is derivative of CMSIS V5.00 system_ARMCM23.c + */ + +#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/an539/device/source/armclang/an539_mps2_bl2.sct b/platform/ext/target/mps2/an539/device/source/armclang/an539_mps2_bl2.sct new file mode 100644 index 0000000000..c133c85c28 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/armclang/an539_mps2_bl2.sct @@ -0,0 +1,40 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8-m.base -E -xc + +/* + * Copyright (c) 2017-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 "region_defs.h" + +LR_CODE BL2_CODE_START { + ER_CODE BL2_CODE_START BL2_CODE_SIZE { + *.o (RESET +First) + * (+RO) + } + + TFM_SHARED_DATA BL2_DATA_START ALIGN 32 EMPTY BOOT_TFM_SHARED_DATA_SIZE { + } + + ER_DATA +0 BL2_DATA_SIZE { + * (+ZI +RW) + } + + /* MSP */ + ARM_LIB_STACK +0 ALIGN 32 EMPTY BL2_MSP_STACK_SIZE { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY BL2_HEAP_SIZE { + } +} diff --git a/platform/ext/target/mps2/an539/device/source/armclang/an539_mps2_ns.sct b/platform/ext/target/mps2/an539/device/source/armclang/an539_mps2_ns.sct new file mode 100644 index 0000000000..6e32d1210b --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/armclang/an539_mps2_ns.sct @@ -0,0 +1,41 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8-m.base -E -xc + +/* + * Copyright (c) 2017-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 "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 NS_DATA_SIZE { + * (+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 { + } +} diff --git a/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_bl2.s b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_bl2.s new file mode 100644 index 0000000000..de8fb6c526 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_bl2.s @@ -0,0 +1,320 @@ +;/* +; * Copyright (c) 2016-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. +; */ +; +; This file is derivative of CMSIS V5.00 startup_ARMv8MML.s + + +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; Core IoT Interrupts + DCD NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + DCD NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + DCD 0 ; - 2 Reserved + DCD TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 IRQ Handler + DCD TIMER1_Handler ; - 4 TIMER 1 IRQ Handler + DCD 0 ; - 5 Reserved + DCD CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + DCD CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + DCD 0 ; 8 Reserved + DCD MPC_Handler ; - 9 MPC Combined (Secure) Handler + DCD PPC_Handler ; - 10 PPC Combined (Secure) Handler + DCD MSC_Handler ; - 11 MSC Combined (Secure) Handler + DCD BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + DCD 0 ; - 13 Reserved + DCD 0 ; 14 Reserved + DCD PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + DCD 0 ; - 16 Reserved + DCD 0 ; - 17 Reserved + DCD 0 ; - 18 Reserved + DCD 0 ; - 19 Reserved + DCD 0 ; - 20 Reserved + DCD 0 ; - 21 Reserved + DCD 0 ; - 22 Reserved + DCD 0 ; - 23 Reserved + DCD 0 ; - 24 Reserved + DCD 0 ; - 25 Reserved + DCD 0 ; - 26 Reserved + DCD 0 ; - 27 Reserved + DCD 0 ; - 28 Reserved + DCD 0 ; - 29 Reserved + DCD 0 ; - 30 Reserved + DCD 0 ; - 31 Reserved + ; External Interrupts + DCD UARTRX0_Handler ; 32 UART 0 RX Handler + DCD UARTTX0_Handler ; 33 UART 0 TX Handler + DCD UARTRX1_Handler ; 34 UART 1 RX Handler + DCD UARTTX1_Handler ; 35 UART 1 TX Handler + DCD UARTRX2_Handler ; 36 UART 2 RX Handler + DCD UARTTX2_Handler ; 37 UART 2 TX Handler + DCD UARTRX3_Handler ; 38 UART 3 RX Handler + DCD UARTTX3_Handler ; 39 UART 3 TX Handler + DCD UARTRX4_Handler ; 40 UART 4 RX Handler + DCD UARTTX4_Handler ; 41 UART 4 TX Handler + DCD UART0_Handler ; 42 UART 0 combined Handler + DCD UART1_Handler ; 43 UART 1 combined Handler + DCD UART2_Handler ; 44 UART 2 combined Handler + DCD UART3_Handler ; 45 UART 3 combined Handler + DCD UART4_Handler ; 46 UART 4 combined Handler + DCD UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + DCD ETHERNET_Handler ; 48 Ethernet Handler + DCD I2S_Handler ; 49 I2S Handler + DCD TSC_Handler ; 50 Touch Screen Handler + DCD SPI0_Handler ; 51 SPI 0 Handler + DCD SPI1_Handler ; 52 SPI 1 Handler + DCD SPI2_Handler ; 53 SPI 2 Handler + DCD SPI3_Handler ; 54 SPI 3 Handler + DCD SPI4_Handler ; 55 SPI 4 Handler + DCD DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + DCD DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + DCD DMA0_Handler ; 58 DMA 0 Combined Handler + DCD DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + DCD DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + DCD DMA1_Handler ; 61 DMA 1 Combined Handler + DCD DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + DCD DMA2_TC_Handler ; 63 DMA 2 Terminal Count Ha + DCD DMA2_Handler ; 64 DMA 2 Combined Handler + DCD DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + DCD DMA3_TC_Handler ; 66 DMA 3 Terminal Count Ha + DCD DMA3_Handler ; 67 DMA 3 Combined Handler + DCD GPIO0_Handler ; 68 GPIO 0 Comboned Handler + DCD GPIO1_Handler ; 69 GPIO 1 Comboned Handler + DCD GPIO2_Handler ; 70 GPIO 2 Comboned Handler + DCD GPIO3_Handler ; 71 GPIO 3 Comboned Handler + DCD GPIO0_0_Handler ; 72 /* There are 16 pins for GPIO 0 */ + DCD GPIO0_1_Handler ; 73 + DCD GPIO0_2_Handler ; 74 + DCD GPIO0_3_Handler ; 75 + DCD GPIO0_4_Handler ; 76 + DCD GPIO0_5_Handler ; 77 + DCD GPIO0_6_Handler ; 78 + DCD GPIO0_7_Handler ; 79 + DCD GPIO0_8_Handler ; 80 + DCD GPIO0_9_Handler ; 81 + DCD GPIO0_10_Handler ; 82 + DCD GPIO0_11_Handler ; 83 + DCD GPIO0_12_Handler ; 84 + DCD GPIO0_13_Handler ; 85 + DCD GPIO0_14_Handler ; 86 + DCD GPIO0_15_Handler ; 87 + DCD GPIO1_0_Handler ; 88 /* There are 16 pins for GPIO 1 */ + DCD GPIO1_1_Handler ; 89 + DCD GPIO1_2_Handler ; 90 + DCD GPIO1_3_Handler ; 91 + DCD GPIO1_4_Handler ; 92 + DCD GPIO1_5_Handler ; 93 + DCD GPIO1_6_Handler ; 94 + DCD GPIO1_7_Handler ; 95 + DCD GPIO1_8_Handler ; 96 + DCD GPIO1_9_Handler ; 97 + DCD GPIO1_10_Handler ; 98 + DCD GPIO1_11_Handler ; 99 + DCD GPIO1_12_Handler ; 100 + DCD GPIO1_13_Handler ; 101 + DCD GPIO1_14_Handler ; 102 + DCD GPIO1_15_Handler ; 103 + DCD GPIO2_0_Handler ; 104 /* There are 16 pins for GPIO 2 */ + DCD GPIO2_1_Handler ; 105 + DCD GPIO2_2_Handler ; 106 + DCD GPIO2_3_Handler ; 107 + DCD GPIO2_4_Handler ; 108 + DCD GPIO2_5_Handler ; 109 + DCD GPIO2_6_Handler ; 110 + DCD GPIO2_7_Handler ; 111 + DCD GPIO2_8_Handler ; 112 + DCD GPIO2_9_Handler ; 113 + DCD GPIO2_10_Handler ; 114 + DCD GPIO2_11_Handler ; 115 + DCD GPIO2_12_Handler ; 116 + DCD GPIO2_13_Handler ; 117 + DCD GPIO2_14_Handler ; 118 + DCD GPIO2_15_Handler ; 119 + DCD GPIO3_0_Handler ; 120 /* There are 4 pins for GPIO 4 */ + DCD GPIO3_1_Handler ; 121 + DCD GPIO3_2_Handler ; 122 + DCD GPIO3_3_Handler ; 123 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + MACRO + Default_Handler $handler_name +$handler_name PROC + EXPORT $handler_name [WEAK] + B . + ENDP + MEND + + Default_Handler NMI_Handler + Default_Handler HardFault_Handler + Default_Handler SVC_Handler + Default_Handler PendSV_Handler + Default_Handler SysTick_Handler + +; Core IoT Interrupts + Default_Handler NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + Default_Handler NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + Default_Handler TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler + Default_Handler TIMER1_Handler ; - 4 TIMER 1 Handler + Default_Handler CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + Default_Handler CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + Default_Handler MPC_Handler ; - 9 MPC Combined (Secure) Handler + Default_Handler PPC_Handler ; - 10 PPC Combined (Secure) Handler + Default_Handler MSC_Handler ; - 11 MSC Combined (Secure) Handler + Default_Handler BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + Default_Handler PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + ; External Interrupts + Default_Handler UARTRX0_Handler ; 32 UART 0 RX Handler + Default_Handler UARTTX0_Handler ; 33 UART 0 TX Handler + Default_Handler UARTRX1_Handler ; 34 UART 1 RX Handler + Default_Handler UARTTX1_Handler ; 35 UART 1 TX Handler + Default_Handler UARTRX2_Handler ; 36 UART 2 RX Handler + Default_Handler UARTTX2_Handler ; 37 UART 2 TX Handler + Default_Handler UARTRX3_Handler ; 38 UART 3 RX Handler + Default_Handler UARTTX3_Handler ; 39 UART 3 TX Handler + Default_Handler UARTRX4_Handler ; 40 UART 4 RX Handler + Default_Handler UARTTX4_Handler ; 41 UART 4 TX Handler + Default_Handler UART0_Handler ; 42 UART 0 combined Handler + Default_Handler UART1_Handler ; 43 UART 1 combined Handler + Default_Handler UART2_Handler ; 44 UART 2 combined Handler + Default_Handler UART3_Handler ; 45 UART 3 combined Handler + Default_Handler UART4_Handler ; 46 UART 4 combined Handler + Default_Handler UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + Default_Handler ETHERNET_Handler ; 48 Ethernet Handler + Default_Handler I2S_Handler ; 49 I2S Handler + Default_Handler TSC_Handler ; 50 Touch Screen Handler + Default_Handler SPI0_Handler ; 51 SPI 0 Handler + Default_Handler SPI1_Handler ; 52 SPI 1 Handler + Default_Handler SPI2_Handler ; 53 SPI 2 Handler + Default_Handler SPI3_Handler ; 54 SPI 3 Handler + Default_Handler SPI4_Handler ; 55 SPI 4 Handler + Default_Handler DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + Default_Handler DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + Default_Handler DMA0_Handler ; 58 DMA 0 Combined Handler + Default_Handler DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + Default_Handler DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + Default_Handler DMA1_Handler ; 61 DMA 1 Combined Handler + Default_Handler DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + Default_Handler DMA2_TC_Handler ; 63 DMA 2 Terminal Count Handler + Default_Handler DMA2_Handler ; 64 DMA 2 Combined Handler + Default_Handler DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + Default_Handler DMA3_TC_Handler ; 66 DMA 3 Terminal Count Handler + Default_Handler DMA3_Handler ; 67 DMA 3 Combined Handler + Default_Handler GPIO0_Handler ; 68 GPIO 0 Comboned Handler + Default_Handler GPIO1_Handler ; 69 GPIO 1 Comboned Handler + Default_Handler GPIO2_Handler ; 70 GPIO 2 Comboned Handler + Default_Handler GPIO3_Handler ; 71 GPIO 3 Comboned Handler + Default_Handler GPIO0_0_Handler ; 72 GPIO 0 has 16 individual Handlers + Default_Handler GPIO0_1_Handler ; 73 + Default_Handler GPIO0_2_Handler ; 74 + Default_Handler GPIO0_3_Handler ; 75 + Default_Handler GPIO0_4_Handler ; 76 + Default_Handler GPIO0_5_Handler ; 77 + Default_Handler GPIO0_6_Handler ; 78 + Default_Handler GPIO0_7_Handler ; 79 + Default_Handler GPIO0_8_Handler ; 80 + Default_Handler GPIO0_9_Handler ; 81 + Default_Handler GPIO0_10_Handler ; 82 + Default_Handler GPIO0_11_Handler ; 83 + Default_Handler GPIO0_12_Handler ; 84 + Default_Handler GPIO0_13_Handler ; 85 + Default_Handler GPIO0_14_Handler ; 86 + Default_Handler GPIO0_15_Handler ; 87 + Default_Handler GPIO1_0_Handler ; 88 GPIO 1 has 16 individual Handlers + Default_Handler GPIO1_1_Handler ; 89 + Default_Handler GPIO1_2_Handler ; 90 + Default_Handler GPIO1_3_Handler ; 91 + Default_Handler GPIO1_4_Handler ; 92 + Default_Handler GPIO1_5_Handler ; 93 + Default_Handler GPIO1_6_Handler ; 94 + Default_Handler GPIO1_7_Handler ; 95 + Default_Handler GPIO1_8_Handler ; 96 + Default_Handler GPIO1_9_Handler ; 97 + Default_Handler GPIO1_10_Handler ; 98 + Default_Handler GPIO1_11_Handler ; 99 + Default_Handler GPIO1_12_Handler ; 100 + Default_Handler GPIO1_13_Handler ; 101 + Default_Handler GPIO1_14_Handler ; 102 + Default_Handler GPIO1_15_Handler ; 103 + Default_Handler GPIO2_0_Handler ; 104 GPIO 2 has 16 individual Handlers + Default_Handler GPIO2_1_Handler ; 105 + Default_Handler GPIO2_2_Handler ; 106 + Default_Handler GPIO2_3_Handler ; 107 + Default_Handler GPIO2_4_Handler ; 108 + Default_Handler GPIO2_5_Handler ; 109 + Default_Handler GPIO2_6_Handler ; 110 + Default_Handler GPIO2_7_Handler ; 111 + Default_Handler GPIO2_8_Handler ; 112 + Default_Handler GPIO2_9_Handler ; 113 + Default_Handler GPIO2_10_Handler ; 114 + Default_Handler GPIO2_11_Handler ; 115 + Default_Handler GPIO2_12_Handler ; 116 + Default_Handler GPIO2_13_Handler ; 117 + Default_Handler GPIO2_14_Handler ; 118 + Default_Handler GPIO2_15_Handler ; 119 + Default_Handler GPIO3_0_Handler ; 120 GPIO 3 has 16 individual Handlers + Default_Handler GPIO3_1_Handler ; 121 + Default_Handler GPIO3_2_Handler ; 122 + Default_Handler GPIO3_3_Handler ; 123 + + ALIGN + + END diff --git a/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_ns.s b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_ns.s new file mode 100644 index 0000000000..f2000b212a --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_ns.s @@ -0,0 +1,325 @@ +;/* +; * Copyright (c) 2016-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. +; */ +; +; This file is derivative of CMSIS V5.00 startup_ARMv8MML.s + + +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + + IMPORT |Image$$ARM_LIB_STACK_MSP$$ZI$$Limit| + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD |Image$$ARM_LIB_STACK_MSP$$ZI$$Limit| ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; Core IoT Interrupts + DCD NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + DCD NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + DCD 0 ; - 2 Reserved + DCD TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 IRQ Handler + DCD TIMER1_Handler ; - 4 TIMER 1 IRQ Handler + DCD 0 ; - 5 Reserved + DCD CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + DCD CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + DCD 0 ; 8 Reserved + DCD MPC_Handler ; - 9 MPC Combined (Secure) Handler + DCD PPC_Handler ; - 10 PPC Combined (Secure) Handler + DCD MSC_Handler ; - 11 MSC Combined (Secure) Handler + DCD BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + DCD 0 ; - 13 Reserved + DCD 0 ; 14 Reserved + DCD PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + DCD 0 ; - 16 Reserved + DCD 0 ; - 17 Reserved + DCD 0 ; - 18 Reserved + DCD 0 ; - 19 Reserved + DCD 0 ; - 20 Reserved + DCD 0 ; - 21 Reserved + DCD 0 ; - 22 Reserved + DCD 0 ; - 23 Reserved + DCD 0 ; - 24 Reserved + DCD 0 ; - 25 Reserved + DCD 0 ; - 26 Reserved + DCD 0 ; - 27 Reserved + DCD 0 ; - 28 Reserved + DCD 0 ; - 29 Reserved + DCD 0 ; - 30 Reserved + DCD 0 ; - 31 Reserved + ; External Interrupts + DCD UARTRX0_Handler ; 32 UART 0 RX Handler + DCD UARTTX0_Handler ; 33 UART 0 TX Handler + DCD UARTRX1_Handler ; 34 UART 1 RX Handler + DCD UARTTX1_Handler ; 35 UART 1 TX Handler + DCD UARTRX2_Handler ; 36 UART 2 RX Handler + DCD UARTTX2_Handler ; 37 UART 2 TX Handler + DCD UARTRX3_Handler ; 38 UART 3 RX Handler + DCD UARTTX3_Handler ; 39 UART 3 TX Handler + DCD UARTRX4_Handler ; 40 UART 4 RX Handler + DCD UARTTX4_Handler ; 41 UART 4 TX Handler + DCD UART0_Handler ; 42 UART 0 combined Handler + DCD UART1_Handler ; 43 UART 1 combined Handler + DCD UART2_Handler ; 44 UART 2 combined Handler + DCD UART3_Handler ; 45 UART 3 combined Handler + DCD UART4_Handler ; 46 UART 4 combined Handler + DCD UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + DCD ETHERNET_Handler ; 48 Ethernet Handler + DCD I2S_Handler ; 49 I2S Handler + DCD TSC_Handler ; 50 Touch Screen Handler + DCD SPI0_Handler ; 51 SPI 0 Handler + DCD SPI1_Handler ; 52 SPI 1 Handler + DCD SPI2_Handler ; 53 SPI 2 Handler + DCD SPI3_Handler ; 54 SPI 3 Handler + DCD SPI4_Handler ; 55 SPI 4 Handler + DCD DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + DCD DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + DCD DMA0_Handler ; 58 DMA 0 Combined Handler + DCD DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + DCD DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + DCD DMA1_Handler ; 61 DMA 1 Combined Handler + DCD DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + DCD DMA2_TC_Handler ; 63 DMA 2 Terminal Count Ha + DCD DMA2_Handler ; 64 DMA 2 Combined Handler + DCD DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + DCD DMA3_TC_Handler ; 66 DMA 3 Terminal Count Ha + DCD DMA3_Handler ; 67 DMA 3 Combined Handler + DCD GPIO0_Handler ; 68 GPIO 0 Comboned Handler + DCD GPIO1_Handler ; 69 GPIO 1 Comboned Handler + DCD GPIO2_Handler ; 70 GPIO 2 Comboned Handler + DCD GPIO3_Handler ; 71 GPIO 3 Comboned Handler + DCD GPIO0_0_Handler ; 72 /* There are 16 pins for GPIO 0 */ + DCD GPIO0_1_Handler ; 73 + DCD GPIO0_2_Handler ; 74 + DCD GPIO0_3_Handler ; 75 + DCD GPIO0_4_Handler ; 76 + DCD GPIO0_5_Handler ; 77 + DCD GPIO0_6_Handler ; 78 + DCD GPIO0_7_Handler ; 79 + DCD GPIO0_8_Handler ; 80 + DCD GPIO0_9_Handler ; 81 + DCD GPIO0_10_Handler ; 82 + DCD GPIO0_11_Handler ; 83 + DCD GPIO0_12_Handler ; 84 + DCD GPIO0_13_Handler ; 85 + DCD GPIO0_14_Handler ; 86 + DCD GPIO0_15_Handler ; 87 + DCD GPIO1_0_Handler ; 88 /* There are 16 pins for GPIO 1 */ + DCD GPIO1_1_Handler ; 89 + DCD GPIO1_2_Handler ; 90 + DCD GPIO1_3_Handler ; 91 + DCD GPIO1_4_Handler ; 92 + DCD GPIO1_5_Handler ; 93 + DCD GPIO1_6_Handler ; 94 + DCD GPIO1_7_Handler ; 95 + DCD GPIO1_8_Handler ; 96 + DCD GPIO1_9_Handler ; 97 + DCD GPIO1_10_Handler ; 98 + DCD GPIO1_11_Handler ; 99 + DCD GPIO1_12_Handler ; 100 + DCD GPIO1_13_Handler ; 101 + DCD GPIO1_14_Handler ; 102 + DCD GPIO1_15_Handler ; 103 + DCD GPIO2_0_Handler ; 104 /* There are 16 pins for GPIO 2 */ + DCD GPIO2_1_Handler ; 105 + DCD GPIO2_2_Handler ; 106 + DCD GPIO2_3_Handler ; 107 + DCD GPIO2_4_Handler ; 108 + DCD GPIO2_5_Handler ; 109 + DCD GPIO2_6_Handler ; 110 + DCD GPIO2_7_Handler ; 111 + DCD GPIO2_8_Handler ; 112 + DCD GPIO2_9_Handler ; 113 + DCD GPIO2_10_Handler ; 114 + DCD GPIO2_11_Handler ; 115 + DCD GPIO2_12_Handler ; 116 + DCD GPIO2_13_Handler ; 117 + DCD GPIO2_14_Handler ; 118 + DCD GPIO2_15_Handler ; 119 + DCD GPIO3_0_Handler ; 120 /* There are 4 pins for GPIO 4 */ + DCD GPIO3_1_Handler ; 121 + DCD GPIO3_2_Handler ; 122 + DCD GPIO3_3_Handler ; 123 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + MRS R0, control ; Get control value + MOVS R1, #1 + ORRS R0, R0, R1 ; Select switch to unprivileged mode + MOVS R1, #2 + ORRS R0, R0, R1 ; Select switch to PSP + MSR control, R0 + LDR R0, =|Image$$ARM_LIB_STACK$$ZI$$Limit| + MOV SP, R0 ; Initialise PSP + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + MACRO + Default_Handler $handler_name +$handler_name PROC + EXPORT $handler_name [WEAK] + B . + ENDP + MEND + + Default_Handler NMI_Handler + Default_Handler HardFault_Handler + Default_Handler SVC_Handler + Default_Handler PendSV_Handler + Default_Handler SysTick_Handler + +; Core IoT Interrupts + Default_Handler NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + Default_Handler NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + Default_Handler TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler + Default_Handler TIMER1_Handler ; - 4 TIMER 1 Handler + Default_Handler CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + Default_Handler CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + Default_Handler MPC_Handler ; - 9 MPC Combined (Secure) Handler + Default_Handler PPC_Handler ; - 10 PPC Combined (Secure) Handler + Default_Handler MSC_Handler ; - 11 MSC Combined (Secure) Handler + Default_Handler BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + Default_Handler PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + ; External Interrupts + Default_Handler UARTRX0_Handler ; 32 UART 0 RX Handler + Default_Handler UARTTX0_Handler ; 33 UART 0 TX Handler + Default_Handler UARTRX1_Handler ; 34 UART 1 RX Handler + Default_Handler UARTTX1_Handler ; 35 UART 1 TX Handler + Default_Handler UARTRX2_Handler ; 36 UART 2 RX Handler + Default_Handler UARTTX2_Handler ; 37 UART 2 TX Handler + Default_Handler UARTRX3_Handler ; 38 UART 3 RX Handler + Default_Handler UARTTX3_Handler ; 39 UART 3 TX Handler + Default_Handler UARTRX4_Handler ; 40 UART 4 RX Handler + Default_Handler UARTTX4_Handler ; 41 UART 4 TX Handler + Default_Handler UART0_Handler ; 42 UART 0 combined Handler + Default_Handler UART1_Handler ; 43 UART 1 combined Handler + Default_Handler UART2_Handler ; 44 UART 2 combined Handler + Default_Handler UART3_Handler ; 45 UART 3 combined Handler + Default_Handler UART4_Handler ; 46 UART 4 combined Handler + Default_Handler UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + Default_Handler ETHERNET_Handler ; 48 Ethernet Handler + Default_Handler I2S_Handler ; 49 I2S Handler + Default_Handler TSC_Handler ; 50 Touch Screen Handler + Default_Handler SPI0_Handler ; 51 SPI 0 Handler + Default_Handler SPI1_Handler ; 52 SPI 1 Handler + Default_Handler SPI2_Handler ; 53 SPI 2 Handler + Default_Handler SPI3_Handler ; 54 SPI 3 Handler + Default_Handler SPI4_Handler ; 55 SPI 4 Handler + Default_Handler DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + Default_Handler DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + Default_Handler DMA0_Handler ; 58 DMA 0 Combined Handler + Default_Handler DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + Default_Handler DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + Default_Handler DMA1_Handler ; 61 DMA 1 Combined Handler + Default_Handler DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + Default_Handler DMA2_TC_Handler ; 63 DMA 2 Terminal Count Handler + Default_Handler DMA2_Handler ; 64 DMA 2 Combined Handler + Default_Handler DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + Default_Handler DMA3_TC_Handler ; 66 DMA 3 Terminal Count Handler + Default_Handler DMA3_Handler ; 67 DMA 3 Combined Handler + Default_Handler GPIO0_Handler ; 68 GPIO 0 Comboned Handler + Default_Handler GPIO1_Handler ; 69 GPIO 1 Comboned Handler + Default_Handler GPIO2_Handler ; 70 GPIO 2 Comboned Handler + Default_Handler GPIO3_Handler ; 71 GPIO 3 Comboned Handler + Default_Handler GPIO0_0_Handler ; 72 GPIO 0 has 16 individual Handlers + Default_Handler GPIO0_1_Handler ; 73 + Default_Handler GPIO0_2_Handler ; 74 + Default_Handler GPIO0_3_Handler ; 75 + Default_Handler GPIO0_4_Handler ; 76 + Default_Handler GPIO0_5_Handler ; 77 + Default_Handler GPIO0_6_Handler ; 78 + Default_Handler GPIO0_7_Handler ; 79 + Default_Handler GPIO0_8_Handler ; 80 + Default_Handler GPIO0_9_Handler ; 81 + Default_Handler GPIO0_10_Handler ; 82 + Default_Handler GPIO0_11_Handler ; 83 + Default_Handler GPIO0_12_Handler ; 84 + Default_Handler GPIO0_13_Handler ; 85 + Default_Handler GPIO0_14_Handler ; 86 + Default_Handler GPIO0_15_Handler ; 87 + Default_Handler GPIO1_0_Handler ; 88 GPIO 1 has 16 individual Handlers + Default_Handler GPIO1_1_Handler ; 89 + Default_Handler GPIO1_2_Handler ; 90 + Default_Handler GPIO1_3_Handler ; 91 + Default_Handler GPIO1_4_Handler ; 92 + Default_Handler GPIO1_5_Handler ; 93 + Default_Handler GPIO1_6_Handler ; 94 + Default_Handler GPIO1_7_Handler ; 95 + Default_Handler GPIO1_8_Handler ; 96 + Default_Handler GPIO1_9_Handler ; 97 + Default_Handler GPIO1_10_Handler ; 98 + Default_Handler GPIO1_11_Handler ; 99 + Default_Handler GPIO1_12_Handler ; 100 + Default_Handler GPIO1_13_Handler ; 101 + Default_Handler GPIO1_14_Handler ; 102 + Default_Handler GPIO1_15_Handler ; 103 + Default_Handler GPIO2_0_Handler ; 104 GPIO 2 has 16 individual Handlers + Default_Handler GPIO2_1_Handler ; 105 + Default_Handler GPIO2_2_Handler ; 106 + Default_Handler GPIO2_3_Handler ; 107 + Default_Handler GPIO2_4_Handler ; 108 + Default_Handler GPIO2_5_Handler ; 109 + Default_Handler GPIO2_6_Handler ; 110 + Default_Handler GPIO2_7_Handler ; 111 + Default_Handler GPIO2_8_Handler ; 112 + Default_Handler GPIO2_9_Handler ; 113 + Default_Handler GPIO2_10_Handler ; 114 + Default_Handler GPIO2_11_Handler ; 115 + Default_Handler GPIO2_12_Handler ; 116 + Default_Handler GPIO2_13_Handler ; 117 + Default_Handler GPIO2_14_Handler ; 118 + Default_Handler GPIO2_15_Handler ; 119 + Default_Handler GPIO3_0_Handler ; 120 GPIO 3 has 16 individual Handlers + Default_Handler GPIO3_1_Handler ; 121 + Default_Handler GPIO3_2_Handler ; 122 + Default_Handler GPIO3_3_Handler ; 123 + + ALIGN + + END diff --git a/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_s.s b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_s.s new file mode 100644 index 0000000000..8810a8e60e --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/armclang/startup_cmsdk_an539_mps2_s.s @@ -0,0 +1,332 @@ +;/* +; * Copyright (c) 2016-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. +; */ +; +; This file is derivative of CMSIS V5.00 startup_ARMv8MML.s + + +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + + IMPORT |Image$$ARM_LIB_STACK_MSP$$ZI$$Limit| + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + + PRESERVE8 + +__Vectors DCD |Image$$ARM_LIB_STACK_MSP$$ZI$$Limit| ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; Core IoT Interrupts + DCD NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + DCD NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + DCD 0 ; - 2 Reserved + DCD TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 IRQ Handler + DCD TIMER1_Handler ; - 4 TIMER 1 IRQ Handler + DCD 0 ; - 5 Reserved + DCD CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + DCD CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + DCD 0 ; 8 Reserved + DCD MPC_Handler ; - 9 MPC Combined (Secure) Handler + DCD PPC_Handler ; - 10 PPC Combined (Secure) Handler + DCD MSC_Handler ; - 11 MSC Combined (Secure) Handler + DCD BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + DCD 0 ; - 13 Reserved + DCD 0 ; 14 Reserved + DCD PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + DCD 0 ; - 16 Reserved + DCD 0 ; - 17 Reserved + DCD 0 ; - 18 Reserved + DCD 0 ; - 19 Reserved + DCD 0 ; - 20 Reserved + DCD 0 ; - 21 Reserved + DCD 0 ; - 22 Reserved + DCD 0 ; - 23 Reserved + DCD 0 ; - 24 Reserved + DCD 0 ; - 25 Reserved + DCD 0 ; - 26 Reserved + DCD 0 ; - 27 Reserved + DCD 0 ; - 28 Reserved + DCD 0 ; - 29 Reserved + DCD 0 ; - 30 Reserved + DCD 0 ; - 31 Reserved + ; External Interrupts + DCD UARTRX0_Handler ; 32 UART 0 RX Handler + DCD UARTTX0_Handler ; 33 UART 0 TX Handler + DCD UARTRX1_Handler ; 34 UART 1 RX Handler + DCD UARTTX1_Handler ; 35 UART 1 TX Handler + DCD UARTRX2_Handler ; 36 UART 2 RX Handler + DCD UARTTX2_Handler ; 37 UART 2 TX Handler + DCD UARTRX3_Handler ; 38 UART 3 RX Handler + DCD UARTTX3_Handler ; 39 UART 3 TX Handler + DCD UARTRX4_Handler ; 40 UART 4 RX Handler + DCD UARTTX4_Handler ; 41 UART 4 TX Handler + DCD UART0_Handler ; 42 UART 0 combined Handler + DCD UART1_Handler ; 43 UART 1 combined Handler + DCD UART2_Handler ; 44 UART 2 combined Handler + DCD UART3_Handler ; 45 UART 3 combined Handler + DCD UART4_Handler ; 46 UART 4 combined Handler + DCD UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + DCD ETHERNET_Handler ; 48 Ethernet Handler + DCD I2S_Handler ; 49 I2S Handler + DCD TSC_Handler ; 50 Touch Screen Handler + DCD SPI0_Handler ; 51 SPI 0 Handler + DCD SPI1_Handler ; 52 SPI 1 Handler + DCD SPI2_Handler ; 53 SPI 2 Handler + DCD SPI3_Handler ; 54 SPI 3 Handler + DCD SPI4_Handler ; 55 SPI 4 Handler + DCD DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + DCD DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + DCD DMA0_Handler ; 58 DMA 0 Combined Handler + DCD DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + DCD DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + DCD DMA1_Handler ; 61 DMA 1 Combined Handler + DCD DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + DCD DMA2_TC_Handler ; 63 DMA 2 Terminal Count Ha + DCD DMA2_Handler ; 64 DMA 2 Combined Handler + DCD DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + DCD DMA3_TC_Handler ; 66 DMA 3 Terminal Count Ha + DCD DMA3_Handler ; 67 DMA 3 Combined Handler + DCD GPIO0_Handler ; 68 GPIO 0 Comboned Handler + DCD GPIO1_Handler ; 69 GPIO 1 Comboned Handler + DCD GPIO2_Handler ; 70 GPIO 2 Comboned Handler + DCD GPIO3_Handler ; 71 GPIO 3 Comboned Handler + DCD GPIO0_0_Handler ; 72 /* There are 16 pins for GPIO 0 */ + DCD GPIO0_1_Handler ; 73 + DCD GPIO0_2_Handler ; 74 + DCD GPIO0_3_Handler ; 75 + DCD GPIO0_4_Handler ; 76 + DCD GPIO0_5_Handler ; 77 + DCD GPIO0_6_Handler ; 78 + DCD GPIO0_7_Handler ; 79 + DCD GPIO0_8_Handler ; 80 + DCD GPIO0_9_Handler ; 81 + DCD GPIO0_10_Handler ; 82 + DCD GPIO0_11_Handler ; 83 + DCD GPIO0_12_Handler ; 84 + DCD GPIO0_13_Handler ; 85 + DCD GPIO0_14_Handler ; 86 + DCD GPIO0_15_Handler ; 87 + DCD GPIO1_0_Handler ; 88 /* There are 16 pins for GPIO 1 */ + DCD GPIO1_1_Handler ; 89 + DCD GPIO1_2_Handler ; 90 + DCD GPIO1_3_Handler ; 91 + DCD GPIO1_4_Handler ; 92 + DCD GPIO1_5_Handler ; 93 + DCD GPIO1_6_Handler ; 94 + DCD GPIO1_7_Handler ; 95 + DCD GPIO1_8_Handler ; 96 + DCD GPIO1_9_Handler ; 97 + DCD GPIO1_10_Handler ; 98 + DCD GPIO1_11_Handler ; 99 + DCD GPIO1_12_Handler ; 100 + DCD GPIO1_13_Handler ; 101 + DCD GPIO1_14_Handler ; 102 + DCD GPIO1_15_Handler ; 103 + DCD GPIO2_0_Handler ; 104 /* There are 16 pins for GPIO 2 */ + DCD GPIO2_1_Handler ; 105 + DCD GPIO2_2_Handler ; 106 + DCD GPIO2_3_Handler ; 107 + DCD GPIO2_4_Handler ; 108 + DCD GPIO2_5_Handler ; 109 + DCD GPIO2_6_Handler ; 110 + DCD GPIO2_7_Handler ; 111 + DCD GPIO2_8_Handler ; 112 + DCD GPIO2_9_Handler ; 113 + DCD GPIO2_10_Handler ; 114 + DCD GPIO2_11_Handler ; 115 + DCD GPIO2_12_Handler ; 116 + DCD GPIO2_13_Handler ; 117 + DCD GPIO2_14_Handler ; 118 + DCD GPIO2_15_Handler ; 119 + DCD GPIO3_0_Handler ; 120 /* There are 4 pins for GPIO 4 */ + DCD GPIO3_1_Handler ; 121 + DCD GPIO3_2_Handler ; 122 + DCD GPIO3_3_Handler ; 123 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + CPSID i ; Disable IRQs + LDR R0, =SystemInit + BLX R0 + MRS R0, control ; Get control value + MOVS R1, #2 + ORRS R0, R0, R1 ; Select switch to PSP + MSR control, R0 + LDR R0, =|Image$$ARM_LIB_STACK$$ZI$$Limit| + MOVS R1, #7 + BICS R0, R1 ; Make sure that the SP address is aligned to 8 + MOV SP, R0 ; Initialise PSP + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + MACRO + Default_Handler $handler_name +$handler_name PROC + EXPORT $handler_name [WEAK] + B . + ENDP + MEND + + Default_Handler NMI_Handler + Default_Handler HardFault_Handler + Default_Handler SVC_Handler + Default_Handler PendSV_Handler + Default_Handler SysTick_Handler + +; Core IoT Interrupts + Default_Handler NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler + Default_Handler NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler + Default_Handler TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler + Default_Handler TIMER1_Handler ; - 4 TIMER 1 Handler + Default_Handler CTI_REQ0_IRQHandler ; - 6 CTI request 0 IRQ Handler + Default_Handler CTI_REQ1_IRQHandler ; - 7 CTI request 1 IRQ Handler + Default_Handler MPC_Handler ; - 9 MPC Combined (Secure) Handler + Default_Handler PPC_Handler ; - 10 PPC Combined (Secure) Handler + Default_Handler MSC_Handler ; - 11 MSC Combined (Secure) Handler + Default_Handler BRIDGE_ERROR_Handler ; - 12 Bridge Error Combined (Secure) Handler + Default_Handler PD_SYS_PPU_IRQHandler ; - 15 SYS PPU Handler + ; External Interrupts + Default_Handler UARTRX0_Handler ; 32 UART 0 RX Handler + Default_Handler UARTTX0_Handler ; 33 UART 0 TX Handler + Default_Handler UARTRX1_Handler ; 34 UART 1 RX Handler + Default_Handler UARTTX1_Handler ; 35 UART 1 TX Handler + Default_Handler UARTRX2_Handler ; 36 UART 2 RX Handler + Default_Handler UARTTX2_Handler ; 37 UART 2 TX Handler + Default_Handler UARTRX3_Handler ; 38 UART 3 RX Handler + Default_Handler UARTTX3_Handler ; 39 UART 3 TX Handler + Default_Handler UARTRX4_Handler ; 40 UART 4 RX Handler + Default_Handler UARTTX4_Handler ; 41 UART 4 TX Handler + Default_Handler UART0_Handler ; 42 UART 0 combined Handler + Default_Handler UART1_Handler ; 43 UART 1 combined Handler + Default_Handler UART2_Handler ; 44 UART 2 combined Handler + Default_Handler UART3_Handler ; 45 UART 3 combined Handler + Default_Handler UART4_Handler ; 46 UART 4 combined Handler + Default_Handler UARTOVF_Handler ; 47 UART 0,1,2,3,4 Overflow Handler + Default_Handler ETHERNET_Handler ; 48 Ethernet Handler + Default_Handler I2S_Handler ; 49 I2S Handler + Default_Handler TSC_Handler ; 50 Touch Screen Handler + Default_Handler SPI0_Handler ; 51 SPI 0 Handler + Default_Handler SPI1_Handler ; 52 SPI 1 Handler + Default_Handler SPI2_Handler ; 53 SPI 2 Handler + Default_Handler SPI3_Handler ; 54 SPI 3 Handler + Default_Handler SPI4_Handler ; 55 SPI 4 Handler + Default_Handler DMA0_ERROR_Handler ; 56 DMA 0 Error Handler + Default_Handler DMA0_TC_Handler ; 57 DMA 0 Terminal Count Handler + Default_Handler DMA0_Handler ; 58 DMA 0 Combined Handler + Default_Handler DMA1_ERROR_Handler ; 59 DMA 1 Error Handler + Default_Handler DMA1_TC_Handler ; 60 DMA 1 Terminal Count Handler + Default_Handler DMA1_Handler ; 61 DMA 1 Combined Handler + Default_Handler DMA2_ERROR_Handler ; 62 DMA 2 Error Handler + Default_Handler DMA2_TC_Handler ; 63 DMA 2 Terminal Count Handler + Default_Handler DMA2_Handler ; 64 DMA 2 Combined Handler + Default_Handler DMA3_ERROR_Handler ; 65 DMA 3 Error Handler + Default_Handler DMA3_TC_Handler ; 66 DMA 3 Terminal Count Handler + Default_Handler DMA3_Handler ; 67 DMA 3 Combined Handler + Default_Handler GPIO0_Handler ; 68 GPIO 0 Comboned Handler + Default_Handler GPIO1_Handler ; 69 GPIO 1 Comboned Handler + Default_Handler GPIO2_Handler ; 70 GPIO 2 Comboned Handler + Default_Handler GPIO3_Handler ; 71 GPIO 3 Comboned Handler + Default_Handler GPIO0_0_Handler ; 72 GPIO 0 has 16 individual Handlers + Default_Handler GPIO0_1_Handler ; 73 + Default_Handler GPIO0_2_Handler ; 74 + Default_Handler GPIO0_3_Handler ; 75 + Default_Handler GPIO0_4_Handler ; 76 + Default_Handler GPIO0_5_Handler ; 77 + Default_Handler GPIO0_6_Handler ; 78 + Default_Handler GPIO0_7_Handler ; 79 + Default_Handler GPIO0_8_Handler ; 80 + Default_Handler GPIO0_9_Handler ; 81 + Default_Handler GPIO0_10_Handler ; 82 + Default_Handler GPIO0_11_Handler ; 83 + Default_Handler GPIO0_12_Handler ; 84 + Default_Handler GPIO0_13_Handler ; 85 + Default_Handler GPIO0_14_Handler ; 86 + Default_Handler GPIO0_15_Handler ; 87 + Default_Handler GPIO1_0_Handler ; 88 GPIO 1 has 16 individual Handlers + Default_Handler GPIO1_1_Handler ; 89 + Default_Handler GPIO1_2_Handler ; 90 + Default_Handler GPIO1_3_Handler ; 91 + Default_Handler GPIO1_4_Handler ; 92 + Default_Handler GPIO1_5_Handler ; 93 + Default_Handler GPIO1_6_Handler ; 94 + Default_Handler GPIO1_7_Handler ; 95 + Default_Handler GPIO1_8_Handler ; 96 + Default_Handler GPIO1_9_Handler ; 97 + Default_Handler GPIO1_10_Handler ; 98 + Default_Handler GPIO1_11_Handler ; 99 + Default_Handler GPIO1_12_Handler ; 100 + Default_Handler GPIO1_13_Handler ; 101 + Default_Handler GPIO1_14_Handler ; 102 + Default_Handler GPIO1_15_Handler ; 103 + Default_Handler GPIO2_0_Handler ; 104 GPIO 2 has 16 individual Handlers + Default_Handler GPIO2_1_Handler ; 105 + Default_Handler GPIO2_2_Handler ; 106 + Default_Handler GPIO2_3_Handler ; 107 + Default_Handler GPIO2_4_Handler ; 108 + Default_Handler GPIO2_5_Handler ; 109 + Default_Handler GPIO2_6_Handler ; 110 + Default_Handler GPIO2_7_Handler ; 111 + Default_Handler GPIO2_8_Handler ; 112 + Default_Handler GPIO2_9_Handler ; 113 + Default_Handler GPIO2_10_Handler ; 114 + Default_Handler GPIO2_11_Handler ; 115 + Default_Handler GPIO2_12_Handler ; 116 + Default_Handler GPIO2_13_Handler ; 117 + Default_Handler GPIO2_14_Handler ; 118 + Default_Handler GPIO2_15_Handler ; 119 + Default_Handler GPIO3_0_Handler ; 120 GPIO 3 has 16 individual Handlers + Default_Handler GPIO3_1_Handler ; 121 + Default_Handler GPIO3_2_Handler ; 122 + Default_Handler GPIO3_3_Handler ; 123 + + ALIGN + + END diff --git a/platform/ext/target/mps2/an539/device/source/device_definition.c b/platform/ext/target/mps2/an539/device/source/device_definition.c new file mode 100644 index 0000000000..4e61cab0ee --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/device_definition.c @@ -0,0 +1,529 @@ +/* + * 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 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 + +#ifdef UART3_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_S = { + .base = UART3_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_S = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART3_DEV_S = { + &(UART3_CMSDK_DEV_CFG_S), + &(UART3_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART3_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART3_CMSDK_DEV_CFG_NS = { + .base = UART3_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART3_CMSDK_DEV_DATA_NS = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART3_DEV_NS = { + &(UART3_CMSDK_DEV_CFG_NS), + &(UART3_CMSDK_DEV_DATA_NS) +}; +#endif + +#ifdef UART4_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_S = { + .base = UART4_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_S = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART4_DEV_S = { + &(UART4_CMSDK_DEV_CFG_S), + &(UART4_CMSDK_DEV_DATA_S) +}; +#endif +#ifdef UART4_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART4_CMSDK_DEV_CFG_NS = { + .base = UART4_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE +}; +static struct uart_cmsdk_dev_data_t UART4_CMSDK_DEV_DATA_NS = { + .state = 0, + .system_clk = 0, + .baudrate = 0 +}; +struct uart_cmsdk_dev_t ARM_UART4_DEV_NS = { + &(UART4_CMSDK_DEV_CFG_NS), + &(UART4_CMSDK_DEV_DATA_NS) +}; +#endif + + +/* SSE-123 PPC driver structures */ +#ifdef PPC_SSE123_AHB_EXP0_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_AHB_EXP0_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_AHB_EXP0}; +static struct ppc_sse123_dev_data_t PPC_SSE123_AHB_EXP0_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_AHB_EXP0_DEV_S = { + &PPC_SSE123_AHB_EXP0_CFG_S, &PPC_SSE123_AHB_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE123_APB_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_APB_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_APB}; +static struct ppc_sse123_dev_data_t PPC_SSE123_APB_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_APB_DEV_S = { + &PPC_SSE123_APB_CFG_S, &PPC_SSE123_APB_DATA_S }; +#endif + + +#ifdef PPC_SSE123_APB_EXP0_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_APB_EXP0_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_APB_EXP0}; +static struct ppc_sse123_dev_data_t PPC_SSE123_APB_EXP0_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_APB_EXP0_DEV_S = { + &PPC_SSE123_APB_EXP0_CFG_S, &PPC_SSE123_APB_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE123_APB_EXP1_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_APB_EXP1_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_APB_EXP1}; +static struct ppc_sse123_dev_data_t PPC_SSE123_APB_EXP1_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_APB_EXP1_DEV_S = { + &PPC_SSE123_APB_EXP1_CFG_S, &PPC_SSE123_APB_EXP1_DATA_S }; +#endif + +#ifdef PPC_SSE123_APB_EXP2_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_APB_EXP2_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_APB_EXP2}; +static struct ppc_sse123_dev_data_t PPC_SSE123_APB_EXP2_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_APB_EXP2_DEV_S = { + &PPC_SSE123_APB_EXP2_CFG_S, &PPC_SSE123_APB_EXP2_DATA_S }; +#endif + +#ifdef PPC_SSE123_APB_EXP3_S +static struct ppc_sse123_dev_cfg_t PPC_SSE123_APB_EXP3_CFG_S = { + .spctrl_base = SSE123_SPCTRL_BASE_S, + .nspctrl_base = SSE123_NSPCTRL_BASE_NS, + .ppc_name = PPC_SSE123_APB_EXP3}; +static struct ppc_sse123_dev_data_t PPC_SSE123_APB_EXP3_DATA_S = { + .spctrl_ns_ppc = 0, + .spctrl_sp_ppc = 0, + .nspctrl_nsp_ppc = 0, + .int_bit_mask = 0, + .state = 0 }; +struct ppc_sse123_dev_t PPC_SSE123_APB_EXP3_DEV_S = { + &PPC_SSE123_APB_EXP3_CFG_S, &PPC_SSE123_APB_EXP3_DATA_S }; +#endif + +/* ARM MPC SIE 200 driver structures */ +#ifdef MPC_ISRAM0_S +static const struct mpc_sie200_dev_cfg_t MPC_ISRAM0_DEV_CFG_S = { + .base = MPC_ISRAM_BASE_S}; +static struct mpc_sie200_dev_data_t MPC_ISRAM0_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .state = 0, + .reserved = 0}; +struct mpc_sie200_dev_t MPC_ISRAM0_DEV_S = { + &(MPC_ISRAM0_DEV_CFG_S), + &(MPC_ISRAM0_DEV_DATA_S)}; +#endif + +#ifdef MPC_SSRAM1_S +static const struct mpc_sie200_dev_cfg_t MPC_SSRAM1_DEV_CFG_S = { + .base = MPC_SSRAM1_BASE_S}; +static struct mpc_sie200_dev_data_t MPC_SSRAM1_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .state = 0, + .reserved = 0}; +struct mpc_sie200_dev_t MPC_SSRAM1_DEV_S = { + &(MPC_SSRAM1_DEV_CFG_S), + &(MPC_SSRAM1_DEV_DATA_S)}; +#endif + +#ifdef MPC_SSRAM2_S +static const struct mpc_sie200_dev_cfg_t MPC_SSRAM2_DEV_CFG_S = { + .base = MPC_SSRAM2_BASE_S}; +static struct mpc_sie200_dev_data_t MPC_SSRAM2_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .state = 0, + .reserved = 0}; +struct mpc_sie200_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_sie200_dev_cfg_t MPC_SSRAM3_DEV_CFG_S = { + .base = MPC_SSRAM3_BASE_S}; +static struct mpc_sie200_dev_data_t MPC_SSRAM3_DEV_DATA_S = { + .range_list = 0, + .nbr_of_ranges = 0, + .state = 0, + .reserved = 0}; +struct mpc_sie200_dev_t MPC_SSRAM3_DEV_S = { + &(MPC_SSRAM3_DEV_CFG_S), + &(MPC_SSRAM3_DEV_DATA_S)}; +#endif + +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S + +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT > \ + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT is invalid. +#endif + +static const struct syscounter_armv8_m_cntrl_dev_cfg_t +SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_CNTRL_BASE_S, + .scale0.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT, + .scale0.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT, + .scale1.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT, + .scale1.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT +}; +static struct syscounter_armv8_m_cntrl_dev_data_t +SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S = { + .is_initialized = false +}; +struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S = { + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S), + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S) +}; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +static const struct syscounter_armv8_m_read_dev_cfg_t +SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_READ_BASE_S, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S = { + &(SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S), +}; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +static const struct syscounter_armv8_m_read_dev_cfg_t +SYSCOUNTER_READ_ARMV8_M_DEV_CFG_NS = { + .base = SYSCNTR_READ_BASE_NS, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS = { + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_NS), +}; +#endif + +#ifdef SYSTIMER0_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t +SYSTIMER0_ARMV8_M_DEV_CFG_S = { + .base = SYSTEM_TIMER0_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 = SYSTEM_TIMER0_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 = SYSTEM_TIMER1_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 = SYSTEM_TIMER1_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
\ No newline at end of file diff --git a/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_bl2.ld b/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_bl2.ld new file mode 100644 index 0000000000..f929819419 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_bl2.ld @@ -0,0 +1,188 @@ +;/* +; * Copyright (c) 2018-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. +; * +; * +; * This file is derivative of CMSIS V5.00 gcc_arm.ld +; */ + +/* Linker script to configure memory regions. */ +/* This file will be run trough the pre-processor. */ + +#include "region_defs.h" + +MEMORY +{ + FLASH (rx) : ORIGIN = BL2_CODE_START, LENGTH = BL2_CODE_SIZE + RAM (rwx) : ORIGIN = BL2_DATA_START, LENGTH = BL2_DATA_SIZE +} + +__heap_size__ = BL2_HEAP_SIZE; +__msp_stack_size__ = BL2_MSP_STACK_SIZE; + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * define etext2/data2_start/data2_end and + * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps2_sse_200.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (DEFINED(__etext2) ? __etext2 : 0) + LONG (DEFINED(__data2_start__) ? __data2_start__ : 0) + LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0) + __copy_table_end__ = .; + } > FLASH + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0) + LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0) + __zero_table_end__ = .; + } > FLASH + + __etext = .; + + .tfm_bl2_shared_data : ALIGN(32) + { + . += BOOT_TFM_SHARED_DATA_SIZE; + } > RAM + Image$$SHARED_DATA$$RW$$Base = ADDR(.tfm_bl2_shared_data); + Image$$SHARED_DATA$$RW$$Limit = ADDR(.tfm_bl2_shared_data) + SIZEOF(.tfm_bl2_shared_data); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + bss_size = __bss_end__ - __bss_start__; + + .msp_stack : ALIGN(32) + { + . += __msp_stack_size__; + } > RAM + Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.msp_stack); + Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack); + + .heap : ALIGN(8) + { + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += __heap_size__; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > RAM + + PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit); +} diff --git a/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_ns.ld b/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_ns.ld new file mode 100644 index 0000000000..f0c071d2d4 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/gcc/an539_mps2_ns.ld @@ -0,0 +1,189 @@ +;/* +; * Copyright (c) 2017-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. +; * +; * +; * This file is derivative of CMSIS V5.00 gcc_arm.ld +; */ + +/* Linker script to configure memory regions. */ +/* This file will be run trough the pre-processor. */ + +#include "region_defs.h" + +MEMORY +{ + /* Non-secure origin = Non-secure base + Secure length */ + FLASH (rx) : ORIGIN = NS_CODE_START, LENGTH = NS_CODE_SIZE + RAM (rwx) : ORIGIN = NS_DATA_START, LENGTH = NS_DATA_SIZE +} + +__heap_size__ = NS_HEAP_SIZE; +__psp_stack_size__ = NS_PSP_STACK_SIZE; +__msp_stack_size__ = NS_MSP_STACK_SIZE; + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * define etext2/data2_start/data2_end and + * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps2_sse_200.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (DEFINED(__etext2) ? __etext2 : 0) + LONG (DEFINED(__data2_start__) ? __data2_start__ : 0) + LONG (DEFINED(__data2_start__) ? __data2_end__ - __data2_start__ : 0) + __copy_table_end__ = .; + } > FLASH + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0) + LONG (DEFINED(__bss2_start__) ? __bss2_end__ - __bss2_start__ : 0) + __zero_table_end__ = .; + } > FLASH + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + bss_size = __bss_end__ - __bss_start__; + + .msp_stack : ALIGN(32) + { + . += __msp_stack_size__; + } > RAM + Image$$ARM_LIB_STACK_MSP$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack); + + .psp_stack : ALIGN(32) + { + . += __psp_stack_size__; + } > RAM + Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.psp_stack); + Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.psp_stack) + SIZEOF(.psp_stack); + + .heap : ALIGN(8) + { + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += __heap_size__; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > RAM + + PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit); +} diff --git a/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_bl2.S b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_bl2.S new file mode 100644 index 0000000000..ab9e577c79 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_bl2.S @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2009-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. + */ + +/* This file is derivative of CMSIS V5.40 startup_ARMCM23.S + * Git SHA: cb3fb9a70f3de3670bf5523a588c7f63cec48ff6 + */ + + .syntax unified + .arch armv8-m.base + + .section .vectors + .align 2 + .globl __Vectors +__Vectors: + .long Image$$ARM_LIB_STACK$$ZI$$Limit /* Top of Stack */ + + /* Core interrupts */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + .long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + .long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + .long 0 /* 2: Reserved */ + .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + .long TIMER1_Handler /* 4: TIMER 1 Handler */ + .long 0 /* 5: Reserved */ + .long CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + .long CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + .long 0 /* 8: Reserved */ + .long MPC_Handler /* 9: MPC Combined (Secure) Handler */ + .long PPC_Handler /* 10: PPC Combined (Secure) Handler */ + .long MSC_Handler /* 11: MSC Combined (Secure) Handler */ + .long BRIDGE_ERROR_Handler /* 12: Bridge Error Combined (Secure) Handler */ + .long 0 /* 13: Reserved */ + .long 0 /* 14: Reserved */ + .long SYS_PPU_Handler /* 15: SYS PPU Handler */ + .long 0 /* 16: Reserved */ + .long 0 /* 17: Reserved */ + .long 0 /* 18: Reserved */ + .long 0 /* 19: Reserved */ + .long 0 /* 20: Reserved */ + .long 0 /* 21: Reserved */ + .long 0 /* 22: Reserved */ + .long 0 /* 23: Reserved */ + .long 0 /* 24: Reserved */ + .long 0 /* 25: Reserved */ + .long 0 /* 26: Reserved */ + .long 0 /* 27: Reserved */ + .long 0 /* 28: Reserved */ + .long 0 /* 29: Reserved */ + .long 0 /* 30: Reserved */ + .long 0 /* 31: Reserved */ + /* External Interrupts */ + .long UARTRX0_Handler /* 32: UART 0 RX Handler */ + .long UARTTX0_Handler /* 33: UART 0 TX Handler */ + .long UARTRX1_Handler /* 34: UART 1 RX Handler */ + .long UARTTX1_Handler /* 35: UART 1 TX Handler */ + .long UARTRX2_Handler /* 36: UART 2 RX Handler */ + .long UARTTX2_Handler /* 37: UART 2 TX Handler */ + .long UARTRX3_Handler /* 38: UART 3 RX Handler */ + .long UARTTX3_Handler /* 39: UART 3 TX Handler */ + .long UARTRX4_Handler /* 40: UART 4 RX Handler */ + .long UARTTX4_Handler /* 41: UART 4 TX Handler */ + .long UART0_Handler /* 42: UART 0 combined Handler */ + .long UART1_Handler /* 43: UART 1 combined Handler */ + .long UART2_Handler /* 44: UART 2 combined Handler */ + .long UART3_Handler /* 45: UART 3 combined Handler */ + .long UART4_Handler /* 46: UART 4 combined Handler */ + .long UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + .long ETHERNET_Handler /* 48: Ethernet Handler */ + .long I2S_Handler /* 49: I2S Handler */ + .long TSC_Handler /* 50: Touch Screen Handler */ + .long SPI0_Handler /* 51: SPI 0 Handler */ + .long SPI1_Handler /* 52: SPI 1 Handler */ + .long SPI2_Handler /* 53: SPI 2 Handler */ + .long SPI3_Handler /* 54: SPI 3 Handler */ + .long SPI4_Handler /* 55: SPI 4 Handler */ + .long DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + .long DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + .long DMA0_Handler /* 58: DMA 0 Combined Handler */ + .long DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + .long DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + .long DMA1_Handler /* 61: DMA 1 Combined Handler */ + .long DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + .long DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + .long DMA2_Handler /* 64: DMA 2 Combined Handler */ + .long DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + .long DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + .long DMA3_Handler /* 67: DMA 3 Combined Handler */ + .long GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + .long GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + .long GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + .long GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + .long GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + .long GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + .long GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + .long GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + .long GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + .long GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + .long GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + .long GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + .long GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + .long GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + .long GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + .long GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + .long GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + .long GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + .long GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + .long GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + .long GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + .long GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + .long GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + .long GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + .long GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + .long GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + .long GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + .long GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + .long GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + .long GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + .long GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + .long GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + .long GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + .long GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + .long GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + .long GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + .long GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + .long GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + .long GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + .long GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + .long GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + .long GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + .long GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + .long GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + .long GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + .long GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + .long GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + .long GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + .long GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + .long GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + .long GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + .long GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + .long GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + .long GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + .long GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + .long GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + +__Vectors_End: + .equ __Vectors_Size, __Vectors_End - __Vectors + .size __Vectors, . - __Vectors + + .thumb + .section .text + .align 2 + + .thumb_func + .type Reset_Handler, %function + .globl Reset_Handler + .fnstart +Reset_Handler: +/* Firstly it copies data from read only memory to RAM. There are two schemes + * to copy. One can copy more than one sections. Another can only copy + * one section. The former scheme needs more instructions and read-only + * data to implement than the latter. + * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ + +#ifdef __STARTUP_COPY_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of triplets, each of which specify: + * offset 0: LMA of start of a section to copy from + * offset 4: VMA of start of a section to copy to + * offset 8: size of the section to copy. Must be multiply of 4 + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r4, =__copy_table_start__ + ldr r5, =__copy_table_end__ + +.L_loop0: + cmp r4, r5 + bge .L_loop0_done + ldr r1, [r4] + ldr r2, [r4, #4] + ldr r3, [r4, #8] + +.L_loop0_0: + subs r3, #4 + blt .L_loop0_0_done + ldr r0, [r1, r3] + str r0, [r2, r3] + b .L_loop0_0 + +.L_loop0_0_done: + adds r4, #12 + b .L_loop0 + +.L_loop0_done: +#else +/* Single section scheme. + * + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: +#endif /*__STARTUP_COPY_MULTIPLE */ + +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * There are two schemes too. One can clear multiple BSS sections. Another + * can only clear one section. The former is more size expensive than the + * latter. + * + * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. + * Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later. + */ +#ifdef __STARTUP_CLEAR_BSS_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of tuples specifying: + * offset 0: Start of a BSS section + * offset 4: Size of this BSS section. Must be multiply of 4 + */ + ldr r3, =__zero_table_start__ + ldr r4, =__zero_table_end__ + +.L_loop2: + cmp r3, r4 + bge .L_loop2_done + ldr r1, [r3] + ldr r2, [r3, #4] + movs r0, 0 + +.L_loop2_0: + subs r2, #4 + blt .L_loop2_0_done + str r0, [r1, r2] + b .L_loop2_0 +.L_loop2_0_done: + + adds r3, #8 + b .L_loop2 +.L_loop2_done: +#elif defined (__STARTUP_CLEAR_BSS) +/* Single BSS section scheme. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ + + bl SystemInit + +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + +/* Macro to define default handlers. */ + .macro def_irq_handler handler_name + .thumb_func + .weak \handler_name + \handler_name: + b \handler_name + .endm + + /* Core interrupts */ + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler SVC_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */ + def_irq_handler CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + def_irq_handler CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + def_irq_handler MPC_Handler /* 9 MPC Combined (Secure) Handler */ + def_irq_handler PPC_Handler /* 10 PPC Combined (Secure) Handler */ + def_irq_handler MSC_Handler /* 11 MSC Combined (Secure) Handler */ + def_irq_handler BRIDGE_ERROR_Handler /* 12 Bridge Error Combined (Secure) Handler */ + def_irq_handler SYS_PPU_Handler /* 15 SYS PPU Handler */ + /* External interrupts */ + def_irq_handler UARTRX0_Handler /* 32: UART 0 RX Handler */ + def_irq_handler UARTTX0_Handler /* 33: UART 0 TX Handler */ + def_irq_handler UARTRX1_Handler /* 34: UART 1 RX Handler */ + def_irq_handler UARTTX1_Handler /* 35: UART 1 TX Handler */ + def_irq_handler UARTRX2_Handler /* 36: UART 2 RX Handler */ + def_irq_handler UARTTX2_Handler /* 37: UART 2 TX Handler */ + def_irq_handler UARTRX3_Handler /* 38: UART 3 RX Handler */ + def_irq_handler UARTTX3_Handler /* 39: UART 3 TX Handler */ + def_irq_handler UARTRX4_Handler /* 40: UART 4 RX Handler */ + def_irq_handler UARTTX4_Handler /* 41: UART 4 TX Handler */ + def_irq_handler UART0_Handler /* 42: UART 0 combined Handler */ + def_irq_handler UART1_Handler /* 43: UART 1 combined Handler */ + def_irq_handler UART2_Handler /* 44: UART 2 combined Handler */ + def_irq_handler UART3_Handler /* 45: UART 3 combined Handler */ + def_irq_handler UART4_Handler /* 46: UART 4 combined Handler */ + def_irq_handler UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + def_irq_handler ETHERNET_Handler /* 48: Ethernet Handler */ + def_irq_handler I2S_Handler /* 49: I2S Handler */ + def_irq_handler TSC_Handler /* 50: Touch Screen Handler */ + def_irq_handler SPI0_Handler /* 51: SPI 0 Handler */ + def_irq_handler SPI1_Handler /* 52: SPI 1 Handler */ + def_irq_handler SPI2_Handler /* 53: SPI 2 Handler */ + def_irq_handler SPI3_Handler /* 54: SPI 3 Handler */ + def_irq_handler SPI4_Handler /* 55: SPI 4 Handler */ + def_irq_handler DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + def_irq_handler DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + def_irq_handler DMA0_Handler /* 58: DMA 0 Combined Handler */ + def_irq_handler DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + def_irq_handler DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + def_irq_handler DMA1_Handler /* 61: DMA 1 Combined Handler */ + def_irq_handler DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + def_irq_handler DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + def_irq_handler DMA2_Handler /* 64: DMA 2 Combined Handler */ + def_irq_handler DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + def_irq_handler DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + def_irq_handler DMA3_Handler /* 67: DMA 3 Combined Handler */ + def_irq_handler GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + def_irq_handler GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + def_irq_handler GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + def_irq_handler GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + def_irq_handler GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + def_irq_handler GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + def_irq_handler GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + def_irq_handler GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + def_irq_handler GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + def_irq_handler GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + def_irq_handler GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + def_irq_handler GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + def_irq_handler GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + def_irq_handler GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + def_irq_handler GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + def_irq_handler GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + def_irq_handler GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + def_irq_handler GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + def_irq_handler GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + def_irq_handler GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + def_irq_handler GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + def_irq_handler GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + def_irq_handler GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + def_irq_handler GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + def_irq_handler GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + def_irq_handler GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + def_irq_handler GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + def_irq_handler GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + def_irq_handler GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + def_irq_handler GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + def_irq_handler GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + def_irq_handler GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + def_irq_handler GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + def_irq_handler GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + def_irq_handler GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + def_irq_handler GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + def_irq_handler GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + def_irq_handler GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + def_irq_handler GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + def_irq_handler GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + def_irq_handler GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + def_irq_handler GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + def_irq_handler GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + def_irq_handler GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + def_irq_handler GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + def_irq_handler GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + def_irq_handler GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + def_irq_handler GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + def_irq_handler GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + def_irq_handler GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + def_irq_handler GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + def_irq_handler GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + def_irq_handler GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + def_irq_handler GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + def_irq_handler GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + def_irq_handler GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + + .end diff --git a/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_ns.S b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_ns.S new file mode 100644 index 0000000000..0ecd1f1027 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_ns.S @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2009-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. + */ + +/* This file is derivative of CMSIS V5.40 startup_ARMCM23.S + * Git SHA: cb3fb9a70f3de3670bf5523a588c7f63cec48ff6 + */ + + .syntax unified + .arch armv8-m.base + + .section .vectors + .align 2 + .globl __Vectors +__Vectors: + .long Image$$ARM_LIB_STACK_MSP$$ZI$$Limit /* Top of Stack */ + + /* Core interrupts */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + .long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + .long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + .long 0 /* 2: Reserved */ + .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + .long TIMER1_Handler /* 4: TIMER 1 Handler */ + .long 0 /* 5: Reserved */ + .long CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + .long CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + .long 0 /* 8: Reserved */ + .long MPC_Handler /* 9: MPC Combined (Secure) Handler */ + .long PPC_Handler /* 10: PPC Combined (Secure) Handler */ + .long MSC_Handler /* 11: MSC Combined (Secure) Handler */ + .long BRIDGE_ERROR_Handler /* 12: Bridge Error Combined (Secure) Handler */ + .long 0 /* 13: Reserved */ + .long 0 /* 14: Reserved */ + .long SYS_PPU_Handler /* 15: SYS PPU Handler */ + .long 0 /* 16: Reserved */ + .long 0 /* 17: Reserved */ + .long 0 /* 18: Reserved */ + .long 0 /* 19: Reserved */ + .long 0 /* 20: Reserved */ + .long 0 /* 21: Reserved */ + .long 0 /* 22: Reserved */ + .long 0 /* 23: Reserved */ + .long 0 /* 24: Reserved */ + .long 0 /* 25: Reserved */ + .long 0 /* 26: Reserved */ + .long 0 /* 27: Reserved */ + .long 0 /* 28: Reserved */ + .long 0 /* 29: Reserved */ + .long 0 /* 30: Reserved */ + .long 0 /* 31: Reserved */ + /* External Interrupts */ + .long UARTRX0_Handler /* 32: UART 0 RX Handler */ + .long UARTTX0_Handler /* 33: UART 0 TX Handler */ + .long UARTRX1_Handler /* 34: UART 1 RX Handler */ + .long UARTTX1_Handler /* 35: UART 1 TX Handler */ + .long UARTRX2_Handler /* 36: UART 2 RX Handler */ + .long UARTTX2_Handler /* 37: UART 2 TX Handler */ + .long UARTRX3_Handler /* 38: UART 3 RX Handler */ + .long UARTTX3_Handler /* 39: UART 3 TX Handler */ + .long UARTRX4_Handler /* 40: UART 4 RX Handler */ + .long UARTTX4_Handler /* 41: UART 4 TX Handler */ + .long UART0_Handler /* 42: UART 0 combined Handler */ + .long UART1_Handler /* 43: UART 1 combined Handler */ + .long UART2_Handler /* 44: UART 2 combined Handler */ + .long UART3_Handler /* 45: UART 3 combined Handler */ + .long UART4_Handler /* 46: UART 4 combined Handler */ + .long UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + .long ETHERNET_Handler /* 48: Ethernet Handler */ + .long I2S_Handler /* 49: I2S Handler */ + .long TSC_Handler /* 50: Touch Screen Handler */ + .long SPI0_Handler /* 51: SPI 0 Handler */ + .long SPI1_Handler /* 52: SPI 1 Handler */ + .long SPI2_Handler /* 53: SPI 2 Handler */ + .long SPI3_Handler /* 54: SPI 3 Handler */ + .long SPI4_Handler /* 55: SPI 4 Handler */ + .long DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + .long DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + .long DMA0_Handler /* 58: DMA 0 Combined Handler */ + .long DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + .long DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + .long DMA1_Handler /* 61: DMA 1 Combined Handler */ + .long DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + .long DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + .long DMA2_Handler /* 64: DMA 2 Combined Handler */ + .long DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + .long DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + .long DMA3_Handler /* 67: DMA 3 Combined Handler */ + .long GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + .long GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + .long GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + .long GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + .long GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + .long GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + .long GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + .long GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + .long GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + .long GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + .long GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + .long GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + .long GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + .long GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + .long GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + .long GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + .long GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + .long GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + .long GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + .long GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + .long GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + .long GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + .long GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + .long GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + .long GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + .long GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + .long GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + .long GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + .long GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + .long GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + .long GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + .long GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + .long GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + .long GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + .long GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + .long GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + .long GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + .long GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + .long GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + .long GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + .long GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + .long GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + .long GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + .long GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + .long GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + .long GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + .long GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + .long GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + .long GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + .long GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + .long GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + .long GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + .long GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + .long GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + .long GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + .long GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + +__Vectors_End: + .equ __Vectors_Size, __Vectors_End - __Vectors + .size __Vectors, . - __Vectors + + .thumb + .section .text + .align 2 + + .thumb_func + .type Reset_Handler, %function + .globl Reset_Handler + .fnstart +Reset_Handler: +/* Firstly it copies data from read only memory to RAM. + * There are two schemes to copy. One can copy more than one sections. + * Another can copy only one section. The former scheme needs more + * instructions and read-only data to implement than the latter. + * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. + */ + +#ifdef __STARTUP_COPY_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of triplets, each of which specify: + * offset 0: LMA of start of a section to copy from + * offset 4: VMA of start of a section to copy to + * offset 8: size of the section to copy. Must be multiply of 4 + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r4, =__copy_table_start__ + ldr r5, =__copy_table_end__ + +.L_loop0: + cmp r4, r5 + bge .L_loop0_done + ldr r1, [r4] + ldr r2, [r4, #4] + ldr r3, [r4, #8] + +.L_loop0_0: + subs r3, #4 + blt .L_loop0_0_done + ldr r0, [r1, r3] + str r0, [r2, r3] + b .L_loop0_0 + +.L_loop0_0_done: + adds r4, #12 + b .L_loop0 + +.L_loop0_done: +#else +/* Single section scheme. +* +* The ranges of copy from/to are specified by following symbols +* __etext: LMA of start of the section to copy from. Usually end of text +* __data_start__: VMA of start of the section to copy to +* __data_end__: VMA of end of the section to copy to +* +* All addresses must be aligned to 4 bytes boundary. +*/ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: +#endif /*__STARTUP_COPY_MULTIPLE */ + +/* This part of work usually is done in C library startup code. + * Otherwise, define this macro to enable it in this startup. + * + * There are two schemes too. + * One can clear multiple BSS sections. Another can only clear one section. + * The former is more size expensive than the latter. + * + * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. + * Otherwise define macro __STARTUP_CLEAR_BSS to choose the later. + */ +#ifdef __STARTUP_CLEAR_BSS_MULTIPLE +/* Multiple sections scheme. +* +* Between symbol address __copy_table_start__ and __copy_table_end__, +* there are array of tuples specifying: +* offset 0: Start of a BSS section +* offset 4: Size of this BSS section. Must be multiply of 4 +*/ + ldr r3, =__zero_table_start__ + ldr r4, =__zero_table_end__ + +.L_loop2: + cmp r3, r4 + bge .L_loop2_done + ldr r1, [r3] + ldr r2, [r3, #4] + movs r0, 0 + +.L_loop2_0: + subs r2, #4 + blt .L_loop2_0_done + str r0, [r1, r2] + b .L_loop2_0 +.L_loop2_0_done: + + adds r3, #8 + b .L_loop2 +.L_loop2_done: +#elif defined (__STARTUP_CLEAR_BSS) +/* Single BSS section scheme. +* +* The BSS section is specified by following symbols +* __bss_start__: start of the BSS section. +* __bss_end__: end of the BSS section. +* +* Both addresses must be aligned to 4 bytes boundary. +*/ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ + + ldr r0, =Image$$ARM_LIB_STACK_MSP$$ZI$$Limit + msr msplim, r0 + + bl SystemInit + bl _start + + .fnend + .size Reset_Handler, . - Reset_Handler + + .align 1 + +/* Macro to define default handlers. */ + .macro def_irq_handler handler_name + .thumb_func + .weak \handler_name + \handler_name: + b \handler_name + .endm + + /* Core interrupts */ + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler SVC_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */ + def_irq_handler CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + def_irq_handler CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + def_irq_handler MPC_Handler /* 9 MPC Combined (Secure) Handler */ + def_irq_handler PPC_Handler /* 10 PPC Combined (Secure) Handler */ + def_irq_handler MSC_Handler /* 11 MSC Combined (Secure) Handler */ + def_irq_handler BRIDGE_ERROR_Handler /* 12 Bridge Error Combined (Secure) Handler */ + def_irq_handler SYS_PPU_Handler /* 15 SYS PPU Handler */ + /* External interrupts */ + def_irq_handler UARTRX0_Handler /* 32: UART 0 RX Handler */ + def_irq_handler UARTTX0_Handler /* 33: UART 0 TX Handler */ + def_irq_handler UARTRX1_Handler /* 34: UART 1 RX Handler */ + def_irq_handler UARTTX1_Handler /* 35: UART 1 TX Handler */ + def_irq_handler UARTRX2_Handler /* 36: UART 2 RX Handler */ + def_irq_handler UARTTX2_Handler /* 37: UART 2 TX Handler */ + def_irq_handler UARTRX3_Handler /* 38: UART 3 RX Handler */ + def_irq_handler UARTTX3_Handler /* 39: UART 3 TX Handler */ + def_irq_handler UARTRX4_Handler /* 40: UART 4 RX Handler */ + def_irq_handler UARTTX4_Handler /* 41: UART 4 TX Handler */ + def_irq_handler UART0_Handler /* 42: UART 0 combined Handler */ + def_irq_handler UART1_Handler /* 43: UART 1 combined Handler */ + def_irq_handler UART2_Handler /* 44: UART 2 combined Handler */ + def_irq_handler UART3_Handler /* 45: UART 3 combined Handler */ + def_irq_handler UART4_Handler /* 46: UART 4 combined Handler */ + def_irq_handler UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + def_irq_handler ETHERNET_Handler /* 48: Ethernet Handler */ + def_irq_handler I2S_Handler /* 49: I2S Handler */ + def_irq_handler TSC_Handler /* 50: Touch Screen Handler */ + def_irq_handler SPI0_Handler /* 51: SPI 0 Handler */ + def_irq_handler SPI1_Handler /* 52: SPI 1 Handler */ + def_irq_handler SPI2_Handler /* 53: SPI 2 Handler */ + def_irq_handler SPI3_Handler /* 54: SPI 3 Handler */ + def_irq_handler SPI4_Handler /* 55: SPI 4 Handler */ + def_irq_handler DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + def_irq_handler DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + def_irq_handler DMA0_Handler /* 58: DMA 0 Combined Handler */ + def_irq_handler DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + def_irq_handler DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + def_irq_handler DMA1_Handler /* 61: DMA 1 Combined Handler */ + def_irq_handler DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + def_irq_handler DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + def_irq_handler DMA2_Handler /* 64: DMA 2 Combined Handler */ + def_irq_handler DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + def_irq_handler DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + def_irq_handler DMA3_Handler /* 67: DMA 3 Combined Handler */ + def_irq_handler GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + def_irq_handler GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + def_irq_handler GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + def_irq_handler GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + def_irq_handler GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + def_irq_handler GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + def_irq_handler GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + def_irq_handler GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + def_irq_handler GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + def_irq_handler GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + def_irq_handler GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + def_irq_handler GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + def_irq_handler GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + def_irq_handler GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + def_irq_handler GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + def_irq_handler GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + def_irq_handler GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + def_irq_handler GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + def_irq_handler GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + def_irq_handler GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + def_irq_handler GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + def_irq_handler GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + def_irq_handler GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + def_irq_handler GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + def_irq_handler GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + def_irq_handler GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + def_irq_handler GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + def_irq_handler GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + def_irq_handler GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + def_irq_handler GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + def_irq_handler GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + def_irq_handler GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + def_irq_handler GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + def_irq_handler GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + def_irq_handler GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + def_irq_handler GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + def_irq_handler GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + def_irq_handler GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + def_irq_handler GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + def_irq_handler GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + def_irq_handler GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + def_irq_handler GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + def_irq_handler GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + def_irq_handler GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + def_irq_handler GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + def_irq_handler GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + def_irq_handler GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + def_irq_handler GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + def_irq_handler GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + def_irq_handler GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + def_irq_handler GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + def_irq_handler GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + def_irq_handler GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + def_irq_handler GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + def_irq_handler GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + def_irq_handler GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + + .end diff --git a/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_s.S b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_s.S new file mode 100644 index 0000000000..3ef49f5889 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/gcc/startup_cmsdk_an539_mps2_s.S @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2009-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. + */ + +/* This file is derivative of CMSIS V5.40 startup_ARMCM23.S + * Git SHA: cb3fb9a70f3de3670bf5523a588c7f63cec48ff6 + */ + + .syntax unified + .arch armv8-m.base + + .section .vectors + .align 2 + .globl __Vectors +__Vectors: + .long Image$$ARM_LIB_STACK_MSP$$ZI$$Limit /* Top of Stack */ + + /* Core interrupts */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + .long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + .long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + .long 0 /* 2: Reserved */ + .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + .long TIMER1_Handler /* 4: TIMER 1 Handler */ + .long 0 /* 5: Reserved */ + .long CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + .long CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + .long 0 /* 8: Reserved */ + .long MPC_Handler /* 9: MPC Combined (Secure) Handler */ + .long PPC_Handler /* 10: PPC Combined (Secure) Handler */ + .long MSC_Handler /* 11: MSC Combined (Secure) Handler */ + .long BRIDGE_ERROR_Handler /* 12: Bridge Error Combined (Secure) Handler */ + .long 0 /* 13: Reserved */ + .long 0 /* 14: Reserved */ + .long SYS_PPU_Handler /* 15: SYS PPU Handler */ + .long 0 /* 16: Reserved */ + .long 0 /* 17: Reserved */ + .long 0 /* 18: Reserved */ + .long 0 /* 19: Reserved */ + .long 0 /* 20: Reserved */ + .long 0 /* 21: Reserved */ + .long 0 /* 22: Reserved */ + .long 0 /* 23: Reserved */ + .long 0 /* 24: Reserved */ + .long 0 /* 25: Reserved */ + .long 0 /* 26: Reserved */ + .long 0 /* 27: Reserved */ + .long 0 /* 28: Reserved */ + .long 0 /* 29: Reserved */ + .long 0 /* 30: Reserved */ + .long 0 /* 31: Reserved */ + /* External Interrupts */ + .long UARTRX0_Handler /* 32: UART 0 RX Handler */ + .long UARTTX0_Handler /* 33: UART 0 TX Handler */ + .long UARTRX1_Handler /* 34: UART 1 RX Handler */ + .long UARTTX1_Handler /* 35: UART 1 TX Handler */ + .long UARTRX2_Handler /* 36: UART 2 RX Handler */ + .long UARTTX2_Handler /* 37: UART 2 TX Handler */ + .long UARTRX3_Handler /* 38: UART 3 RX Handler */ + .long UARTTX3_Handler /* 39: UART 3 TX Handler */ + .long UARTRX4_Handler /* 40: UART 4 RX Handler */ + .long UARTTX4_Handler /* 41: UART 4 TX Handler */ + .long UART0_Handler /* 42: UART 0 combined Handler */ + .long UART1_Handler /* 43: UART 1 combined Handler */ + .long UART2_Handler /* 44: UART 2 combined Handler */ + .long UART3_Handler /* 45: UART 3 combined Handler */ + .long UART4_Handler /* 46: UART 4 combined Handler */ + .long UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + .long ETHERNET_Handler /* 48: Ethernet Handler */ + .long I2S_Handler /* 49: I2S Handler */ + .long TSC_Handler /* 50: Touch Screen Handler */ + .long SPI0_Handler /* 51: SPI 0 Handler */ + .long SPI1_Handler /* 52: SPI 1 Handler */ + .long SPI2_Handler /* 53: SPI 2 Handler */ + .long SPI3_Handler /* 54: SPI 3 Handler */ + .long SPI4_Handler /* 55: SPI 4 Handler */ + .long DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + .long DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + .long DMA0_Handler /* 58: DMA 0 Combined Handler */ + .long DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + .long DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + .long DMA1_Handler /* 61: DMA 1 Combined Handler */ + .long DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + .long DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + .long DMA2_Handler /* 64: DMA 2 Combined Handler */ + .long DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + .long DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + .long DMA3_Handler /* 67: DMA 3 Combined Handler */ + .long GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + .long GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + .long GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + .long GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + .long GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + .long GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + .long GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + .long GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + .long GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + .long GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + .long GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + .long GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + .long GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + .long GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + .long GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + .long GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + .long GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + .long GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + .long GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + .long GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + .long GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + .long GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + .long GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + .long GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + .long GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + .long GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + .long GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + .long GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + .long GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + .long GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + .long GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + .long GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + .long GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + .long GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + .long GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + .long GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + .long GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + .long GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + .long GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + .long GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + .long GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + .long GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + .long GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + .long GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + .long GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + .long GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + .long GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + .long GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + .long GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + .long GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + .long GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + .long GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + .long GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + .long GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + .long GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + .long GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + +__Vectors_End: + .equ __Vectors_Size, __Vectors_End - __Vectors + .size __Vectors, . - __Vectors + + .thumb + .section .text + .align 2 + + .thumb_func + .type Reset_Handler, %function + .globl Reset_Handler + .fnstart +Reset_Handler: +/* Firstly it copies data from read only memory to RAM. There are two schemes + * to copy. One can copy more than one sections. Another can only copy + * one section. The former scheme needs more instructions and read-only + * data to implement than the latter. + * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ + +#ifdef __STARTUP_COPY_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of triplets, each of which specify: + * offset 0: LMA of start of a section to copy from + * offset 4: VMA of start of a section to copy to + * offset 8: size of the section to copy. Must be multiply of 4 + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r4, =__copy_table_start__ + ldr r5, =__copy_table_end__ + +.L_loop0: + cmp r4, r5 + bge .L_loop0_done + ldr r1, [r4] + ldr r2, [r4, #4] + ldr r3, [r4, #8] + +.L_loop0_0: + subs r3, #4 + blt .L_loop0_0_done + ldr r0, [r1, r3] + str r0, [r2, r3] + b .L_loop0_0 + +.L_loop0_0_done: + adds r4, #12 + b .L_loop0 + +.L_loop0_done: +#else +/* Single section scheme. + * + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: +#endif /*__STARTUP_COPY_MULTIPLE */ + +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * There are two schemes too. One can clear multiple BSS sections. Another + * can only clear one section. The former is more size expensive than the + * latter. + * + * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. + * Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later. + */ +#ifdef __STARTUP_CLEAR_BSS_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of tuples specifying: + * offset 0: Start of a BSS section + * offset 4: Size of this BSS section. Must be multiply of 4 + */ + ldr r3, =__zero_table_start__ + ldr r4, =__zero_table_end__ + +.L_loop2: + cmp r3, r4 + bge .L_loop2_done + ldr r1, [r3] + ldr r2, [r3, #4] + movs r0, 0 + +.L_loop2_0: + subs r2, #4 + blt .L_loop2_0_done + str r0, [r1, r2] + b .L_loop2_0 +.L_loop2_0_done: + + adds r3, #8 + b .L_loop2 +.L_loop2_done: +#elif defined (__STARTUP_CLEAR_BSS) +/* Single BSS section scheme. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ + + cpsid i /* Disable IRQs */ + bl SystemInit + + mrs r0, control /* Get control value */ + movs r1, #2 + orrs r0, r0, r1 /* Select switch to PSP */ + msr control, r0 + ldr r0, =Image$$ARM_LIB_STACK$$ZI$$Limit + msr psp, r0 + +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + +/* Macro to define default handlers. */ + .macro def_irq_handler handler_name + .thumb_func + .weak \handler_name + \handler_name: + b \handler_name + .endm + + /* Core interrupts */ + def_irq_handler NMI_Handler + def_irq_handler HardFault_Handler + def_irq_handler SVC_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */ + def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */ + def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */ + def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */ + def_irq_handler CTI_REQ0_IRQHandler /* 6: CTI request 0 IRQ Handler */ + def_irq_handler CTI_REQ1_IRQHandler /* 7: CTI request 1 IRQ Handler */ + def_irq_handler MPC_Handler /* 9 MPC Combined (Secure) Handler */ + def_irq_handler PPC_Handler /* 10 PPC Combined (Secure) Handler */ + def_irq_handler MSC_Handler /* 11 MSC Combined (Secure) Handler */ + def_irq_handler BRIDGE_ERROR_Handler /* 12 Bridge Error Combined (Secure) Handler */ + def_irq_handler SYS_PPU_Handler /* 15 SYS PPU Handler */ + /* External interrupts */ + def_irq_handler UARTRX0_Handler /* 32: UART 0 RX Handler */ + def_irq_handler UARTTX0_Handler /* 33: UART 0 TX Handler */ + def_irq_handler UARTRX1_Handler /* 34: UART 1 RX Handler */ + def_irq_handler UARTTX1_Handler /* 35: UART 1 TX Handler */ + def_irq_handler UARTRX2_Handler /* 36: UART 2 RX Handler */ + def_irq_handler UARTTX2_Handler /* 37: UART 2 TX Handler */ + def_irq_handler UARTRX3_Handler /* 38: UART 3 RX Handler */ + def_irq_handler UARTTX3_Handler /* 39: UART 3 TX Handler */ + def_irq_handler UARTRX4_Handler /* 40: UART 4 RX Handler */ + def_irq_handler UARTTX4_Handler /* 41: UART 4 TX Handler */ + def_irq_handler UART0_Handler /* 42: UART 0 combined Handler */ + def_irq_handler UART1_Handler /* 43: UART 1 combined Handler */ + def_irq_handler UART2_Handler /* 44: UART 2 combined Handler */ + def_irq_handler UART3_Handler /* 45: UART 3 combined Handler */ + def_irq_handler UART4_Handler /* 46: UART 4 combined Handler */ + def_irq_handler UARTOVF_Handler /* 47: UART 0,1,2,3,4 Overflow Handler */ + def_irq_handler ETHERNET_Handler /* 48: Ethernet Handler */ + def_irq_handler I2S_Handler /* 49: I2S Handler */ + def_irq_handler TSC_Handler /* 50: Touch Screen Handler */ + def_irq_handler SPI0_Handler /* 51: SPI 0 Handler */ + def_irq_handler SPI1_Handler /* 52: SPI 1 Handler */ + def_irq_handler SPI2_Handler /* 53: SPI 2 Handler */ + def_irq_handler SPI3_Handler /* 54: SPI 3 Handler */ + def_irq_handler SPI4_Handler /* 55: SPI 4 Handler */ + def_irq_handler DMA0_ERROR_Handler /* 56: DMA 0 Error Handler */ + def_irq_handler DMA0_TC_Handler /* 57: DMA 0 Terminal Count Handler */ + def_irq_handler DMA0_Handler /* 58: DMA 0 Combined Handler */ + def_irq_handler DMA1_ERROR_Handler /* 59: DMA 1 Error Handler */ + def_irq_handler DMA1_TC_Handler /* 60: DMA 1 Terminal Count Handler */ + def_irq_handler DMA1_Handler /* 61: DMA 1 Combined Handler */ + def_irq_handler DMA2_ERROR_Handler /* 62: DMA 2 Error Handler */ + def_irq_handler DMA2_TC_Handler /* 63: DMA 2 Terminal Count Handler */ + def_irq_handler DMA2_Handler /* 64: DMA 2 Combined Handler */ + def_irq_handler DMA3_ERROR_Handler /* 65: DMA 3 Error Handler */ + def_irq_handler DMA3_TC_Handler /* 66: DMA 3 Terminal Count Handler */ + def_irq_handler DMA3_Handler /* 67: DMA 3 Combined Handler */ + def_irq_handler GPIO0_Handler /* 68: GPIO 0 Combined Handler */ + def_irq_handler GPIO1_Handler /* 69: GPIO 1 Combined Handler */ + def_irq_handler GPIO2_Handler /* 70: GPIO 2 Combined Handler */ + def_irq_handler GPIO3_Handler /* 71: GPIO 3 Combined Handler */ + def_irq_handler GPIO0_0_Handler /* 72: GPIO 0_0 Handler */ + def_irq_handler GPIO0_1_Handler /* 73: GPIO 0_1 Handler */ + def_irq_handler GPIO0_2_Handler /* 74: GPIO 0_2 Handler */ + def_irq_handler GPIO0_3_Handler /* 75: GPIO 0_3 Handler */ + def_irq_handler GPIO0_4_Handler /* 76: GPIO 0_4 Handler */ + def_irq_handler GPIO0_5_Handler /* 77: GPIO 0_5 Handler */ + def_irq_handler GPIO0_6_Handler /* 78: GPIO 0_6 Handler */ + def_irq_handler GPIO0_7_Handler /* 79: GPIO 0_7 Handler */ + def_irq_handler GPIO0_8_Handler /* 80: GPIO 0_8 Handler */ + def_irq_handler GPIO0_9_Handler /* 81: GPIO 0_9 Handler */ + def_irq_handler GPIO0_10_Handler /* 82: GPIO 0_10 Handler */ + def_irq_handler GPIO0_11_Handler /* 83: GPIO 0_11 Handler */ + def_irq_handler GPIO0_12_Handler /* 84: GPIO 0_12 Handler */ + def_irq_handler GPIO0_13_Handler /* 85: GPIO 0_13 Handler */ + def_irq_handler GPIO0_14_Handler /* 86: GPIO 0_14 Handler */ + def_irq_handler GPIO0_15_Handler /* 87: GPIO 0_15 Handler */ + def_irq_handler GPIO1_0_Handler /* 88: GPIO 1_0 Handler */ + def_irq_handler GPIO1_1_Handler /* 89: GPIO 1_1 Handler */ + def_irq_handler GPIO1_2_Handler /* 90: GPIO 1_2 Handler */ + def_irq_handler GPIO1_3_Handler /* 91: GPIO 1_3 Handler */ + def_irq_handler GPIO1_4_Handler /* 92: GPIO 1_4 Handler */ + def_irq_handler GPIO1_5_Handler /* 93: GPIO 1_5 Handler */ + def_irq_handler GPIO1_6_Handler /* 94: GPIO 1_6 Handler */ + def_irq_handler GPIO1_7_Handler /* 95: GPIO 1_7 Handler */ + def_irq_handler GPIO1_8_Handler /* 96: GPIO 1_8 Handler */ + def_irq_handler GPIO1_9_Handler /* 97: GPIO 1_9 Handler */ + def_irq_handler GPIO1_10_Handler /* 98: GPIO 1_10 Handler */ + def_irq_handler GPIO1_11_Handler /* 99: GPIO 1_11 Handler */ + def_irq_handler GPIO1_12_Handler /* 100: GPIO 1_12 Handler */ + def_irq_handler GPIO1_13_Handler /* 101: GPIO 1_13 Handler */ + def_irq_handler GPIO1_14_Handler /* 102: GPIO 1_14 Handler */ + def_irq_handler GPIO1_15_Handler /* 103: GPIO 1_15 Handler */ + def_irq_handler GPIO2_0_Handler /* 104: GPIO 2_0 Handler */ + def_irq_handler GPIO2_1_Handler /* 105: GPIO 2_1 Handler */ + def_irq_handler GPIO2_2_Handler /* 106: GPIO 2_2 Handler */ + def_irq_handler GPIO2_3_Handler /* 107: GPIO 2_3 Handler */ + def_irq_handler GPIO2_4_Handler /* 108: GPIO 2_4 Handler */ + def_irq_handler GPIO2_5_Handler /* 109: GPIO 2_5 Handler */ + def_irq_handler GPIO2_6_Handler /* 110: GPIO 2_6 Handler */ + def_irq_handler GPIO2_7_Handler /* 111: GPIO 2_7 Handler */ + def_irq_handler GPIO2_8_Handler /* 112: GPIO 2_8 Handler */ + def_irq_handler GPIO2_9_Handler /* 113: GPIO 2_9 Handler */ + def_irq_handler GPIO2_10_Handler /* 114: GPIO 2_10 Handler */ + def_irq_handler GPIO2_11_Handler /* 115: GPIO 2_11 Handler */ + def_irq_handler GPIO2_12_Handler /* 116: GPIO 2_12 Handler */ + def_irq_handler GPIO2_13_Handler /* 117: GPIO 2_13 Handler */ + def_irq_handler GPIO2_14_Handler /* 118: GPIO 2_14 Handler */ + def_irq_handler GPIO2_15_Handler /* 119: GPIO 2_15 Handler */ + def_irq_handler GPIO3_0_Handler /* 120: GPIO 3_0 Handler */ + def_irq_handler GPIO3_1_Handler /* 121: GPIO 3_1 Handler */ + def_irq_handler GPIO3_2_Handler /* 122: GPIO 3_2 Handler */ + def_irq_handler GPIO3_3_Handler /* 123: GPIO 3_3 Handler */ + + .end diff --git a/platform/ext/target/mps2/an539/device/source/system_core_init.c b/platform/ext/target/mps2/an539/device/source/system_core_init.c new file mode 100644 index 0000000000..42430b5e41 --- /dev/null +++ b/platform/ext/target/mps2/an539/device/source/system_core_init.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009-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. + */ + +/* + * This file is derivative of CMSIS V5.00 system_ARMCM23.c + */ + +#include <stdint.h> +#include "system_core_init.h" +#include "platform_description.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define XTAL (25000000UL) +#define SYSTEM_CLOCK (XTAL) +#define PERIPHERAL_CLOCK (XTAL) + +/*---------------------------------------------------------------------------- + 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) + extern uint32_t __Vectors; + SCB->VTOR = (uint32_t) &__Vectors; +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + +} diff --git a/platform/ext/target/mps2/an539/dummy_boot_seed.c b/platform/ext/target/mps2/an539/dummy_boot_seed.c new file mode 100644 index 0000000000..0d55100e79 --- /dev/null +++ b/platform/ext/target/mps2/an539/dummy_boot_seed.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-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 "platform/include/tfm_plat_boot_seed.h" + +/*! + * \def BOOT_SEED + * + * \brief Fixed value for boot seed used for test. + */ +#define BOOT_SEED 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, \ + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, \ + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, \ + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF + +static const uint8_t boot_seed[BOOT_SEED_SIZE] = {BOOT_SEED}; + +enum tfm_plat_err_t tfm_plat_get_boot_seed(uint32_t size, uint8_t *buf) +{ + /* FixMe: - This getter function must be ported per target platform. + * - Platform service shall provide an API to further interact this + * getter function to retrieve the boot seed. + */ + + uint32_t i; + uint8_t *p_dst = buf; + const uint8_t *p_src = boot_seed; + + if (size != BOOT_SEED_SIZE) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + for (i = size; i > 0; i--) { + *p_dst = *p_src; + p_src++; + p_dst++; + } + + return TFM_PLAT_ERR_SUCCESS; +} diff --git a/platform/ext/target/mps2/an539/dummy_crypto_keys.c b/platform/ext/target/mps2/an539/dummy_crypto_keys.c new file mode 100644 index 0000000000..7e39bfe641 --- /dev/null +++ b/platform/ext/target/mps2/an539/dummy_crypto_keys.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2017-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 "platform/include/tfm_plat_crypto_keys.h" +#include <stddef.h> + +/* FIXME: Functions in this file should be implemented by platform vendor. For + * the security of the storage system, it is critical to use a hardware unique + * key. For the security of the attestation, it is critical to use a unique key + * pair and keep the private key is secret. + */ + +#define TFM_KEY_LEN_BYTES 16 + +static const uint8_t sample_tfm_key[TFM_KEY_LEN_BYTES] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + +extern const enum ecc_curve_t initial_attestation_curve_type; +extern const uint8_t initial_attestation_private_key[]; +extern const uint32_t initial_attestation_private_key_size; +extern const uint8_t initial_attestation_public_x_key[]; +extern const uint32_t initial_attestation_public_x_key_size; +extern const uint8_t initial_attestation_public_y_key[]; +extern const uint32_t initial_attestation_public_y_key_size; + +extern const struct tfm_plat_rotpk_t device_rotpk[]; +extern const uint32_t rotpk_key_cnt; + +/** + * \brief Copy the key to the destination buffer + * + * \param[out] p_dst Pointer to buffer where to store the key + * \param[in] p_src Pointer to the key + * \param[in] size Length of the key + */ +static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size) +{ + uint32_t i; + + for (i = size; i > 0; i--) { + *p_dst = *p_src; + p_src++; + p_dst++; + } +} + +enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size) +{ + if(size > TFM_KEY_LEN_BYTES) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + copy_key(key, sample_tfm_key, size); + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t +tfm_plat_get_initial_attest_key(uint8_t *key_buf, + uint32_t size, + struct ecc_key_t *ecc_key, + enum ecc_curve_t *curve_type) +{ + uint8_t *key_dst; + const uint8_t *key_src; + uint32_t key_size; + uint32_t full_key_size = initial_attestation_private_key_size + + initial_attestation_public_x_key_size + + initial_attestation_public_y_key_size; + + if (size < full_key_size) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Set the EC curve type which the key belongs to */ + *curve_type = initial_attestation_curve_type; + + /* Copy the private key to the buffer, it MUST be present */ + key_dst = key_buf; + key_src = initial_attestation_private_key; + key_size = initial_attestation_private_key_size; + copy_key(key_dst, key_src, key_size); + ecc_key->priv_key = key_dst; + ecc_key->priv_key_size = key_size; + + /* Copy the x-coordinate of public key to the buffer, it MIGHT be present */ + if (initial_attestation_public_x_key_size != 0) { + key_dst = key_dst + key_size; + key_src = initial_attestation_public_x_key; + key_size = initial_attestation_public_x_key_size; + copy_key(key_dst, key_src, key_size); + ecc_key->pubx_key = key_dst; + ecc_key->pubx_key_size = key_size; + } else { + ecc_key->pubx_key = NULL; + ecc_key->pubx_key_size = 0; + } + + /* Copy the y-coordinate of public key to the buffer, it MIGHT be present */ + if (initial_attestation_public_y_key_size != 0) { + key_dst = key_dst + key_size; + key_src = initial_attestation_public_y_key; + key_size = initial_attestation_public_y_key_size; + copy_key(key_dst, key_src, key_size); + ecc_key->puby_key = key_dst; + ecc_key->puby_key_size = key_size; + } else { + ecc_key->puby_key = NULL; + ecc_key->puby_key_size = 0; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +#ifdef BL2 +enum tfm_plat_err_t +tfm_plat_get_rotpk_hash(uint8_t image_id, + uint8_t *rotpk_hash, + uint32_t *rotpk_hash_size) +{ + if(*rotpk_hash_size < ROTPK_HASH_LEN) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + if (image_id >= rotpk_key_cnt) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + *rotpk_hash_size = ROTPK_HASH_LEN; + copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size); + + return TFM_PLAT_ERR_SUCCESS; +} +#endif diff --git a/platform/ext/target/mps2/an539/dummy_device_id.c b/platform/ext/target/mps2/an539/dummy_device_id.c new file mode 100644 index 0000000000..a5ad100da9 --- /dev/null +++ b/platform/ext/target/mps2/an539/dummy_device_id.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018-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 "platform/include/tfm_plat_device_id.h" +#include <stddef.h> +/* + * NOTE: Functions in this file must be ported per target platform. + */ + +extern const uint8_t initial_attestation_raw_public_key_hash[]; +extern const uint32_t initial_attestation_raw_public_key_hash_size; + +static const uint8_t implementation_id[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, +}; + +static const uint8_t example_ean_13[] = "060456527282910010"; +/** + * \brief Copy the device specific ID to the destination buffer + * + * \param[out] p_dst Pointer to buffer where to store ID + * \param[in] p_src Pointer to the ID + * \param[in] size Length of the ID + */ +static inline void copy_id(uint8_t *p_dst, const uint8_t *p_src, size_t size) +{ + uint32_t i; + + for (i = size; i > 0; i--) { + *p_dst = *p_src; + p_src++; + p_dst++; + } +} + +/** + * Instance ID is mapped to EAT Universal Entity ID (UEID) + * This implementation creates the instance ID as follows: + * - byte 0: 0x01 indicates the type of UEID to be GUID + * - byte 1-32: Hash of attestation public key. Public key is hashed in raw + * format without any encoding. + */ +enum tfm_plat_err_t tfm_plat_get_instance_id(uint32_t *size, uint8_t *buf) +{ + uint8_t *p_dst; + const uint8_t *p_src = initial_attestation_raw_public_key_hash; + + if (*size < INSTANCE_ID_MAX_SIZE) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + buf[0] = 0x01; /* First byte is type byte: 0x01 indicates GUID */ + p_dst = &buf[1]; + + copy_id(p_dst, p_src, initial_attestation_raw_public_key_hash_size); + + /* Instance ID size: 1 type byte + size of public key hash */ + *size = initial_attestation_raw_public_key_hash_size + 1; + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_plat_get_implementation_id(uint32_t *size, + uint8_t *buf) +{ + const uint8_t *p_impl_id = implementation_id; + uint32_t impl_id_size = sizeof(implementation_id); + + if (*size < impl_id_size) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + copy_id(buf, p_impl_id, impl_id_size); + *size = impl_id_size; + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_plat_get_hw_version(uint32_t *size, uint8_t *buf) +{ + const uint8_t *p_hw_version = example_ean_13; + uint32_t hw_version_size = sizeof(example_ean_13) - 1; + + if (*size < hw_version_size) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + copy_id(buf, p_hw_version, hw_version_size); + *size = hw_version_size; + + return TFM_PLAT_ERR_SUCCESS; +} diff --git a/platform/ext/target/mps2/an539/dummy_nv_counters.c b/platform/ext/target/mps2/an539/dummy_nv_counters.c new file mode 100644 index 0000000000..63c27780ce --- /dev/null +++ b/platform/ext/target/mps2/an539/dummy_nv_counters.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +/* NOTE: This API should be implemented by platform vendor. For the security of + * the secure storage system's and the bootloader's rollback protection etc. it + * is CRITICAL to use a internal (in-die) persistent memory for multiple time + * programmable (MTP) non-volatile counters or use a One-time Programmable (OTP) + * non-volatile counters solution. + * + * The current software dummy implementation is not resistant to asynchronous + * power failures and should not be used in production code. It is exclusively + * for testing purposes. + */ + +#include "platform/include/tfm_plat_nv_counters.h" + +#include <limits.h> +#include "Driver_Flash.h" +#include "flash_layout.h" + +/* Compilation time checks to be sure the defines are well defined */ +#ifndef TFM_NV_COUNTERS_AREA_ADDR +#error "TFM_NV_COUNTERS_AREA_ADDR must be defined in flash_layout.h" +#endif + +#ifndef TFM_NV_COUNTERS_AREA_SIZE +#error "TFM_NV_COUNTERS_AREA_SIZE must be defined in flash_layout.h" +#endif + +#ifndef TFM_NV_COUNTERS_SECTOR_ADDR +#error "TFM_NV_COUNTERS_SECTOR_ADDR must be defined in flash_layout.h" +#endif + +#ifndef TFM_NV_COUNTERS_SECTOR_SIZE +#error "TFM_NV_COUNTERS_SECTOR_SIZE must be defined in flash_layout.h" +#endif + +#ifndef FLASH_DEV_NAME +#error "FLASH_DEV_NAME must be defined in flash_layout.h" +#endif +/* End of compilation time checks to be sure the defines are well defined */ + +#define SECTOR_OFFSET 0 +#define NV_COUNTER_SIZE sizeof(uint32_t) +#define INIT_VALUE_SIZE NV_COUNTER_SIZE +#define NV_COUNTERS_AREA_OFFSET (TFM_NV_COUNTERS_AREA_ADDR - \ + TFM_NV_COUNTERS_SECTOR_ADDR) + +#define NV_COUNTERS_INITIALIZED 0xC0DE0042 + +/* Import the CMSIS flash device driver */ +extern ARM_DRIVER_FLASH FLASH_DEV_NAME; + +enum tfm_plat_err_t tfm_plat_init_nv_counter(void) +{ + int32_t err; + uint32_t i; + uint32_t nbr_counters = ((TFM_NV_COUNTERS_AREA_SIZE - INIT_VALUE_SIZE) + / NV_COUNTER_SIZE); + uint32_t *p_nv_counter; + uint8_t sector_data[TFM_NV_COUNTERS_SECTOR_SIZE] = {0}; + + err = FLASH_DEV_NAME.Initialize(NULL); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Read the whole sector to be able to erase and write later in the flash */ + err = FLASH_DEV_NAME.ReadData(TFM_NV_COUNTERS_SECTOR_ADDR, sector_data, + TFM_NV_COUNTERS_SECTOR_SIZE); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Set the pointer to nv counters position */ + p_nv_counter = (uint32_t *)(sector_data + NV_COUNTERS_AREA_OFFSET); + + if (p_nv_counter[nbr_counters] == NV_COUNTERS_INITIALIZED) { + return TFM_PLAT_ERR_SUCCESS; + } + + /* Add watermark, at the end of the NV counters area, to indicate that NV + * counters have been initialized. + */ + p_nv_counter[nbr_counters] = NV_COUNTERS_INITIALIZED; + + /* Initialize all counters to 0 */ + for (i = 0; i < nbr_counters; i++) { + p_nv_counter[i] = 0; + } + + /* Erase sector before write in it */ + err = FLASH_DEV_NAME.EraseSector(TFM_NV_COUNTERS_SECTOR_ADDR); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Write in flash the in-memory block content after modification */ + err = FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_SECTOR_ADDR, sector_data, + TFM_NV_COUNTERS_SECTOR_SIZE); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_plat_read_nv_counter(enum tfm_nv_counter_t counter_id, + uint32_t size, uint8_t *val) +{ + int32_t err; + uint32_t flash_addr; + + if (size != NV_COUNTER_SIZE) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + flash_addr = TFM_NV_COUNTERS_AREA_ADDR + (counter_id * NV_COUNTER_SIZE); + + err = FLASH_DEV_NAME.ReadData(flash_addr, val, NV_COUNTER_SIZE); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_plat_set_nv_counter(enum tfm_nv_counter_t counter_id, + uint32_t value) +{ + int32_t err; + uint32_t *p_nv_counter; + uint8_t sector_data[TFM_NV_COUNTERS_SECTOR_SIZE]; + + /* Read the whole sector to be able to erase and write later in the flash */ + err = FLASH_DEV_NAME.ReadData(TFM_NV_COUNTERS_SECTOR_ADDR, sector_data, + TFM_NV_COUNTERS_SECTOR_SIZE); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Set the pointer to nv counter position */ + p_nv_counter = (uint32_t *)(sector_data + NV_COUNTERS_AREA_OFFSET + + (counter_id * NV_COUNTER_SIZE)); + + if (value != *p_nv_counter) { + + if (value > *p_nv_counter) { + *p_nv_counter = value; + } else { + return TFM_PLAT_ERR_INVALID_INPUT; + } + + /* Erase sector before write in it */ + err = FLASH_DEV_NAME.EraseSector(TFM_NV_COUNTERS_SECTOR_ADDR); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Write in flash the in-memory block content after modification */ + err = FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_SECTOR_ADDR, + sector_data, + TFM_NV_COUNTERS_SECTOR_SIZE); + if (err != ARM_DRIVER_OK) { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + } + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t tfm_plat_increment_nv_counter( + enum tfm_nv_counter_t counter_id) +{ + uint32_t security_cnt; + enum tfm_plat_err_t err; + + err = tfm_plat_read_nv_counter(counter_id, + sizeof(security_cnt), + (uint8_t *)&security_cnt); + if (err != TFM_PLAT_ERR_SUCCESS) { + return err; + } + + if (security_cnt == UINT32_MAX) { + return TFM_PLAT_ERR_MAX_VALUE; + } + + return tfm_plat_set_nv_counter(counter_id, security_cnt + 1u); +} diff --git a/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.c b/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.c new file mode 100644 index 0000000000..b6dd8e99f3 --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.c @@ -0,0 +1,655 @@ +/* + * 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 "mpc_sie200_drv.h" + +#include <stddef.h> + +#include "cmsis_compiler.h" + +#define MPC_SIE200_BLK_CFG_OFFSET 5U + +#define MPC_SIE200_CTRL_SEC_RESP (1UL << 4UL) /* MPC fault triggers a + * bus error + */ +#define MPC_SIE200_CTRL_AUTOINCREMENT (1UL << 8UL) /* BLK_IDX auto increment */ +#define MPC_SIE200_CTRL_SEC_LOCK_DOWN (1UL << 31UL) /* MPC Security lock down */ + +/* ARM MPC interrupt */ +#define MPC_SIE200_INT_EN 1UL +#define MPC_SIE200_INT_STAT 1UL + +/* ARM MPC state definitions */ +#define MPC_SIE200_INITIALIZED (1 << 0) + +/* Error code returned by the internal driver functions */ +enum mpc_sie200_intern_error_t { + MPC_SIE200_INTERN_ERR_NONE = MPC_SIE200_ERR_NONE, + MPC_SIE200_INTERN_ERR_NOT_IN_RANGE = MPC_SIE200_ERR_NOT_IN_RANGE, + MPC_SIE200_INTERN_ERR_NOT_ALIGNED = MPC_SIE200_ERR_NOT_ALIGNED, + MPC_SIE200_INTERN_ERR_INVALID_RANGE = MPC_SIE200_ERR_INVALID_RANGE, + MPC_INTERN_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE = + MPC_SIE200_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_SIE200_INTERN_ERR_BLK_IDX_TOO_HIGH = -1, + +}; + +/* ARM MPC memory mapped register access structure */ +struct mpc_sie200_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[997]; /* 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_sie200_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_sie200_dev_t* dev, + uint32_t addr, + const struct mpc_sie200_memory_range_t** addr_range) +{ + uint32_t i; + const struct mpc_sie200_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_sie200_intern_error_t + */ +static enum mpc_sie200_intern_error_t get_lut_masks( + struct mpc_sie200_dev_t* dev, + const uint32_t base, const uint32_t limit, + const struct mpc_sie200_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_sie200_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_sie200_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_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_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_SIE200_INTERN_ERR_NOT_IN_RANGE; + } + + /* Base and limit should be part of the same range */ + if(base_range != limit_range) { + return MPC_SIE200_INTERN_ERR_INVALID_RANGE; + } + *range = base_range; + + block_size = (1 << (p_mpc->blk_cfg + MPC_SIE200_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_SIE200_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_SIE200_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_SIE200_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_SIE200_INTERN_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_init(struct mpc_sie200_dev_t* dev, + const struct mpc_sie200_memory_range_t** range_list, + uint8_t nbr_of_ranges) +{ + if((range_list == NULL) || (nbr_of_ranges == 0)) { + return MPC_SIE200_INVALID_ARG; + } + + dev->data->range_list = range_list; + dev->data->nbr_of_ranges = nbr_of_ranges; + dev->data->state = MPC_SIE200_INITIALIZED; + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_get_block_size(struct mpc_sie200_dev_t* dev, + uint32_t* blk_size) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + if(blk_size == 0) { + return MPC_SIE200_INVALID_ARG; + } + + /* Calculate the block size in byte according to the manual */ + *blk_size = (1 << (p_mpc->blk_cfg + MPC_SIE200_BLK_CFG_OFFSET)); + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_config_region(struct mpc_sie200_dev_t* dev, + const uint32_t base, + const uint32_t limit, + enum mpc_sie200_sec_attr_t attr) +{ + enum mpc_sie200_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_sie200_memory_range_t* range; + uint32_t word_value; + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_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_SIE200_INTERN_ERR_NONE) { + /* Map internal error code lower than 0 to a generic errpr */ + if(error < 0) { + return MPC_SIE200_ERR_INVALID_RANGE; + } + return (enum mpc_sie200_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_SIE200_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_SIE200_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_SIE200_ERR_NONE; + } + + /* First word */ + word_value = p_mpc->blk_lutn; + if(attr == MPC_SIE200_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_SIE200_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_SIE200_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_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_get_region_config( + struct mpc_sie200_dev_t* dev, + uint32_t base, uint32_t limit, + enum mpc_sie200_sec_attr_t* attr) +{ + enum mpc_sie200_sec_attr_t attr_prev; + uint32_t block_size; + uint32_t block_size_mask; + enum mpc_sie200_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_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + const struct mpc_sie200_memory_range_t* range; + uint32_t word_value; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + if(attr == 0) { + return MPC_SIE200_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_SIE200_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_SIE200_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_SIE200_INTERN_ERR_NONE) { + /* Map internal error code lower than 0 to generic error */ + if(error < 0) { + return MPC_SIE200_ERR_INVALID_RANGE; + } + return (enum mpc_sie200_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_SIE200_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_SIE200_SEC_ATTR_MIXED; + } else { + *attr = MPC_SIE200_SEC_ATTR_NONSECURE; + } + return MPC_SIE200_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_SIE200_SEC_ATTR_SECURE; + } else if(word_value ^ first_word_mask) { + *attr = MPC_SIE200_SEC_ATTR_MIXED; + /* + * Bail out as the security attribute will be the same regardless + * of the configuration of other blocks + */ + return MPC_SIE200_ERR_NONE; + } else { + *attr = MPC_SIE200_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_SIE200_SEC_ATTR_SECURE; + } else if(word_value == 0xFFFFFFFF) { + *attr = MPC_SIE200_SEC_ATTR_NONSECURE; + } else { + *attr = MPC_SIE200_SEC_ATTR_MIXED; + return MPC_SIE200_ERR_NONE; + } + + /* If the attribute is different than the one found before, bail out */ + if(*attr != attr_prev) { + *attr = MPC_SIE200_SEC_ATTR_MIXED; + return MPC_SIE200_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_SIE200_SEC_ATTR_SECURE; + } else if(word_value ^ first_word_mask) { + *attr = MPC_SIE200_SEC_ATTR_MIXED; + return MPC_SIE200_ERR_NONE; + } else { + *attr = MPC_SIE200_SEC_ATTR_NONSECURE; + } + + if(*attr != attr_prev) { + *attr = MPC_SIE200_SEC_ATTR_MIXED; + return MPC_SIE200_ERR_NONE; + } + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_get_ctrl(struct mpc_sie200_dev_t* dev, + uint32_t* ctrl_val) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + if(ctrl_val == 0) { + return MPC_SIE200_INVALID_ARG; + } + + *ctrl_val = p_mpc->ctrl; + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_set_ctrl(struct mpc_sie200_dev_t* dev, + uint32_t mpc_ctrl) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + p_mpc->ctrl = mpc_ctrl; + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_get_sec_resp(struct mpc_sie200_dev_t* dev, + enum mpc_sie200_sec_resp_t* sec_rep) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + if(sec_rep == 0) { + return MPC_SIE200_INVALID_ARG; + } + + if(p_mpc->ctrl & MPC_SIE200_CTRL_SEC_RESP) { + *sec_rep = MPC_SIE200_RESP_BUS_ERROR; + return MPC_SIE200_ERR_NONE; + } + + *sec_rep = MPC_SIE200_RESP_RAZ_WI; + + return MPC_SIE200_ERR_NONE; +} + +enum mpc_sie200_error_t mpc_sie200_irq_enable(struct mpc_sie200_dev_t* dev) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + p_mpc->int_en |= MPC_SIE200_INT_EN; + + return MPC_SIE200_ERR_NONE; +} + +void mpc_sie200_irq_disable(struct mpc_sie200_dev_t* dev) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + p_mpc->int_en &= ~MPC_SIE200_INT_EN; +} + +void mpc_sie200_clear_irq(struct mpc_sie200_dev_t* dev) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + p_mpc->int_clear = MPC_SIE200_INT_EN; +} + +uint32_t mpc_sie200_irq_state(struct mpc_sie200_dev_t* dev) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + return (p_mpc->int_stat & MPC_SIE200_INT_STAT); +} + +enum mpc_sie200_error_t mpc_sie200_lock_down(struct mpc_sie200_dev_t* dev) +{ + struct mpc_sie200_reg_map_t* p_mpc = + (struct mpc_sie200_reg_map_t*)dev->cfg->base; + + if(!(dev->data->state & MPC_SIE200_INITIALIZED)) { + return MPC_SIE200_NOT_INIT; + } + + p_mpc->ctrl |= (MPC_SIE200_CTRL_AUTOINCREMENT + | MPC_SIE200_CTRL_SEC_LOCK_DOWN); + + return MPC_SIE200_ERR_NONE; +} diff --git a/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.h b/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.h new file mode 100644 index 0000000000..998a5f1089 --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/mpc_sie200_drv.h @@ -0,0 +1,285 @@ +/* + * 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_sie200_drv.h + * \brief Generic driver for ARM SIE 200 Memory Protection + * Controllers (MPC). + */ + +#ifndef __MPC_SIE_200_DRV_H__ +#define __MPC_SIE_200_DRV_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error code returned by the driver functions */ +enum mpc_sie200_error_t { + MPC_SIE200_ERR_NONE, /*!< No error */ + MPC_SIE200_INVALID_ARG, /*!< MPC invalid input arguments */ + MPC_SIE200_NOT_INIT, /*!< MPC not initialized */ + MPC_SIE200_ERR_NOT_IN_RANGE, /*!< Address does not belong to a range + * controlled by the MPC */ + MPC_SIE200_ERR_NOT_ALIGNED, /*!< Address is not aligned on the block size + * of this MPC + */ + MPC_SIE200_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_SIE200_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be + * accessed with the wanted + * security attributes + */ +}; + +/* Security attribute used in various place of the API */ +enum mpc_sie200_sec_attr_t { + MPC_SIE200_SEC_ATTR_SECURE, /*!< Secure attribute */ + MPC_SIE200_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_SIE200_SEC_ATTR_MIXED, +}; + +/* What can happen when trying to do an illegal memory access */ +enum mpc_sie200_sec_resp_t { + MPC_SIE200_RESP_RAZ_WI, /*!< Read As Zero, Write Ignored */ + MPC_SIE200_RESP_BUS_ERROR /*!< Bus error */ +}; + +/* Description of a memory range controlled by the MPC */ +struct mpc_sie200_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_sie200_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 200 device configuration structure */ +struct mpc_sie200_dev_cfg_t { + const uint32_t base; /*!< MPC base address */ +}; + +/* ARM MPC SIE 200 device data structure */ +struct mpc_sie200_dev_data_t { + /*!< Array of pointers to memory ranges controlled by the MPC */ + const struct mpc_sie200_memory_range_t** range_list; + uint8_t nbr_of_ranges; /*!< Number of memory ranges in the list */ + uint8_t state; /*!< Indicates if the MPC driver + * is initialized and enabled + */ + uint16_t reserved; /*!< 32 bits alignment */ +}; + +/* ARM MPC SIE 200 device structure */ +struct mpc_sie200_dev_t { + const struct mpc_sie200_dev_cfg_t* const cfg; /*!< MPC configuration */ + struct mpc_sie200_dev_data_t* const data; /*!< MPC data */ +}; + +/** + * \brief Initializes a MPC device. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * \param[in] range_list List of memory ranges controller by the MPC + * (\ref mpc_sie200_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_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_init(struct mpc_sie200_dev_t* dev, + const struct mpc_sie200_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_sie200_dev_t + * \param[out] blk_size MPC block size + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_get_block_size(struct mpc_sie200_dev_t* dev, + uint32_t* blk_size); + +/** + * \brief Configures a memory region (base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie200_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_sie200_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_SIE200_ATTR_MIXED. + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_config_region(struct mpc_sie200_dev_t* dev, + const uint32_t base, + const uint32_t limit, + enum mpc_sie200_sec_attr_t attr); + +/** + * \brief Gets a memory region configuration(base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie200_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_sie200_sec_attr_t + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_get_region_config( + struct mpc_sie200_dev_t* dev, + uint32_t base, + uint32_t limit, + enum mpc_sie200_sec_attr_t* attr); + +/** + * \brief Gets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * \param[out] ctrl_val Current MPC control value. + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_get_ctrl(struct mpc_sie200_dev_t* dev, + uint32_t* ctrl_val); + +/** + * \brief Sets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * \param[in] mpc_ctrl New MPC control value + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_set_ctrl(struct mpc_sie200_dev_t* dev, + uint32_t mpc_ctrl); + +/** + * \brief Gets the configured secure response. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * \param[out] sec_rep Configured secure response (\ref mpc_sie200_sec_resp_t). + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_get_sec_resp(struct mpc_sie200_dev_t* dev, + enum mpc_sie200_sec_resp_t* sec_rep); + +/** + * \brief Enables MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_irq_enable(struct mpc_sie200_dev_t* dev); + +/** + * \brief Disables MPC interrupt + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie200_irq_disable(struct mpc_sie200_dev_t* dev); + +/** + * \brief Clears MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie200_clear_irq(struct mpc_sie200_dev_t* dev); + +/** + * \brief Returns the MPC interrupt state. + * + * \param[in] dev MPC device \ref mpc_sie200_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_sie200_irq_state(struct mpc_sie200_dev_t* dev); + +/** + * \brief Locks down the MPC configuration. + * + * \param[in] dev MPC device \ref mpc_sie200_dev_t + * + * \return Returns error code as specified in \ref mpc_sie200_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie200_error_t mpc_sie200_lock_down(struct mpc_sie200_dev_t* dev); + +#ifdef __cplusplus +} +#endif +#endif /* __MPC_SIE_200_DRV_H__ */ diff --git a/platform/ext/target/mps2/an539/native_drivers/mpu_armv8m_drv.c b/platform/ext/target/mps2/an539/native_drivers/mpu_armv8m_drv.c new file mode 100644 index 0000000000..8b492972a4 --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/mpu_armv8m_drv.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017-2019, 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/an539/native_drivers/mpu_armv8m_drv.h b/platform/ext/target/mps2/an539/native_drivers/mpu_armv8m_drv.h new file mode 100644 index 0000000000..d427604f38 --- /dev/null +++ b/platform/ext/target/mps2/an539/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/an539/native_drivers/ppc_sse123_drv.c b/platform/ext/target/mps2/an539/native_drivers/ppc_sse123_drv.c new file mode 100644 index 0000000000..d7a6e20dc2 --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/ppc_sse123_drv.c @@ -0,0 +1,217 @@ +/* + * 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. + */ + +#include "ppc_sse123_drv.h" +#include "platform_regs.h" + +/* PPC state definition */ +#define PPC_SSE123_INITIALIZED 1U + +/* Default peripheral states */ +#define SECURE_AS_DEFAULT_PERIPHERAL_STATE true +#define PRIVILEGE_ONLY_AS_DEFAULT_PERIPHERAL_STATE true + +enum ppc_sse123_error_t ppc_sse123_init(struct ppc_sse123_dev_t* dev) +{ + struct sse123_spctrl_t* p_spctrl = + (struct sse123_spctrl_t*)dev->cfg->spctrl_base; + struct sse123_nspctrl_t* p_nspctrl = + (struct sse123_nspctrl_t*)dev->cfg->nspctrl_base; + + switch(dev->cfg->ppc_name) { + case PPC_SSE123_AHB_EXP0: + dev->data->spctrl_ns_ppc = &p_spctrl->ahbnsppcexp; + dev->data->spctrl_sp_ppc = &p_spctrl->ahbspppcexp; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->ahbnspppcexp; + dev->data->int_bit_mask = AHB_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE123_APB: + dev->data->spctrl_ns_ppc = &p_spctrl->apbnsppc; + dev->data->spctrl_sp_ppc = &p_spctrl->apbspppc; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->apbnspppc; + dev->data->int_bit_mask = APB_PPC0_INT_POS_MASK; + break; + case PPC_SSE123_APB_EXP0: + dev->data->spctrl_ns_ppc = &p_spctrl->apbnsppcexp0; + dev->data->spctrl_sp_ppc = &p_spctrl->apbspppcexp0; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->apbnspppcexp0; + dev->data->int_bit_mask = APB_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE123_APB_EXP1: + dev->data->spctrl_ns_ppc = &p_spctrl->apbnsppcexp1; + dev->data->spctrl_sp_ppc = &p_spctrl->apbspppcexp1; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->apbnspppcexp1; + dev->data->int_bit_mask = APB_PPCEXP1_INT_POS_MASK; + break; + case PPC_SSE123_APB_EXP2: + dev->data->spctrl_ns_ppc = &p_spctrl->apbnsppcexp2; + dev->data->spctrl_sp_ppc = &p_spctrl->apbspppcexp2; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->apbnspppcexp2; + dev->data->int_bit_mask = APB_PPCEXP2_INT_POS_MASK; + break; + case PPC_SSE123_APB_EXP3: + dev->data->spctrl_ns_ppc = &p_spctrl->apbnsppcexp3; + dev->data->spctrl_sp_ppc = &p_spctrl->apbspppcexp3; + dev->data->nspctrl_nsp_ppc = &p_nspctrl->apbnspppcexp3; + dev->data->int_bit_mask = APB_PPCEXP3_INT_POS_MASK; + break; + default: + return PPC_SSE123_ERR_INVALID_PARAM; + } + + dev->data->state = PPC_SSE123_INITIALIZED; + + return PPC_SSE123_ERR_NONE; +} + +enum ppc_sse123_error_t +ppc_sse123_config_privilege(struct ppc_sse123_dev_t* dev, uint8_t periph, + enum ppc_sse123_sec_attr_t sec_attr, + enum ppc_sse123_priv_attr_t priv_attr) +{ + if(dev->data->state != PPC_SSE123_INITIALIZED) { + return PPC_SSE123_ERR_NOT_INIT; + } + + if(sec_attr == PPC_SSE123_SECURE_ACCESS) { +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + /* Uses secure unprivileged access address (SPCTRL) to set privilege + * attribute + */ + if(priv_attr == PPC_SSE123_PRIV_ONLY_ACCESS) { + *(dev->data->spctrl_sp_ppc) &= ~(1U << periph); + } else { + *(dev->data->spctrl_sp_ppc) |= (1U << periph); + } +#else + /* Configuring security from Non-Secure domain is not permitted. */ + return PPC_SSE123_ERR_NOT_PERMITTED; +#endif + } else { + /* Uses non-secure unprivileged access address (NSPCTRL) to set + * privilege attribute */ + if(priv_attr == PPC_SSE123_PRIV_ONLY_ACCESS) { + *(dev->data->nspctrl_nsp_ppc) &= ~(1U << periph); + } else { + *(dev->data->nspctrl_nsp_ppc) |= (1U << periph); + } + } + + return PPC_SSE123_ERR_NONE; +} + +bool ppc_sse123_is_periph_priv_only(struct ppc_sse123_dev_t* dev, + uint8_t periph) +{ + if(dev->data->state != PPC_SSE123_INITIALIZED) { + /* 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->spctrl_ns_ppc) & (1U << periph)) == 0) { + /* Returns secure unprivileged access (SPCTRL) */ + return ((*(dev->data->spctrl_sp_ppc) & (1U << periph)) == 0); + } else { + /* Returns non-secure unprivileged access (NSPCTRL) */ + return ((*(dev->data->nspctrl_nsp_ppc) & (1U << periph)) == 0); + } +#else + /* Returns non-secure unprivileged access address (NSPCTRL) */ + return ((*(dev->data->nspctrl_nsp_ppc) & (1U << periph)) == 0); +#endif +} + +/* Secure only functions */ +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +enum ppc_sse123_error_t +ppc_sse123_config_security(struct ppc_sse123_dev_t* dev, uint8_t periph, + enum ppc_sse123_sec_attr_t sec_attr) +{ + if(dev->data->state != PPC_SSE123_INITIALIZED) { + return PPC_SSE123_ERR_NOT_INIT; + } + + if(sec_attr == PPC_SSE123_SECURE_ACCESS) { + *(dev->data->spctrl_ns_ppc) &= ~(1U << periph); + } else { + *(dev->data->spctrl_ns_ppc) |= (1U << periph); + } + + return PPC_SSE123_ERR_NONE; +} + +bool ppc_sse123_is_periph_secure(struct ppc_sse123_dev_t* dev, + uint8_t periph) +{ + if(dev->data->state != PPC_SSE123_INITIALIZED) { + /* Return true as the default configuration is secure */ + return true; + } + + return ((*(dev->data->spctrl_ns_ppc) & (1U << periph)) == 0); +} + +enum ppc_sse123_error_t ppc_sse123_irq_enable(struct ppc_sse123_dev_t* dev) +{ + struct sse123_spctrl_t* p_spctrl = + (struct sse123_spctrl_t*)dev->cfg->spctrl_base; + + if(dev->data->state != PPC_SSE123_INITIALIZED) { + return PPC_SSE123_ERR_NOT_INIT; + } + + p_spctrl->secppcinten |= dev->data->int_bit_mask; + + return PPC_SSE123_ERR_NONE; +} + +void ppc_sse123_irq_disable(struct ppc_sse123_dev_t* dev) +{ + struct sse123_spctrl_t* p_spctrl = + (struct sse123_spctrl_t*)dev->cfg->spctrl_base; + + if(dev->data->state == PPC_SSE123_INITIALIZED) { + p_spctrl->secppcinten &= ~(dev->data->int_bit_mask); + } +} + +void ppc_sse123_clear_irq(struct ppc_sse123_dev_t* dev) +{ + struct sse123_spctrl_t* p_spctrl = + (struct sse123_spctrl_t*)dev->cfg->spctrl_base; + + if(dev->data->state == PPC_SSE123_INITIALIZED) { + p_spctrl->secppcintclr = dev->data->int_bit_mask; + } +} + +bool ppc_sse123_irq_state(struct ppc_sse123_dev_t* dev) +{ + struct sse123_spctrl_t* p_spctrl = + (struct sse123_spctrl_t*)dev->cfg->spctrl_base; + + if(dev->data->state != PPC_SSE123_INITIALIZED) { + return false; + } + + return ((p_spctrl->secppcintstat & dev->data->int_bit_mask) != 0); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ diff --git a/platform/ext/target/mps2/an539/native_drivers/ppc_sse123_drv.h b/platform/ext/target/mps2/an539/native_drivers/ppc_sse123_drv.h new file mode 100644 index 0000000000..c9229abcb7 --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/ppc_sse123_drv.h @@ -0,0 +1,215 @@ +/* + * 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 ppc_sse123_drv.h + * \brief Generic driver for SSE-123 Peripheral Protection + * Controllers (PPC). + */ + +#ifndef __PPC_SSE_123_DRV_H__ +#define __PPC_SSE_123_DRV_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSE-123 PPC names */ +enum ppc_sse123_name_t { + PPC_SSE123_AHB_EXP0 = 0, /*!< Expansion 0 AHB PPC */ + PPC_SSE123_APB, /*!< APB PPC0 */ + PPC_SSE123_APB_EXP0, /*!< Expansion 0 APB PPC */ + PPC_SSE123_APB_EXP1, /*!< Expansion 1 APB PPC */ + PPC_SSE123_APB_EXP2, /*!< Expansion 2 APB PPC */ + PPC_SSE123_APB_EXP3, /*!< Expansion 3 APB PPC */ + SSE123_PPC_MAX_NUM +}; + +/* SSE-123 PPC device configuration structure */ +struct ppc_sse123_dev_cfg_t { + uint32_t const spctrl_base; /*!< Secure Privilege Control Block base */ + uint32_t const nspctrl_base; /*!< Non-Secure Privilege Control Block base */ + enum ppc_sse123_name_t ppc_name; +}; + +/* SSE-123 PPC device data structure */ +struct ppc_sse123_dev_data_t { + volatile uint32_t* spctrl_ns_ppc; /*!< Pointer to non-secure register */ + volatile uint32_t* spctrl_sp_ppc; /*!< Pointer to secure unprivileged + register */ + volatile uint32_t* nspctrl_nsp_ppc; /*!< Pointer to non-secure unprivileged + register */ + uint32_t int_bit_mask; /*!< Interrupt bit mask */ + uint32_t state; /*!< Indicates if the PPC driver + is initialized */ +}; + +/* SSE-123 PPC device structure */ +struct ppc_sse123_dev_t { + const struct ppc_sse123_dev_cfg_t* const cfg; /*!< PPC configuration */ + struct ppc_sse123_dev_data_t* const data; /*!< PPC data */ +}; + +/* Security attribute used to configure the peripherals */ +enum ppc_sse123_sec_attr_t { + PPC_SSE123_SECURE_ACCESS = 0, /*! Secure access */ + PPC_SSE123_NONSECURE_ACCESS, /*! Non-secure access */ +}; + +/* Privilege attribute used to configure the peripherals */ +enum ppc_sse123_priv_attr_t { + PPC_SSE123_PRIV_AND_NONPRIV_ACCESS = 0, /*! Privilege and NonPrivilege access */ + PPC_SSE123_PRIV_ONLY_ACCESS, /*! Privilege only access */ +}; + +/* ARM PPC error codes */ +enum ppc_sse123_error_t { + PPC_SSE123_ERR_NONE = 0, /*!< No error */ + PPC_SSE123_ERR_INVALID_PARAM, /*!< PPC invalid parameter error */ + PPC_SSE123_ERR_NOT_INIT, /*!< PPC not initialized */ + PPC_SSE123_ERR_NOT_PERMITTED /*!< PPC Operation not permitted */ +}; + +/** + * \brief Initialize the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * + * \return Returns error code as specified in \ref ppc_sse123_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse123_error_t ppc_sse123_init(struct ppc_sse123_dev_t* dev); + +/** + * \brief Configures privilege attribute through the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * \param[in] periph Peripheral position in 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_sse123_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse123_error_t +ppc_sse123_config_privilege(struct ppc_sse123_dev_t* dev, uint8_t periph, + enum ppc_sse123_sec_attr_t sec_attr, + enum ppc_sse123_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_sse123_dev_t + * \param[in] periph Peripheral position in 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_sse123_is_periph_priv_only(struct ppc_sse123_dev_t* dev, + uint8_t periph); + +/* 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_sse123_dev_t + * \param[in] periph Peripheral position in the PPC. + * \param[in] sec_attr Secure attribute value. + * + * \return Returns error code as specified in \ref ppc_sse123_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse123_error_t +ppc_sse123_config_security(struct ppc_sse123_dev_t* dev, uint8_t periph, + enum ppc_sse123_sec_attr_t sec_attr); + +/** + * \brief Checks if the peripheral is configured as secure or non-secure. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * \param[in] periph Peripheral position in 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_sse123_is_periph_secure(struct ppc_sse123_dev_t* dev, + uint8_t periph); + +/** + * \brief Enables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * + * \return Returns error code as specified in \ref ppc_sse123_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse123_error_t ppc_sse123_irq_enable(struct ppc_sse123_dev_t* dev); + +/** + * \brief Disables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse123_irq_disable(struct ppc_sse123_dev_t* dev); + +/** + * \brief Clears PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse123_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse123_clear_irq(struct ppc_sse123_dev_t* dev); + +/** + * \brief Returns the PPC interrupt state. + * + * \param[in] dev PPC device \ref ppc_sse123_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_sse123_irq_state(struct ppc_sse123_dev_t* dev); + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE_123_DRV_H__ */ diff --git a/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.c b/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.c new file mode 100644 index 0000000000..832bb0292f --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2019 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file syscounter_armv8-m_cntrl_drv.c + * + * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase + * Frame + * + * This System Counter is a 64-bit up-counter, generating the physical + * count for System Timer. + * + * Main features: + * - Enabled/disable and Set/Get the 64-bit upcounter + * - 2 scaling register for the 2 clock sources + * - These registers are used to pre-program the scaling values so + * that when hardware based clock switching is implemented there is no + * need to program the scaling increment value each time when clock is + * switched. + * - When counter scaling is enabled, ScaleVal is the amount added to the + * Counter Count Value for every period of the counter as determined + * by 1/Frequency from the current operating frequency of the system + * counter (the “counter tick”). + * - ScaleVal is expressed as an unsigned fixed-point number with + * a 8 bit integer value and a 24-bit fractional value + * - Interrupt for error detection + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + */ + +#include "syscounter_armv8-m_cntrl_drv.h" + +/** Setter bit manipulation macro */ +#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX))) +/** Clearing bit manipulation macro */ +#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX))) +/** Getter bit manipulation macro */ +#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX)))) +/** Clear-and-Set bit manipulation macro */ +#define ASSIGN_BIT(WORD, BIT_INDEX, VALUE) \ + (WORD = ((WORD & ~(1U << (BIT_INDEX))) | (VALUE << (BIT_INDEX)))) +/** Getter bit-field manipulation macro */ +#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) \ + ((WORD & BIT_MASK) >> BIT_OFFSET) +/** Bit mask for given width bit-field manipulation macro */ +#define BITMASK(width) ((1u<<(width))-1) + +/** + * \brief CNTControlBase Register map structure + */ +struct cnt_control_base_reg_map_t { + volatile uint32_t cntcr; + /*!< Offset: 0x000 (R/W) Counter Control Register */ + volatile const uint32_t cntsr; + /*!< Offset: 0x004 (RO) Counter Status Register */ + volatile uint32_t cntcv_low; + /*!< Offset: 0x008 (R/W) Counter Count Value [31:0] Register */ + volatile uint32_t cntcv_high; + /*!< Offset: 0x00C (R/W) Counter Count Value [63:32] Register */ + volatile uint32_t cntscr; + /*!< Offset: 0x010 (R/W) Counter Scale Register + * Aliased with CNTSCR0, meaning that either addresses of CNTSCR and + * CNTSCR0 will physically access a single register + */ + volatile const uint32_t reserved0[2]; + /*!< Offset: 0x014-0x018 Reserved (RAZWI) */ + volatile const uint32_t cntid; + /*!< Offset: 0x01C (RO) Counter ID Register */ + volatile const uint32_t reserved1[40]; + /*!< Offset: 0x020-0x0BC Reserved (RAZWI) */ + volatile const uint32_t reserved2[4]; + /*!< Offset: 0x0C0-0x0CC Reserved (RAZWI) */ + volatile uint32_t cntscr0; + /*!< Offset: 0x0D0 (R/W) Counter Scale Register 0 */ + volatile uint32_t cntscr1; + /*!< Offset: 0x0D4 (R/W) Counter Scale Register 1 */ + volatile const uint32_t reserved3[958]; + /*!< Offset: 0x0D8-0xFCC Reserved (RAZWI) */ + volatile const uint32_t cntpidr4; + /*!< Offset: 0xFD0 (RO) Peripheral ID Register */ + volatile const uint32_t reserved4[3]; + /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */ + volatile const uint32_t cntpidr0; + /*!< Offset: 0xFE0 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr1; + /*!< Offset: 0xFE4 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr2; + /*!< Offset: 0xFE8 (RO) Peripheral ID Register */ + volatile const uint32_t cntpidr3; + /*!< Offset: 0xFEC (RO) Peripheral ID Register */ + volatile const uint32_t cntcidr0; + /*!< Offset: 0xFF0 (RO) Component ID Register */ + volatile const uint32_t cntcidr1; + /*!< Offset: 0xFF4 (RO) Component ID Register */ + volatile const uint32_t cntcidr2; + /*!< Offset: 0xFF8 (RO) Component ID Register */ + volatile const uint32_t cntcidr3; + /*!< Offset: 0xFFC (RO) Component ID Register */ +}; + +/** + * \brief Counter Control Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTCR_EN_OFF 0u + /*!< Counter Control Register Enable Counter bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF 1u + /*!< Counter Control Register Halt On Debug bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF 2u + /*!< Counter Control Register Scale enable bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF 3u + /*!< Counter Control Register Interrupt mask bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF 4u + /*!< Counter Control Register PSLVERR disable bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF 5u + /*!< Counter Control Register Interrupt Clear bit field offset */ + +/** + * \brief Counter Status Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF 1u + /*!< Counter Status Register Halt-on-Debug bit field offset */ + +/** + * \brief Counter ID Register bit fields + */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF 0u + /*!< Counter ID Register Counter Scaling is implemented bit field offset */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF 16u + /*!< Counter ID Register Clock switching is implemented bit field offset */ + +/*! Counter ID Register Clock source */ +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF 17u +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH 2u +#define SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK \ + (BITMASK(SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_WIDTH) \ + << SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF) + +#define SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF 19u + /*!< Counter ID Register Override counter enable condition for + * writing to CNTSCR registers bit offset + */ + +enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + enum syscounter_armv8_m_cntrl_error_t result = SYSCOUNTER_ARMV8_M_ERR_NONE; + + if (dev->data->is_initialized == false) { + syscounter_armv8_m_cntrl_disable_counter(dev); + if (syscounter_armv8_m_cntrl_is_counter_scaling_implemented(dev)) { + result = syscounter_armv8_m_cntrl_set_counter_scale_value( + dev, SYSCOUNTER_ARMV8_M_SCALE_NR_0, dev->cfg->scale0); + if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) { + return result; + } + result = syscounter_armv8_m_cntrl_set_counter_scale_value( + dev, SYSCOUNTER_ARMV8_M_SCALE_NR_1, dev->cfg->scale1); + if (result != SYSCOUNTER_ARMV8_M_ERR_NONE) { + return result; + } + } + syscounter_armv8_m_cntrl_set_counter_value(dev, + SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL); + syscounter_armv8_m_cntrl_disable_interrupt(dev); + syscounter_armv8_m_cntrl_disable_scale(dev); + + syscounter_armv8_m_cntrl_enable_counter(dev); + dev->data->is_initialized = true; + } + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} + +void syscounter_armv8_m_cntrl_uninit( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + if (dev->data->is_initialized == true) { + syscounter_armv8_m_cntrl_disable_counter(dev); + syscounter_armv8_m_cntrl_disable_interrupt(dev); + syscounter_armv8_m_cntrl_set_counter_value(dev, + SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL); + dev->data->is_initialized = false; + } +} + +void syscounter_armv8_m_cntrl_enable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +void syscounter_armv8_m_cntrl_disable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +bool syscounter_armv8_m_cntrl_is_counter_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_EN_OFF); +} + +void syscounter_armv8_m_cntrl_enable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +void syscounter_armv8_m_cntrl_disable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_HDBG_OFF); +} + +void syscounter_armv8_m_cntrl_enable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +void syscounter_armv8_m_cntrl_disable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +bool syscounter_armv8_m_cntrl_is_scale_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_SCEN_OFF); +} + +void syscounter_armv8_m_cntrl_enable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +void syscounter_armv8_m_cntrl_disable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +bool syscounter_armv8_m_cntrl_is_interrupt_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_INTRMASK_OFF); +} + +void syscounter_armv8_m_cntrl_enable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + SET_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +void syscounter_armv8_m_cntrl_disable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +bool syscounter_armv8_m_cntrl_is_pslverr_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntcr, + SYSCOUNTER_ARMV8M_CNTCR_PSLVERRDIS_OFF); +} + +void syscounter_armv8_m_cntrl_clear_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + CLR_BIT(p_cnt->cntcr, SYSCOUNTER_ARMV8M_CNTCR_INTRCLR_OFF); +} + +bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntsr, + SYSCOUNTER_ARMV8M_CNTSR_DBGH_OFF); +} + +uint64_t syscounter_armv8_m_cntrl_get_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + uint32_t high = 0; + uint32_t low = 0; + uint32_t high_prev = 0; + uint64_t value = 0; + + /* Make sure the 64-bit read will be atomic to avoid overflow between + * the low and high registers read + */ + high = p_cnt->cntcv_high; + do { + high_prev = high; + low = p_cnt->cntcv_low; + high = p_cnt->cntcv_high; + }while(high != high_prev); + + value = low | + (((uint64_t)high) << SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH); + return value; +} + +void syscounter_armv8_m_cntrl_set_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + uint64_t value) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + p_cnt->cntcv_low = value & UINT32_MAX; + p_cnt->cntcv_high = value >> SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH; +} + +bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSC_OFF); +} + +bool syscounter_armv8_m_cntrl_is_clock_switching_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTCS_OFF); +} + +enum syscounter_armv8_m_cntrl_selclk_t +syscounter_armv8_m_cntrl_get_clock_source( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return (enum syscounter_armv8_m_cntrl_selclk_t) + GET_BIT_FIELD(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_MASK, + SYSCOUNTER_ARMV8M_CNTID_CNTSELCLK_OFF); +} + +enum syscounter_armv8_m_cntrl_cntscr_ovr_t +syscounter_armv8_m_cntrl_get_override_cntscr( + struct syscounter_armv8_m_cntrl_dev_t* dev) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + return (enum syscounter_armv8_m_cntrl_cntscr_ovr_t) + GET_BIT(p_cnt->cntid, + SYSCOUNTER_ARMV8M_CNTID_CNTSCR_OVR_OFF); +} + +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_get_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t *val) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + + switch (nr) { + case SYSCOUNTER_ARMV8_M_SCALE_NR_0: + val->integer = p_cnt->cntscr0 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + val->fixed_point_fraction = p_cnt->cntscr0 & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX; + break; + case SYSCOUNTER_ARMV8_M_SCALE_NR_1: + val->integer = p_cnt->cntscr1 >> SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + val->fixed_point_fraction = p_cnt->cntscr1 & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX; + break; + default: + val->integer = 0; + val->fixed_point_fraction = 0; + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} + +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_set_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t val) +{ + struct cnt_control_base_reg_map_t* p_cnt = + (struct cnt_control_base_reg_map_t*)dev->cfg->base; + uint32_t reg_val = 0; + + if ((syscounter_armv8_m_cntrl_get_override_cntscr(dev) == + SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED) && + syscounter_armv8_m_cntrl_is_counter_enabled(dev)) { + return SYSCOUNTER_ARMV8_M_ERR_INVALID; + } + if (val.integer > SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX || + val.fixed_point_fraction > SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX) { + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + reg_val = val.integer << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF; + reg_val |= (val.fixed_point_fraction & + SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX); + + switch (nr) { + case SYSCOUNTER_ARMV8_M_SCALE_NR_0: + p_cnt->cntscr0 = reg_val; + break; + case SYSCOUNTER_ARMV8_M_SCALE_NR_1: + p_cnt->cntscr1 = reg_val; + break; + default: + return SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG; + } + + return SYSCOUNTER_ARMV8_M_ERR_NONE; +} diff --git a/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.h b/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.h new file mode 100644 index 0000000000..e84786d23c --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/syscounter_armv8-m_cntrl_drv.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2019 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file syscounter_armv8-m_cntrl_drv.h + * + * \brief Driver for Armv8-M System Counter Control, covering CNTControlBase + * Frame + * + * This System Counter is a 64-bit up-counter, generating the physical + * count for System Timer. + * + * Main features: + * - Enable/disable and Set/Get the 64-bit upcounter + * - 2 scaling registers for the 2 clock sources + * - These registers are used to pre-program the scaling values so + * that when hardware based clock switching is implemented there is no + * need to program the scaling increment value each time when clock is + * switched. + * - When counter scaling is enabled, ScaleVal is the value added to the + * Counter Count Value for every period of the counter as determined + * by 1/Frequency from the current operating frequency of the system + * counter (the “counter tick”). + * - ScaleVal is expressed as an unsigned fixed-point number with + * a 8 bit integer value and a 24-bit fractional value + * - Interrupt for error detection + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + */ + +#ifndef __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ +#define __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSCOUNTER_ARMV8_M_CNTRL_REGISTER_BIT_WIDTH 32u + /*!< Armv8-M System Counter Control registers bit width */ + +#define SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL 0u + /*!< Armv8-M System Counter Control default counter init value */ + +/** + * \brief Armv8-M System Counter Control scaling value + */ +struct syscounter_armv8_m_cntrl_scale_val_t { + uint32_t integer; /* 8 bit */ + uint32_t fixed_point_fraction; /* 24 bit */ +}; + +/** + * \brief Armv8-M System Counter Control scaling value macros * + * 8 bit integer and 24 bit fixed point fractional value + */ +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX UINT8_MAX +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF 24u +#define SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX \ + ((1u << SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_OFF) - 1u) + +/** + * \brief Armv8-M System Counter Control device configuration structure + */ +struct syscounter_armv8_m_cntrl_dev_cfg_t { + const uint32_t base; + /*!< Armv8-M System Counter Control device base address */ + struct syscounter_armv8_m_cntrl_scale_val_t scale0; + /*!< Default clock scaling value for Clock source 0 */ + struct syscounter_armv8_m_cntrl_scale_val_t scale1; + /*!< Default clock scaling value for Clock source 1 */ +}; + +/** + * \brief Armv8-M System Counter Control device data structure + */ +struct syscounter_armv8_m_cntrl_dev_data_t { + bool is_initialized; +}; + +/** + * \brief Armv8-M System Counter Control device structure + */ +struct syscounter_armv8_m_cntrl_dev_t { + const struct syscounter_armv8_m_cntrl_dev_cfg_t* const cfg; + /*!< Armv8-M System Counter Control configuration structure */ + struct syscounter_armv8_m_cntrl_dev_data_t* const data; + /*!< Armv8-M System Counter Control data structure */ +}; + +/** + * \brief Armv8-M System Counter Control error enumeration types + */ +enum syscounter_armv8_m_cntrl_error_t { + SYSCOUNTER_ARMV8_M_ERR_NONE = 0u, + SYSCOUNTER_ARMV8_M_ERR_INVALID = 1u, + SYSCOUNTER_ARMV8_M_ERR_INVALID_ARG = 2u +}; + +/** + * \brief Armv8-M System Counter Control scaling number for each clock sources + */ +enum syscounter_armv8_m_cntrl_scale_nr_t { + SYSCOUNTER_ARMV8_M_SCALE_NR_0 = 0u, + /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK0 */ + SYSCOUNTER_ARMV8_M_SCALE_NR_1 = 1u + /*!< Scaling for \ref SYSCOUNTER_ARMV8_M_SELCLK_CLK1 */ +}; + +/** + * \brief Clock select values + */ +enum syscounter_armv8_m_cntrl_selclk_t { + SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID0 = 0u, + /*!< Clock select invalid value */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK0 = 1u, + /*!< Clock select clock source 0 */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK1 = 2u, + /*!< Clock select clock source 1 */ + SYSCOUNTER_ARMV8_M_SELCLK_CLK_INVALID1 = 3u + /*!< Clock select invalid value */ +}; + +/** + * \brief Override counter enable condition for writing to CNTSCR registers + * + */ +enum syscounter_armv8_m_cntrl_cntscr_ovr_t { + SYSCOUNTER_ARMV8_M_CNTSCR_IF_DISABLED = 0u, + /*!< Scaling registers can be written only when counter is disabled */ + SYSCOUNTER_ARMV8_M_CNTSCR_ALWAYS = 1u + /*!< CNTSCR can be written regardless of counter enabled or disabled */ +}; + +/** + * \brief Initializes counter to a known default state, which is: + * - counter is enabled, so starts counting + * - interrupt is disabled + * - counter reset to default reset value + * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL + * - scaling is disabled + * - scaling registers are set to the set values: + * \ref struct syscounter_armv8_m_cntrl_dev_cfg_t + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t syscounter_armv8_m_cntrl_init( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Uninitializes counter to a known default state, which is: + * - counter is disabled, so stops counting + * - interrupt is disabled + * - counter reset to default reset value + * \ref SYSCOUNTER_ARMV8_M_DEFAULT_INIT_CNT_VAL + * - scaling is disabled + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_uninit( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables the counter, so counter starts counting + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables the counter, so counter stops counting + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_counter( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls counter enable status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables Halt-On-Debug feature + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables Halt-On-Debug feature + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_halt_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls Halt-On-Debug enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_halt_on_debug_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables scaling + * The used scaling register is depending on the used HW clock source. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables scaling + * Counter count will be incremented by default 1 for each ticks. + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_scale( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls scaling enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_scale_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables interrupt + * + * There are 2 possible reasons for error notification generation from + * the Counter: + * 1. Security attribute mismatch between register access and security + * attribute of the CONTROL frame + * 2. Address decode error within a given frame + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables interrupt + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls interrupt enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_interrupt_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Enables PSLVERR output + * + * PSLVERR output signal on APB bus dynamically generated for the + * following error: + * For security attribute mismatch between register access and security + * attribute of the CONTROL frame + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_enable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Disables PSLVERR output + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_disable_pslverr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls PSLVERR output enablement status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_pslverr_enabled( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Clears interrupt pending flag + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_clear_interrupt( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls Halt-On-Debug status + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if counter is halted, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_halted_on_debug( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Read counter value + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return 64 bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t syscounter_armv8_m_cntrl_get_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Writes counter value + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] value 64 bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +void syscounter_armv8_m_cntrl_set_counter_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + uint64_t value); + +/** + * \brief Polls whether scaling is implemented + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_counter_scaling_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Polls whether HW based clock switching is implemented + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool syscounter_armv8_m_cntrl_is_clock_switching_implemented( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads which clock source is being used + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Clock source \ref enum syscounter_armv8_m_cntrl_selclk_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_selclk_t + syscounter_armv8_m_cntrl_get_clock_source( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads scaling register can be overriden anytime + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * + * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_cntscr_ovr_t + syscounter_armv8_m_cntrl_get_override_cntscr( + struct syscounter_armv8_m_cntrl_dev_t* dev); + +/** + * \brief Reads scaling register + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] nr Index of scaling register to read + * \ref enum syscounter_armv8_m_cntrl_scale_nr_t + * \param[out] nr Pointer to structure to read the scale value + * \ref struct syscounter_armv8_m_cntrl_scale_val_t + * + * \return Override condition \ref enum syscounter_armv8_m_cntrl_cntscr_ovr_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_get_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t *val); + +/** + * \brief Writes scaling register + * + * \param[in] dev Counter device struct \ref syscounter_armv8_m_cntrl_dev_t + * \param[in] nr Index of scaling register to write + * \ref enum syscounter_armv8_m_cntrl_scale_nr_t + * \param[in] Scale value structure + * \ref struct syscounter_armv8_m_cntrl_scale_val_t + * + * \return Error status \ref enum syscounter_armv8_m_cntrl_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum syscounter_armv8_m_cntrl_error_t +syscounter_armv8_m_cntrl_set_counter_scale_value( + struct syscounter_armv8_m_cntrl_dev_t* dev, + enum syscounter_armv8_m_cntrl_scale_nr_t nr, + struct syscounter_armv8_m_cntrl_scale_val_t val); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSCOUNTER_ARMV8_M_CNTRL_DRV_H__ */ diff --git a/platform/ext/target/mps2/an539/native_drivers/systimer_armv8-m_drv.c b/platform/ext/target/mps2/an539/native_drivers/systimer_armv8-m_drv.c new file mode 100644 index 0000000000..1c4b5a203c --- /dev/null +++ b/platform/ext/target/mps2/an539/native_drivers/systimer_armv8-m_drv.c @@ -0,0 +1,345 @@ +/* + * 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.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/an539/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/mps2/an539/native_drivers/systimer_armv8-m_drv.h new file mode 100644 index 0000000000..d14d2f79e2 --- /dev/null +++ b/platform/ext/target/mps2/an539/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/an539/native_drivers/uart_cmsdk_drv.c b/platform/ext/target/mps2/an539/native_drivers/uart_cmsdk_drv.c new file mode 100644 index 0000000000..c3d1230052 --- /dev/null +++ b/platform/ext/target/mps2/an539/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/an539/native_drivers/uart_cmsdk_drv.h b/platform/ext/target/mps2/an539/native_drivers/uart_cmsdk_drv.h new file mode 100644 index 0000000000..2d3278ef65 --- /dev/null +++ b/platform/ext/target/mps2/an539/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/an539/partition/flash_layout.h b/platform/ext/target/mps2/an539/partition/flash_layout.h new file mode 100644 index 0000000000..d60e923f63 --- /dev/null +++ b/platform/ext/target/mps2/an539/partition/flash_layout.h @@ -0,0 +1,216 @@ +/* + * 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 __FLASH_LAYOUT_H__ +#define __FLASH_LAYOUT_H__ + +/* Flash layout on MPS2 AN539 with BL2 (multiple image boot): + * + * 0x0000_0000 BL2 - MCUBoot (0.5 MB) + * 0x0008_0000 Secure image primary slot (0.5 MB) + * 0x0010_0000 Non-secure image primary slot (0.5 MB) + * 0x0018_0000 Secure image secondary slot (0.5 MB) + * 0x0020_0000 Non-secure image secondary slot (0.5 MB) + * 0x0028_0000 Scratch area (0.5 MB) + * 0x0030_0000 Secure Storage Area (0.02 MB) + * 0x0030_5000 NV counters area (24 Bytes) + * 0x0030_5018 Unused (0.980 MB) + * + * Flash layout on MPS2 AN539 with BL2 (single image boot): + * + * 0x0000_0000 BL2 - MCUBoot (0.5 MB) + * 0x0008_0000 Primary image area (1 MB): + * 0x0008_0000 Secure image primary + * 0x0010_0000 Non-secure image primary + * 0x0018_0000 Secondary image area (1 MB): + * 0x0018_0000 Secure image secondary + * 0x0020_0000 Non-secure image secondary + * 0x0028_0000 Scratch area (1 MB) + * 0x0038_0000 Secure Storage Area (0.02 MB) + * 0x0038_5000 NV counters area (24 Bytes) + * 0x0038_5018 Unused (0.480 MB) + * + * Flash layout on MPS2 AN539, if BL2 not defined: + * + * 0x0000_0000 Secure image (0.5 MB) + * 0x0010_0000 Non-secure image (0.5 MB) + */ + +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) + +/* 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 (0x80000) /* S partition: 512 KB */ +#define FLASH_NS_PARTITION_SIZE (0x80000) /* NS partition: 512 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 */ + +/* Flash layout info for BL2 bootloader */ +/* Same as FLASH0_BASE_S */ +#define FLASH_BASE_ADDRESS (0x10000000) + +/* 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 (0x80000) /* 512 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 (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE) +#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. */ +/* The maximum number of status entries must be at least 2. For more + * information see the MCUBoot issue: + * https://github.com/JuulLabs-OSS/mcuboot/issues/427. + */ +#define BOOT_STATUS_MAX_ENTRIES MAX(2, \ + ((FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) / \ + FLASH_AREA_SCRATCH_SIZE)) +/* Maximum number of image sectors supported by the bootloader. */ +#define BOOT_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 (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE) +#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. */ +/* The maximum number of status entries must be at least 2. For more + * information see the MCUBoot issue: + * https://github.com/JuulLabs-OSS/mcuboot/issues/427. + */ +#define BOOT_STATUS_MAX_ENTRIES MAX(2, \ + (FLASH_MAX_PARTITION_SIZE / \ + FLASH_AREA_SCRATCH_SIZE)) +/* Maximum number of image sectors supported by the bootloader. */ +#define BOOT_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 */ + +/* 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 */ + +/* NV Counters definitions */ +#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_SST_AREA_OFFSET + \ + FLASH_SST_AREA_SIZE) +#define FLASH_NV_COUNTERS_AREA_SIZE (0x18) /* 24 Bytes */ + +/* 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 + * flash base address instead of the full flash address. + */ +#define SST_FLASH_AREA_ADDR FLASH_SST_AREA_OFFSET +#define SST_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE +/* The sectors must be in consecutive memory location */ +#define SST_NBR_OF_SECTORS (FLASH_SST_AREA_SIZE / SST_SECTOR_SIZE) +/* 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) + +/* NV Counters definitions */ +#define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET +#define TFM_NV_COUNTERS_AREA_SIZE FLASH_NV_COUNTERS_AREA_SIZE +#define TFM_NV_COUNTERS_SECTOR_ADDR FLASH_NV_COUNTERS_AREA_OFFSET +#define TFM_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE + +/* Use Internal SSRAM1 to store code */ +#define S_ROM_ALIAS_BASE (0x10000000) +#define NS_ROM_ALIAS_BASE (0x00000000) + +/* Use Internal SSRAM2 to store RW data */ +#define S_RAM_ALIAS_BASE (0x38000000) +#define NS_RAM_ALIAS_BASE (0x28000000) + +#define TOTAL_RAM_SIZE (0x00200000) /* 2MiB - SSRAM2 */ + +/* 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_RAM_ALIAS_BASE +#define BOOT_TFM_SHARED_DATA_SIZE (0x400) + +#endif /* __FLASH_LAYOUT_H__ */ diff --git a/platform/ext/target/mps2/an539/partition/region_defs.h b/platform/ext/target/mps2/an539/partition/region_defs.h new file mode 100644 index 0000000000..cab621a1be --- /dev/null +++ b/platform/ext/target/mps2/an539/partition/region_defs.h @@ -0,0 +1,146 @@ +/* + * 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 __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "flash_layout.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 AN539 MPS2 FPGA image. 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 + * 0x7_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 (0x10000) /* 64 KB */ +#else +/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */ +#define BL2_HEADER_SIZE (0x0) +#define BL2_TRAILER_SIZE (0x10400) +#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 (0x380) + +/* Alias definitions for secure and non-secure areas*/ +#define S_ROM_ALIAS(x) (S_ROM_ALIAS_BASE + (x)) +#define NS_ROM_ALIAS(x) (NS_ROM_ALIAS_BASE + (x)) + +#define S_RAM_ALIAS(x) (S_RAM_ALIAS_BASE + (x)) +#define NS_RAM_ALIAS(x) (NS_RAM_ALIAS_BASE + (x)) + +/* Secure regions */ +#define S_IMAGE_PRIMARY_AREA_OFFSET \ + (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) +#define S_CODE_START (S_ROM_ALIAS(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) + +/* First half of SSRAM2 is assigned to secure data */ +#define S_DATA_START (S_RAM_ALIAS(0x0)) +#define S_DATA_SIZE (TOTAL_RAM_SIZE / 2) +#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) +#define NS_CODE_START (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_AREA_OFFSET)) +#define NS_CODE_SIZE (IMAGE_NS_CODE_SIZE) +#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1) + +/* Second half of SSRAM2 is assigned to non-secure data */ +#define NS_DATA_START (NS_RAM_ALIAS(TOTAL_RAM_SIZE / 2)) +#define NS_DATA_SIZE (TOTAL_RAM_SIZE / 2) +#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 \ + (NS_ROM_ALIAS(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 \ + (NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET)) +#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + \ + FLASH_NS_PARTITION_SIZE) + +#ifdef BL2 +/* Bootloader regions */ +#define BL2_CODE_START (S_ROM_ALIAS(FLASH_AREA_BL2_OFFSET)) +#define BL2_CODE_SIZE (FLASH_AREA_BL2_SIZE) +#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1) + +#define BL2_DATA_START (S_RAM_ALIAS(0x0)) +#define BL2_DATA_SIZE (TOTAL_RAM_SIZE) +#define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1) +#endif /* BL2 */ + +#endif /* __REGION_DEFS_H__ */ diff --git a/platform/ext/target/mps2/an539/plat_test.c b/platform/ext/target/mps2/an539/plat_test.c new file mode 100644 index 0000000000..ba3ac071e2 --- /dev/null +++ b/platform/ext/target/mps2/an539/plat_test.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, 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 "syscounter_armv8-m_cntrl_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) +{ + syscounter_armv8_m_cntrl_init(&SYSCOUNTER_CNTRL_ARMV8_M_DEV_S); + + systimer_armv8_m_init(&SYSTIMER0_ARMV8_M_DEV_S); + /* If already initialized, call results in a fall through. */ + systimer_armv8_m_set_autoinc_reload( + &SYSTIMER0_ARMV8_M_DEV_S, TIMER_RELOAD_VALUE); + systimer_armv8_m_enable_autoinc(&SYSTIMER0_ARMV8_M_DEV_S); + systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S); + 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); + /* If already initialized, call results in a fall through. */ + systimer_armv8_m_set_autoinc_reload( + &SYSTIMER1_ARMV8_M_DEV_NS, TIMER_RELOAD_VALUE); + systimer_armv8_m_enable_autoinc(&SYSTIMER1_ARMV8_M_DEV_NS); + systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER1_ARMV8_M_DEV_NS); + 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/an539/services/src/tfm_platform_system.c b/platform/ext/target/mps2/an539/services/src/tfm_platform_system.c new file mode 100644 index 0000000000..2295ff68a8 --- /dev/null +++ b/platform/ext/target/mps2/an539/services/src/tfm_platform_system.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "platform/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/an539/spm_hal.c b/platform/ext/target/mps2/an539/spm_hal.c new file mode 100644 index 0000000000..997ab4ec7b --- /dev/null +++ b/platform/ext/target/mps2/an539/spm_hal.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include <stdio.h> +#include "tfm_spm_hal.h" +#include "tfm_platform_core_api.h" +#include "spm_db.h" +#include "target_cfg.h" +#include "mpu_armv8m_drv.h" +#include "region_defs.h" +#include "platform_description.h" + +/* 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) + +/* Get address of memory regions to configure MPU */ +extern const struct memory_region_limits memory_regions; + +enum tfm_plat_err_t tfm_spm_hal_init_isolation_hw(void) +{ + enum tfm_plat_err_t err = TFM_PLAT_ERR_SUCCESS; + + /* Configures non-secure memory spaces in the target */ + 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; +} + +void tfm_spm_hal_configure_default_isolation( + const struct tfm_spm_partition_platform_data_t *platform_data) +{ + if (platform_data) { + if (platform_data->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) { + ppc_configure_to_secure(platform_data->periph_ppc_bank, + platform_data->periph_ppc_loc); + ppc_configure_to_secure_priv(platform_data->periph_ppc_bank, + platform_data->periph_ppc_loc); + } + } +} + +#if TFM_LVL != 1 + +#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 6 +#define PARTITION_REGION_SHARE 7 + +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); + +static enum spm_err_t tfm_spm_mpu_init(void) +{ + struct mpu_armv8m_region_cfg_t region_cfg; + + mpu_clean(); + + /* Veneer region */ + region_cfg.region_nr = MPU_REGION_VENEERS; + region_cfg.region_base = memory_regions.veneer_base; + region_cfg.region_limit = memory_regions.veneer_limit; + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX; + region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV; + region_cfg.attr_sh = MPU_ARMV8M_SH_NONE; + region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + /* TFM Core unprivileged code region */ + region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_CODE; + region_cfg.region_base = + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base); + region_cfg.region_limit = + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit); + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX; + region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV; + region_cfg.attr_sh = MPU_ARMV8M_SH_NONE; + region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + /* TFM Core unprivileged data region */ + region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA; + region_cfg.region_base = + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_DATA, $$RW$$Base); + region_cfg.region_limit = + (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_DATA, $$ZI$$Limit); + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + /* NSPM PSP */ + region_cfg.region_nr = MPU_REGION_NS_STACK; + region_cfg.region_base = + (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base); + region_cfg.region_limit = + (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit); + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + /* RO region */ + region_cfg.region_nr = PARTITION_REGION_RO; + region_cfg.region_base = + (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base); + region_cfg.region_limit = + (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base); + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX; + region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV; + region_cfg.attr_sh = MPU_ARMV8M_SH_NONE; + region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + /* RW, ZI and stack as one region */ + region_cfg.region_nr = PARTITION_REGION_RW_STACK; + region_cfg.region_base = + (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base); + region_cfg.region_limit = + (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base); + region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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; + if (mpu_region_enable(®ion_cfg) != MPU_ARMV8M_OK) { + return SPM_ERR_INVALID_CONFIG; + } + + mpu_enable(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!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + return TFM_PLAT_ERR_SUCCESS; +} +#endif /* TFM_LVL != 1 */ + +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 */ + LOG_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*/ + LOG_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(int32_t 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; +} + +enum tfm_plat_err_t tfm_spm_hal_init_debug(void) +{ + volatile struct sse123_sysctrl_t *sys_ctrl = + (struct sse123_sysctrl_t *)SSE123_SYSCTRL_BASE_S; + +#if defined(DAUTH_NONE) + /* Set all the debug enable selector bits to 1 */ + sys_ctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 0 */ + sys_ctrl->secdbgclr = + DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_NS_ONLY) + /* Set all the debug enable selector bits to 1 */ + sys_ctrl->secdbgset = All_SEL_STATUS; + /* Set the debug enable bits to 1 for NS, and 0 for S mode */ + sys_ctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS; + sys_ctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_FULL) + /* Set all the debug enable selector bits to 1 */ + sys_ctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 1 */ + sys_ctrl->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 */ + sys_ctrl->secdbgclr = All_SEL_STATUS; + + /* No need to set any enable bits because the value depends on + * input signals. + */ +#endif + + return TFM_PLAT_ERR_SUCCESS; +} + +enum irq_target_state_t tfm_spm_hal_set_irq_target_state( + int32_t 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_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(); +} + +void tfm_spm_hal_clear_pending_irq(int32_t irq_line) +{ + NVIC_ClearPendingIRQ(irq_line); +} + +void tfm_spm_hal_enable_irq(int32_t irq_line) +{ + NVIC_EnableIRQ(irq_line); +} + +void tfm_spm_hal_disable_irq(int32_t irq_line) +{ + NVIC_DisableIRQ(irq_line); +} diff --git a/platform/ext/target/mps2/an539/target_cfg.c b/platform/ext/target/mps2/an539/target_cfg.c new file mode 100644 index 0000000000..2854d3338f --- /dev/null +++ b/platform/ext/target/mps2/an539/target_cfg.c @@ -0,0 +1,580 @@ +/* + * 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. + */ + +#include "target_cfg.h" +#include "Driver_MPC.h" +#include "Driver_SSE123_PPC.h" +#include "device_definition.h" +#include "platform_description.h" +#include "region_defs.h" +#include "tfm_secure_api.h" +#include "mpu_armv8m_drv.h" +#include "secure_utilities.h" +#include "tfm_plat_defs.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 */ +}; + +static struct mpu_armv8m_dev_t dev_mpu = { MPU_BASE }; + +/* Allows software, via SAU, to define the code region as a NSC */ +#define NSCCFG_CODENSC 1 + +/* Import MPC drivers */ +extern ARM_DRIVER_MPC Driver_ISRAM0_MPC; +extern ARM_DRIVER_MPC Driver_SRAM1_MPC; +extern ARM_DRIVER_MPC Driver_SRAM2_MPC; +extern ARM_DRIVER_MPC Driver_SSRAM3_MPC; + +/* Import PPC drivers */ +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_AHB_EXP0; +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB; +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP0; +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP1; +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_EXP2; +extern DRIVER_PPC_SSE123 Driver_PPC_SSE123_APB_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)) + +struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = { + UART0_BASE_NS, + UART0_BASE_NS + 0xFFF, + PPC_SP_DO_NOT_CONFIGURE, + -1 +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io = { + MPS2_IO_FPGAIO_BASE_S, + MPS2_IO_FPGAIO_BASE_S + 0xFFF, + PPC_SP_APB_PPC_EXP3, + FPGA_IO_APB_PPCEXP3_POS +}; + +struct tfm_spm_partition_platform_data_t tfm_peripheral_timer0 = { + SYSTEM_TIMER0_BASE_S, + SYSTEM_TIMER1_BASE_S - 1, + PPC_SP_APB_PPC, + SYSTEM_TIMER0_APB_PPC_POS +}; + +static DRIVER_PPC_SSE123 *const ppc_bank_drivers[] = { + &Driver_PPC_SSE123_AHB_EXP0, /* AHB PPCEXP0 */ + &Driver_PPC_SSE123_APB, /* APB PPC0 */ + &Driver_PPC_SSE123_APB_EXP0, /* APB PPCEXP0 */ + &Driver_PPC_SSE123_APB_EXP1, /* APB PPCEXP1 */ + &Driver_PPC_SSE123_APB_EXP2, /* APB PPCEXP2 */ + &Driver_PPC_SSE123_APB_EXP3, /* APB PPCEXP3 */ +}; + +#define PPC_BANK_COUNT (sizeof(ppc_bank_drivers)/sizeof(ppc_bank_drivers[0])) + +enum tfm_plat_err_t enable_fault_handlers(void) +{ + /* Secure fault is not present in the Baseline implementation. */ + /* Fault handler enable registers are not present in a Baseline + * implementation. + */ + + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t system_reset_cfg(void) +{ + struct sse123_sysctrl_t *sysctrl = + (struct sse123_sysctrl_t *)SSE123_SYSCTRL_BASE_S; + uint32_t reg_value = SCB->AIRCR; + + /* Enable system reset request for CPU 0, to be triggered via + * NVIC_SystemReset function. + */ + sysctrl->resetmask |= 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); + + return TFM_PLAT_ERR_SUCCESS; +} + +enum mpu_armv8m_error_t mpu_enable(uint32_t privdef_en, uint32_t hfnmi_en) +{ + return mpu_armv8m_enable(&dev_mpu, privdef_en, hfnmi_en); +} + +enum mpu_armv8m_error_t mpu_disable(void) +{ + return mpu_armv8m_disable(&dev_mpu); +} + +enum mpu_armv8m_error_t mpu_region_enable( + struct mpu_armv8m_region_cfg_t *region_cfg) +{ + if (!region_cfg) { + return MPU_ARMV8M_ERROR; + } + + return mpu_armv8m_region_enable(&dev_mpu, region_cfg); +} + +enum mpu_armv8m_error_t mpu_region_disable(uint32_t region_nr) +{ + return mpu_armv8m_region_disable(&dev_mpu, region_nr); +} + +enum mpu_armv8m_error_t mpu_clean(void) +{ + return mpu_armv8m_clean(&dev_mpu); +} + +/*----------------- NVIC interrupt enabling for S peripherals ----------------*/ +enum tfm_plat_err_t nvic_interrupt_enable(void) +{ + int32_t ret = ARM_DRIVER_OK; + + /* MPC interrupt enabling */ + mpc_clear_irq(); + ret = Driver_SRAM1_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable MPC interrupt for SSRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM2_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 */ + /* Clear pending PPC interrupts */ + /* In the PPC configuration function, we have used the Non-Secure + * Privilege Control Block to grant unprivilged NS access to some + * peripherals used by NS. That triggers a PPC0 exception as that + * register is meant for NS privileged access only. Clear it here + */ + NVIC_ClearPendingIRQ(PPC_IRQn); + Driver_PPC_SSE123_APB.ClearInterrupt(); + + /* Enable PPC interrupts for APB PPC */ + ret = Driver_PPC_SSE123_APB.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable PPC APB interrupt!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_PPC_SSE123_APB_EXP2.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable PPC APB EXP2 interrupt!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_PPC_SSE123_APB_EXP3.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Enable PPC APB EXP3 interrupt!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + NVIC_EnableIRQ(PPC_IRQn); + + return TFM_PLAT_ERR_SUCCESS; +} + +/*------------------- SAU/IDAU configuration functions -----------------------*/ +void sau_and_idau_cfg(void) +{ + struct sse123_spctrl_t *spctrl = (struct sse123_spctrl_t*)SSE123_SPCTRL_BASE_S; + + /* Enables SAU */ + TZ_SAU_Enable(); + + /* Configures SAU regions to be non-secure */ + SAU->RNR = TFM_NS_REGION_CODE; + 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 = TFM_NS_REGION_DATA; + 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 = TFM_NS_REGION_VENEER; + 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 = TFM_NS_REGION_PERIPH_1; + SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk) + | SAU_RLAR_ENABLE_Msk; +#ifdef BL2 + /* Secondary image partition */ + SAU->RNR = TFM_NS_SECONDARY_IMAGE_REGION; + 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; +#endif /* BL2 */ + + /* Allows SAU to define the code region as a NSC */ + spctrl->nsccfg |= NSCCFG_CODENSC; +} + +/*------------------- Memory configuration functions -------------------------*/ +enum tfm_plat_err_t mpc_init_cfg(void) +{ + int32_t ret = ARM_DRIVER_OK; + + ret = Driver_SRAM1_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SSRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM1_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 SSRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + +#ifdef BL2 + ret = Driver_SRAM1_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 SSRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } +#endif + + ret = Driver_SRAM2_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SSRAM2!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_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_SRAM1_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for SSRAM1!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM2_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 drivers. */ + ret = Driver_ISRAM0_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SSRAM3_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Initialize MPC for SSRAM3!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_ISRAM0_MPC.LockDown(); + if (ret != ARM_DRIVER_OK) { + ERROR_MSG("Failed to Lock down MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_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_SRAM1_MPC.ClearInterrupt(); + Driver_SRAM2_MPC.ClearInterrupt(); +} + +/*------------------- PPC configuration functions -------------------------*/ +enum tfm_plat_err_t ppc_init_cfg(void) +{ + struct sse123_spctrl_t *spctrl = + (struct sse123_spctrl_t*)SSE123_SPCTRL_BASE_S; + int32_t err = ARM_DRIVER_OK; + + /* Grant non-secure access to peripherals in the PPC0 + * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1) + */ + err |= Driver_PPC_SSE123_APB.Initialize(); + err |= Driver_PPC_SSE123_APB.ConfigSecurity(SYSTEM_TIMER0_APB_PPC_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB.ConfigSecurity(SYSTEM_TIMER1_APB_PPC_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB.ConfigSecurity(SYSTEM_WATCHDOG_APB_PPC_POS, + PPC_SSE123_NONSECURE_CONFIG); + + /* Grant non-secure access for APB peripherals on EXP2 */ + err |= Driver_PPC_SSE123_APB_EXP2.Initialize(); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(SPI0_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(SPI1_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(SPI2_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(SPI3_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(SPI4_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(UART0_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(UART1_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(UART2_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(UART3_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(UART4_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(I2C0_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(I2C1_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(I2C2_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_APB_EXP2.ConfigSecurity(I2C3_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG); + + /* Grant un-privileged access for UART0 in NS domain */ + err |= Driver_PPC_SSE123_APB_EXP2.ConfigPrivilege(UART0_APB_PPCEXP2_POS, + PPC_SSE123_NONSECURE_CONFIG, + PPC_SSE123_PRIV_AND_NONPRIV_CONFIG); + + /* Grant non-secure access for APB peripherals on EXP3 */ + err |= Driver_PPC_SSE123_APB_EXP3.Initialize(); + err |= Driver_PPC_SSE123_APB_EXP3.ConfigSecurity(FPGA_SCC_APB_PPCEXP3_POS, + PPC_SSE123_NONSECURE_CONFIG); + + err |= Driver_PPC_SSE123_APB_EXP3.ConfigSecurity(FPGA_AUDIO_APB_PPCEXP3_POS, + PPC_SSE123_NONSECURE_CONFIG); + + err |= Driver_PPC_SSE123_APB_EXP3.ConfigSecurity(FPGA_IO_APB_PPCEXP3_POS, + PPC_SSE123_NONSECURE_CONFIG); + + /* Grant un-privileged access for LEDs in NS domain */ + err |= Driver_PPC_SSE123_APB_EXP3.ConfigPrivilege(FPGA_SCC_APB_PPCEXP3_POS, + PPC_SSE123_NONSECURE_CONFIG, + PPC_SSE123_PRIV_AND_NONPRIV_CONFIG); + + err |= Driver_PPC_SSE123_APB_EXP3.ConfigPrivilege(FPGA_IO_APB_PPCEXP3_POS, + PPC_SSE123_NONSECURE_CONFIG, + PPC_SSE123_PRIV_AND_NONPRIV_CONFIG); + + /* + * Grant non-secure access to all peripherals on AHB EXP0: + * Make sure that all possible peripherals are enabled by default + */ + err |= Driver_PPC_SSE123_AHB_EXP0.Initialize(); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(VGA_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(GPIO0_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(GPIO1_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(GPIO2_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(GPIO3_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(PSRAM_ETH_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(DMA0_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + err |= Driver_PPC_SSE123_AHB_EXP0.ConfigSecurity(DMA1_AHB_PPCEXP_POS, + PPC_SSE123_NONSECURE_CONFIG); + + /* Initialize not used PPC drivers */ + err |= Driver_PPC_SSE123_APB_EXP0.Initialize(); + err |= Driver_PPC_SSE123_APB_EXP1.Initialize(); + + /* + * Configure the response to a security violation as a + * bus error instead of RAZ/WI + */ + spctrl->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_SSE123 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigSecurity(pos, PPC_SSE123_SECURE_CONFIG); + } +} + +void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE123 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigSecurity(pos, PPC_SSE123_NONSECURE_CONFIG); + } +} + +void ppc_configure_to_secure_priv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE123 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigPrivilege(pos, PPC_SSE123_SECURE_CONFIG, + PPC_SSE123_PRIV_CONFIG); + } +} + +void ppc_configure_to_secure_unpriv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE123 *ppc_driver; + + if (bank >= PPC_BANK_COUNT) { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) { + ppc_driver->ConfigPrivilege(pos, PPC_SSE123_SECURE_CONFIG, + PPC_SSE123_PRIV_AND_NONPRIV_CONFIG); + } +} + +void ppc_clear_irq(void) +{ + Driver_PPC_SSE123_AHB_EXP0.ClearInterrupt(); + Driver_PPC_SSE123_APB.ClearInterrupt(); + Driver_PPC_SSE123_APB_EXP2.ClearInterrupt(); + Driver_PPC_SSE123_APB_EXP3.ClearInterrupt(); +} diff --git a/platform/ext/target/mps2/an539/target_cfg.h b/platform/ext/target/mps2/an539/target_cfg.h new file mode 100644 index 0000000000..7667485a04 --- /dev/null +++ b/platform/ext/target/mps2/an539/target_cfg.h @@ -0,0 +1,172 @@ +/* + * 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 __TARGET_CFG_H__ +#define __TARGET_CFG_H__ + +#include <stdint.h> + +#define TFM_DRIVER_STDIO Driver_USART0 +#define NS_DRIVER_STDIO Driver_USART0 + +enum ppc_bank_e { + PPC_SP_DO_NOT_CONFIGURE = -1, + PPC_SP_AHB_PPC_EXP0 = 0, + PPC_SP_APB_PPC = 1, + PPC_SP_APB_PPC_EXP0 = 2, + PPC_SP_APB_PPC_EXP1 = 3, + PPC_SP_APB_PPC_EXP2 = 4, + PPC_SP_APB_PPC_EXP3 = 5, +}; + +/** + * \brief MPU configs + */ +#define PRIVILEGED_DEFAULT_ENABLE 1 +#define HARDFAULT_NMI_ENABLE 1 + +/** + * \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_loc; +}; + +/** + * \brief Forward declaration + */ +struct mpu_armv8m_region_cfg_t; + +/** + * \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) + */ +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) + */ +enum tfm_plat_err_t nvic_interrupt_enable(void); + +/** + * \brief This function enables the MPU + */ +enum mpu_armv8m_error_t mpu_enable(uint32_t privdef_en, uint32_t hfnmi_en); + +/** + * \brief This function disables the MPU + */ +enum mpu_armv8m_error_t mpu_disable(void); + +/** + * \brief This function enables the given MPU region + */ +enum mpu_armv8m_error_t mpu_region_enable( + struct mpu_armv8m_region_cfg_t *region_cfg); + +/** + * \brief This function dsables the given MPU region + */ +enum mpu_armv8m_error_t mpu_region_disable(uint32_t region_nr); + +/** + * \brief This function cleans all the MPU regions configs + */ +enum mpu_armv8m_error_t mpu_clean(void); + +/** + * \brief Configures the Memory Protection Controller. + */ +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 Restict access to peripheral to privileged in secure state + */ +void ppc_configure_to_secure_priv(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Enable unprivileged access to peripheral in secure state + */ +void ppc_configure_to_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/an539/tfm_peripherals_def.h b/platform/ext/target/mps2/an539/tfm_peripherals_def.h new file mode 100644 index 0000000000..5376752eed --- /dev/null +++ b/platform/ext/target/mps2/an539/tfm_peripherals_def.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PERIPHERALS_DEF_H__ +#define __TFM_PERIPHERALS_DEF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define TFM_TIMER0_IRQ (3) + +struct tfm_spm_partition_platform_data_t; + +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io; +extern struct tfm_spm_partition_platform_data_t tfm_peripheral_timer0; + +#define TFM_PERIPHERAL_STD_UART (&tfm_peripheral_std_uart) +#define TFM_PERIPHERAL_FPGA_IO (&tfm_peripheral_fpga_io) +#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0) + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PERIPHERALS_DEF_H__ */ diff --git a/test/suites/sst/CMakeLists.inc b/test/suites/sst/CMakeLists.inc index 54c8edf315..63c2349f02 100644 --- a/test/suites/sst/CMakeLists.inc +++ b/test/suites/sst/CMakeLists.inc @@ -47,8 +47,8 @@ elseif (ENABLE_SECURE_STORAGE_SERVICE_TESTS) 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 and AN521) & AN524. The reference platforms and AN524 - # use RAM memory to emulated a flash device as they do not have one. + # 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. 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() |