From edc7c27a3879d794e832c0958769520784602700 Mon Sep 17 00:00:00 2001 From: Artur Tynecki <77382963+ATmobica@users.noreply.github.com> Date: Sun, 29 Jan 2023 01:50:10 +0100 Subject: [PATCH] [OIS] Add TF-M support to Matter examples (#23951) * [OIS] Build scripts improvements Remove redundant steps: - removing old artifacts to force linking - removing access to ARM GCC toolchain from Matter environment now Pigweed env contains compatible ARM GCC version. Signed-off-by: ATmobica * [OIS] Improve OIS platform storage Add storage library that implements custom Flash Block Device class. OpenIoTSDKConfig uses the getter to block device object and pass it to TDBstore. Custom flash bd is a workaround solution for issues in MDH flash driver. We need to use the non-secure SRAM memory instead of secure part. Signed-off-by: ATmobica * [OIS] Extend chip_data_model Cmake Add SCOPE option - it allows to pass the Cmake scope keyword that defines the scope of included sources. Data model sources will not always be added to the application target directly. Adding the scope option makes it more flexible. Signed-off-by: ATmobica * [OIS] Make init ZCL Data Model and start server common Move init ZCL Data Model and start server to openiotsdk-app target. Implement openiotsdk_chip_run() and openiotsdk_chip_shutdown() Add chip_add_data_model() cmake function to add specified data model to target. Apply changes in lock-app example. Signed-off-by: ATmobica * [OIS] Update external version of mbedtls used by Matter This commit updates the external version of mbedtls used by the Matter integration with the IoT SDK, to the latest available. Signed-off-by: Anna Bridge * [OIS] Update SDK version Udpate Open IoT SDK version to the latest available. Refactoring the Cmake build system for passing the SDK targets to the CHIP build in a more generic way. Signed-off-by: ATmobica * [OIS] Add TF-M support in Matter examples Extend OIS Python package requirements with imgtool. Add custom TF-M AN552 platform implementation - flash layout and memory usage adaptation for Matter examples. Build lock-app and shell examples with TF-M support. They are built as non-secure apps and merged with bootloader and secure TF-M app. Build script adaptation - set TF-M support and get app version. Launch task adaptation to TF-M examples. Signed-off-by: ATmobica * [OIS] PSA protected storage support Add KV store class base on PSA Protected Storage. Rename OpenIoTSDKConfig to KVBlockDeviceStore. Build system adaptation to support various storage type. Change KV manager and Configuration manager to support various storage type. Add CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS Cmake flag to enable PSA PS support. Initialize the KV store manager during CHIP stack setup. Signed-off-by: ATmobica --------- Signed-off-by: ATmobica Signed-off-by: Anna Bridge Co-authored-by: Anna Bridge --- .vscode/launch.json | 8 +- config/openiotsdk/CMakeLists.txt | 34 +- config/openiotsdk/cmake/chip.cmake | 35 + config/openiotsdk/cmake/sdk.cmake | 265 ++- config/openiotsdk/ld/cs300_gcc.ld | 18 +- config/openiotsdk/ld/cs300_gcc_tfm.ld | 172 ++ config/openiotsdk/mbedtls/mbedtls_config.h | 1465 ++++++----------- config/openiotsdk/storage/CMakeLists.txt | 34 + .../openiotsdk/storage/FlashBlockDevice.cpp | 287 ++++ config/openiotsdk/storage/FlashBlockDevice.h | 185 +++ config/openiotsdk/util.cmake | 13 - docs/examples/openiotsdk_examples.md | 45 + docs/guides/openiotsdk_platform_overview.md | 20 + examples/lock-app/openiotsdk/CMakeLists.txt | 26 +- .../openiotsdk/cmsis-config/RTE_Components.h | 2 - .../freertos-config/FreeRTOSConfig.h | 2 +- .../openiotsdk/main/{main.cpp => main_ns.cpp} | 37 +- .../openiotsdk/tf-m-config/TfmProjectConfig.h | 165 ++ .../platform/openiotsdk/app/CMakeLists.txt | 9 +- .../openiotsdk/app/openiotsdk_platform.cpp | 121 +- .../openiotsdk/app/openiotsdk_platform.h | 14 + .../tf-m/targets/an552/CMakeLists.txt | 204 +++ .../tf-m/targets/an552/boot_hal_bl2.c | 87 + .../an552/cmsis_drivers/Driver_AN552_MPC.c | 679 ++++++++ .../an552/cmsis_drivers/Driver_Flash.c | 225 +++ .../an552/cmsis_drivers/Driver_SSE300_PPC.c | 1249 ++++++++++++++ .../an552/cmsis_drivers/Driver_SSE300_PPC.h | 140 ++ .../an552/cmsis_drivers/Driver_USART.c | 694 ++++++++ .../an552/cmsis_drivers/config/RTE_Device.h | 94 ++ .../config/cmsis_driver_config.h | 43 + .../tf-m/targets/an552/config.cmake | 24 + .../targets/an552/device/config/device_cfg.h | 70 + .../tf-m/targets/an552/device/include/an552.h | 92 ++ .../tf-m/targets/an552/device/include/cmsis.h | 22 + .../an552/device/include/device_definition.h | 249 +++ .../an552/device/include/platform_irq.h | 156 ++ .../an552/device/include/platform_pins.h | 115 ++ .../an552/device/include/platform_regs.h | 502 ++++++ .../an552/device/include/system_core_init.h | 55 + .../an552/device/source/an552_ns_init.c | 25 + .../an552/device/source/device_definition.c | 396 +++++ .../an552/device/source/startup_an552.c | 354 ++++ .../an552/device/source/system_core_init.c | 91 + .../openiotsdk/tf-m/targets/an552/faults.c | 52 + .../openiotsdk/tf-m/targets/an552/mmio_defs.h | 69 + .../an552/native_drivers/emulated_flash_drv.c | 223 +++ .../an552/native_drivers/emulated_flash_drv.h | 141 ++ .../an552/native_drivers/mpc_sie_drv.c | 848 ++++++++++ .../an552/native_drivers/mpc_sie_drv.h | 350 ++++ .../an552/native_drivers/mpu_armv8m_drv.c | 145 ++ .../an552/native_drivers/mpu_armv8m_drv.h | 154 ++ .../an552/native_drivers/ppc_sse300_drv.c | 471 ++++++ .../an552/native_drivers/ppc_sse300_drv.h | 222 +++ .../syscounter_armv8-m_cntrl_drv.c | 416 +++++ .../syscounter_armv8-m_cntrl_drv.h | 481 ++++++ .../native_drivers/systimer_armv8-m_drv.c | 298 ++++ .../native_drivers/systimer_armv8-m_drv.h | 393 +++++ .../an552/native_drivers/uart_cmsdk_drv.c | 311 ++++ .../an552/native_drivers/uart_cmsdk_drv.h | 260 +++ .../targets/an552/partition/flash_layout.h | 229 +++ .../an552/partition/platform_base_address.h | 272 +++ .../targets/an552/partition/region_defs.h | 138 ++ .../openiotsdk/tf-m/targets/an552/plat_test.c | 33 + .../tf-m/targets/an552/preload.cmake | 16 + .../an552/services/src/tfm_platform_system.c | 27 + .../tf-m/targets/an552/target_cfg.c | 515 ++++++ .../tf-m/targets/an552/target_cfg.h | 164 ++ .../tf-m/targets/an552/tfm_hal_isolation.c | 334 ++++ .../tf-m/targets/an552/tfm_hal_platform.c | 100 ++ .../tf-m/targets/an552/tfm_interrupts.c | 39 + .../tf-m/targets/an552/tfm_peripherals_def.c | 109 ++ .../tf-m/targets/an552/tfm_peripherals_def.h | 105 ++ examples/shell/openiotsdk/CMakeLists.txt | 9 +- .../freertos-config/FreeRTOSConfig.h | 2 +- .../openiotsdk/main/{main.cpp => main_ns.cpp} | 0 scripts/build/builders/openiotsdk.py | 5 - .../testdata/dry_run_openiotsdk-lock.txt | 3 - .../testdata/dry_run_openiotsdk-shell.txt | 3 - scripts/constraints.txt | 11 +- scripts/examples/openiotsdk_example.sh | 9 +- scripts/requirements.openiotsdk.txt | 3 +- src/app/chip_data_model.cmake | 19 +- src/platform/openiotsdk/BUILD.gn | 53 +- src/platform/openiotsdk/CHIPPlatformConfig.h | 2 + .../openiotsdk/ConfigurationManagerImpl.cpp | 43 +- .../openiotsdk/ConfigurationManagerImpl.h | 5 +- ...oTSDKConfig.cpp => KVBlockDeviceStore.cpp} | 285 ++-- ...penIoTSDKConfig.h => KVBlockDeviceStore.h} | 101 +- src/platform/openiotsdk/KVPsaPsStore.cpp | 624 +++++++ src/platform/openiotsdk/KVPsaPsStore.h | 196 +++ .../openiotsdk/KeyValueStoreManagerImpl.cpp | 90 +- .../openiotsdk/KeyValueStoreManagerImpl.h | 7 +- src/platform/openiotsdk/OpenIoTSDKPort.h | 35 + third_party/open-iot-sdk/sdk | 2 +- 94 files changed, 15613 insertions(+), 1332 deletions(-) create mode 100644 config/openiotsdk/ld/cs300_gcc_tfm.ld create mode 100644 config/openiotsdk/storage/CMakeLists.txt create mode 100644 config/openiotsdk/storage/FlashBlockDevice.cpp create mode 100644 config/openiotsdk/storage/FlashBlockDevice.h rename examples/lock-app/openiotsdk/main/{main.cpp => main_ns.cpp} (63%) create mode 100644 examples/lock-app/openiotsdk/tf-m-config/TfmProjectConfig.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/CMakeLists.txt create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/boot_hal_bl2.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_AN552_MPC.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_Flash.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_USART.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/RTE_Device.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/cmsis_driver_config.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/config.cmake create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/config/device_cfg.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/include/an552.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/include/cmsis.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/include/device_definition.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_irq.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_pins.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_regs.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/include/system_core_init.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/source/an552_ns_init.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/source/device_definition.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/source/startup_an552.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/device/source/system_core_init.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/faults.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/mmio_defs.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/partition/flash_layout.h create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/partition/platform_base_address.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/partition/region_defs.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/plat_test.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/preload.cmake create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/services/src/tfm_platform_system.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.c create mode 100644 examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.h create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_isolation.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_platform.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/tfm_interrupts.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.c create mode 100755 examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.h rename examples/shell/openiotsdk/main/{main.cpp => main_ns.cpp} (100%) rename src/platform/openiotsdk/{OpenIoTSDKConfig.cpp => KVBlockDeviceStore.cpp} (55%) rename src/platform/openiotsdk/{OpenIoTSDKConfig.h => KVBlockDeviceStore.h} (62%) create mode 100644 src/platform/openiotsdk/KVPsaPsStore.cpp create mode 100644 src/platform/openiotsdk/KVPsaPsStore.h create mode 100644 src/platform/openiotsdk/OpenIoTSDKPort.h diff --git a/.vscode/launch.json b/.vscode/launch.json index bf83cc0d85d6e4..5a8cfbce9c8682 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -435,7 +435,13 @@ "armToolchainPath": "${env:ARM_GCC_TOOLCHAIN_PATH}/bin", "servertype": "external", "gdbTarget": "${input:openiotsdkRemoteHost}:31627", //GDBserver port on FVP - "overrideLaunchCommands": ["-enable-pretty-printing"], + "overrideLaunchCommands": [ + "-enable-pretty-printing", + "add-symbol-file ./build/bl2.elf 0x10000000", + "add-symbol-file ./build/tfm_s.elf 0x38000400", + "add-symbol-file ./build/chip-openiotsdk-${input:openiotsdkApp}-example_ns.elf 0x28060400", + "break main_ns.cpp:main" + ], "runToEntryPoint": "main", "preLaunchTask": "Debug Open IoT SDK example", "showDevDebugOutput": "parsed" diff --git a/config/openiotsdk/CMakeLists.txt b/config/openiotsdk/CMakeLists.txt index 414f591095f1dc..1e7a77a0f21615 100644 --- a/config/openiotsdk/CMakeLists.txt +++ b/config/openiotsdk/CMakeLists.txt @@ -97,20 +97,10 @@ endif() set(GN_ROOT_TARGET ${CHIP_ROOT}/config/openiotsdk/chip-gn) # Prepare compiler flags -# All Open IoT SDK targets -list(APPEND ALL_SDK_TARGETS) - -foreach(source_dir ${SDK_SOURCES_BINARY_DIRS}) - get_all_cmake_targets(SDK_TARGETS ${source_dir}) - list(APPEND ALL_SDK_TARGETS ${SDK_TARGETS}) -endforeach() - -# Exclude unnecessary targets -list(FILTER ALL_SDK_TARGETS EXCLUDE REGEX "^.*linker.*|.*example.*|.*apps.*|.*doc.*|dist|lib$") - -foreach(target ${ALL_SDK_TARGETS}) - get_target_common_compile_flags(SDK_TARGET_CFLAGS ${target}) - list(APPEND CHIP_CFLAGS ${SDK_TARGET_CFLAGS}) +# Get compiler flags from external targets +foreach(target ${EXTERNAL_TARGETS}) + get_target_common_compile_flags(EXTERNAL_TARGET_CFLAGS ${target}) + list(APPEND CHIP_CFLAGS ${EXTERNAL_TARGET_CFLAGS}) endforeach() # Remove duplicated flags @@ -200,6 +190,8 @@ chip_gn_arg_bool ("chip_detail_logging" CONFIG_CHIP_DETAIL_LOG chip_gn_arg_bool ("chip_progress_logging" CONFIG_CHIP_PROGRESS_LOGGING) chip_gn_arg_bool ("chip_automation_logging" CONFIG_CHIP_AUTOMATION_LOGGING) chip_gn_arg_bool ("chip_error_logging" CONFIG_CHIP_ERROR_LOGGING) +chip_gn_arg_bool ("chip_openiotsdk_use_tfm" TFM_SUPPORT) +chip_gn_arg_bool ("chip_openiotsdk_use_psa_ps" CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS) if (TARGET cmsis-rtos-api) chip_gn_arg_string("target_os" "cmsis-rtos") endif() @@ -249,22 +241,10 @@ target_include_directories(openiotsdk-chip INTERFACE target_link_directories(openiotsdk-chip INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/lib) target_link_libraries(openiotsdk-chip INTERFACE -Wl,--start-group ${CHIP_LIBRARIES} -Wl,--end-group) target_link_libraries(openiotsdk-chip INTERFACE - $<$:mcu-driver-hal> - $<$:mcu-driver-bootstrap> - $<$:mdh-reference-platforms-for-arm> - $<$:mbedtls> - $<$:lwipcore> - $<$:iotsdk-ip-network-api> - $<$:iotsdk-tdbstore> - $<$:iotsdk-blockdevice> - $<$:$> + ${EXTERNAL_TARGETS} ) add_dependencies(openiotsdk-chip chip-gn) -target_include_directories(openiotsdk-chip INTERFACE - ${CHIP_ROOT}/config/openiotsdk/mbedtls -) - if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug") target_compile_definitions(openiotsdk-chip INTERFACE NDEBUG diff --git a/config/openiotsdk/cmake/chip.cmake b/config/openiotsdk/cmake/chip.cmake index 985d7f05bf74db..9a7dcf629e3a06 100644 --- a/config/openiotsdk/cmake/chip.cmake +++ b/config/openiotsdk/cmake/chip.cmake @@ -19,6 +19,8 @@ # CMake for CHIP library configuration # +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) + # Default CHIP build configuration set(CONFIG_CHIP_PROJECT_CONFIG "main/include/CHIPProjectConfig.h" CACHE STRING "") set(CONFIG_CHIP_LIB_TESTS NO CACHE BOOL "") @@ -29,5 +31,38 @@ set(CONFIG_CHIP_PROGRESS_LOGGING YES CACHE BOOL "Enable logging at progress leve set(CONFIG_CHIP_AUTOMATION_LOGGING YES CACHE BOOL "Enable logging at automation level") set(CONFIG_CHIP_ERROR_LOGGING YES CACHE BOOL "Enable logging at error level") +set(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS NO CACHE BOOL "Enable using PSA Protected Storage") + +if(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS AND NOT TFM_SUPPORT) + message( FATAL_ERROR "You can not use PSA Protected Storage without TF-M support" ) +endif() + # Add CHIP sources add_subdirectory(${OPEN_IOT_SDK_CONFIG} ./chip_build) + +# Additional openiotsdk-chip target configuration + +# TF-M support requires the right order of generating targets +if(TFM_SUPPORT) + add_dependencies(chip-gn tfm-ns-interface) +endif() + +function(chip_add_data_model target scope model_name) + target_include_directories(${target} + PUBLIC + ${GEN_DIR}/app-common + ${GEN_DIR}/${model_name}-app + ) + + target_compile_definitions(${target} + PUBLIC + USE_CHIP_DATA_MODEL + ) + + include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + chip_configure_data_model(${target} + SCOPE ${scope} + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../${model_name}-common/${model_name}-app.zap + ) +endfunction() diff --git a/config/openiotsdk/cmake/sdk.cmake b/config/openiotsdk/cmake/sdk.cmake index c87dad8412579d..52055cacdfc49a 100644 --- a/config/openiotsdk/cmake/sdk.cmake +++ b/config/openiotsdk/cmake/sdk.cmake @@ -24,41 +24,67 @@ include(FetchContent) get_filename_component(OPEN_IOT_SDK_SOURCE ${CHIP_ROOT}/third_party/open-iot-sdk/sdk REALPATH) get_filename_component(OPEN_IOT_SDK_STORAGE_SOURCE ${CHIP_ROOT}/third_party/open-iot-sdk/storage REALPATH) -# List of binary directories to Open IoT SDK sources -list(APPEND SDK_SOURCES_BINARY_DIRS) +# Open IoT SDK targets passed to CHIP build +list(APPEND EXTERNAL_TARGETS) + +# Additional Open IoT SDK build configuration +set(TFM_SUPPORT NO CACHE BOOL "Add Trusted Firmware-M (TF-M) support to application") +set(TFM_NS_APP_VERSION "0.0.0" CACHE STRING "TF-M non-secure application version (in the x.x.x format)") + +# Overwrite versions of Open IoT SDK components + +# Add a Matter specific version of Mbedtls +FetchContent_Declare( + mbedtls + GIT_REPOSITORY https://github.com/ARMmbed/mbedtls + GIT_TAG v3.2.1 + GIT_SHALLOW ON + GIT_PROGRESS ON +) # Open IoT SDK configuration -set(IOTSDK_MDH_ARM ON) -set(MDH_PLATFORM "ARM_AN552_MPS3") -set(MDH_ARM_BUILD_EXAMPLES OFF) -set(IOTSDK_CMSIS_RTOS_API ON) -set(IOTSDK_FREERTOS ON) -set(IOTSDK_MBEDTLS ON) -set(IOTSDK_LWIP ON) -set(FETCHCONTENT_QUIET OFF) -set(IOTSDK_EXAMPLES OFF) -set(BUILD_TESTING NO) +set(IOTSDK_FETCH_LIST + mcu-driver-reference-platforms-for-arm + cmsis-5 + cmsis-freertos + mbedtls + lwip + cmsis-sockets-api +) + +set(MDH_PLATFORM ARM_AN552_MPS3) set(VARIANT "FVP") +set(FETCHCONTENT_QUIET OFF) +if(TFM_SUPPORT) + list(APPEND IOTSDK_FETCH_LIST trusted-firmware-m) + set(TFM_PLATFORM ${OPEN_IOT_SDK_EXAMPLE_COMMON}/tf-m/targets/an552) + set(TFM_PSA_FIRMWARE_UPDATE ON) + set(MCUBOOT_IMAGE_VERSION_NS ${TFM_NS_APP_VERSION}) + set(TFM_CMAKE_ARGS "-DCONFIG_TFM_ENABLE_FP=ON;-DTFM_PROFILE=profile_medium") + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + set(TFM_CMAKE_ARGS "${TFM_CMAKE_ARGS};-DMCUBOOT_LOG_LEVEL=INFO;-DTFM_SPM_LOG_LEVEL=TFM_SPM_LOG_LEVEL_INFO;-DTFM_PARTITION_LOG_LEVEL=TFM_PARTITION_LOG_LEVEL_INFO") + else() + set(TFM_CMAKE_ARGS "${TFM_CMAKE_ARGS};-DMCUBOOT_LOG_LEVEL=ERROR;-DTFM_SPM_LOG_LEVEL=TFM_SPM_LOG_LEVEL_ERROR;-DTFM_PARTITION_LOG_LEVEL=TFM_PARTITION_LOG_LEVEL_ERROR") + endif() + if(TFM_PROJECT_CONFIG_HEADER_FILE) + set(TFM_CMAKE_ARGS "${TFM_CMAKE_ARGS};-DPROJECT_CONFIG_HEADER_FILE=${TFM_PROJECT_CONFIG_HEADER_FILE}") + endif() + set(LINKER_SCRIPT ${OPEN_IOT_SDK_CONFIG}/ld/cs300_gcc_tfm.ld) +endif() # Add Open IoT SDK source add_subdirectory(${OPEN_IOT_SDK_SOURCE} ./sdk_build) -list(APPEND SDK_SOURCES_BINARY_DIRS ${CMAKE_CURRENT_BINARY_DIR}/sdk_build) # Add Open IoT SDK modules to path list(APPEND CMAKE_MODULE_PATH ${open-iot-sdk_SOURCE_DIR}/cmake) +list(APPEND CMAKE_MODULE_PATH ${open-iot-sdk_SOURCE_DIR}/components/trusted-firmware-m) + +# Configure component properties -# CMSIS-RTOS configuration # CMSIS 5 require projects to provide configuration macros via RTE_Components.h # and CMSIS_device_header. The macro CMSIS_device_header is not automatically set # based on CMAKE_SYSTEM_PROCESSOR in the place where cmsis-core is first defined, # because a project may want to provide its own device header. -if(TARGET cmsis-rtos-api) - target_include_directories(cmsis-rtos-api - PUBLIC - cmsis-config - ) -endif() - if(TARGET cmsis-core) target_compile_definitions(cmsis-core INTERFACE @@ -66,6 +92,48 @@ if(TARGET cmsis-core) ) endif() +# Add RTOS configuration headers +# Link cmsis-rtos-api against a concrete implementation +if(TARGET cmsis-rtos-api) + target_include_directories(cmsis-core + INTERFACE + cmsis-config + ) + + target_compile_definitions(cmsis-rtos-api + PUBLIC + DOMAIN_NS=$,1,0> + ) + + if(TARGET freertos-kernel) + target_include_directories(freertos-kernel + PUBLIC + freertos-config + ) + + target_link_libraries(freertos-kernel + PUBLIC + cmsis-core + ) + + target_link_libraries(cmsis-rtos-api + PUBLIC + freertos-cmsis-rtos + freertos-kernel-heap-3 + ) + + target_compile_definitions(cmsis-rtos-api + INTERFACE + CONFIG_RUN_FREERTOS_SECURE_ONLY=$,0,1> + ) + elseif(TARGET cmsis-rtx) + target_link_libraries(cmsis-rtos-api + INTERFACE + cmsis-rtx + ) + endif() +endif() + # LwIP configuration if(TARGET lwip-cmsis-port) # lwipcore requires the config defined by lwip-cmsis-port @@ -94,6 +162,13 @@ if(TARGET ethernet-lan91c111) ) endif() +if(TARGET mcu-driver-hal) + target_compile_definitions(mcu-driver-hal + INTERFACE + DOMAIN_NS=$,1,0> + ) +endif() + # Mbedtls config if(TARGET mbedtls-config) target_include_directories(mbedtls-config @@ -101,14 +176,14 @@ if(TARGET mbedtls-config) ${OPEN_IOT_SDK_CONFIG}/mbedtls ) - target_sources(mbedtls-config + target_sources(mbedtls-config INTERFACE ${OPEN_IOT_SDK_CONFIG}/mbedtls/platform_alt.cpp ) target_compile_definitions(mbedtls-config INTERFACE - MBEDTLS_CONFIG_FILE="mbedtls_config.h" + MBEDTLS_CONFIG_FILE="${OPEN_IOT_SDK_CONFIG}/mbedtls/mbedtls_config.h" ) target_link_libraries(mbedtls-config @@ -117,28 +192,138 @@ if(TARGET mbedtls-config) ) endif() -# Declare RTOS interface target -add_library(cmsis-rtos-implementation INTERFACE) +if("mcu-driver-reference-platforms-for-arm" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + mcu-driver-bootstrap + mcu-driver-hal + mdh-arm-corstone-300-common + target-interface + ) +endif() -if(TARGET freertos-kernel) - target_link_libraries(cmsis-rtos-implementation - INTERFACE - freertos-cmsis-rtos - freertos-kernel-heap-3 +if("cmsis-5" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + cmsis-core + cmsis-rtos-api + iotsdk-ip-network-api ) - target_include_directories(cmsis-rtos-implementation - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/freertos-config +endif() + +if("cmsis-freertos" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + freertos-cmsis-rtos ) -elseif(TARGET cmsis-rtx) - target_link_libraries(cmsis-rtos-implementation - INTERFACE - cmsis-rtx - cmsis-rtos-api - cmsis-rtx-freertos-alloc-wrapper +endif() + +if("mbedtls" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + mbedtls + mbedtls-config + mbedtls-threading-cmsis-rtos ) endif() +if("lwip" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + lwipcore + lwip-cmsis-port + lwip-cmsis-sys + lwip-cmsis-port-low-input-latency + lwipopts + ) +endif() + +if("cmsis-sockets-api" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + cmsis-sockets-api + lwip-sockets + ) +endif() + +if("trusted-firmware-m" IN_LIST IOTSDK_FETCH_LIST) + list(APPEND EXTERNAL_TARGETS + tfm-ns-interface + tfm-ns-interface-cmsis-rtos + ) +endif() + +# Additional Open IoT SDK port components + # Add Open IoT SDK storage source add_subdirectory(${OPEN_IOT_SDK_STORAGE_SOURCE} ./sdk_storage_build) -list(APPEND SDK_SOURCES_BINARY_DIRS ${CMAKE_CURRENT_BINARY_DIR}/sdk_storage_build) +list(APPEND EXTERNAL_TARGETS + iotsdk-blockdevice + iotsdk-tdbstore +) + +# Add custom storage library +add_subdirectory(${OPEN_IOT_SDK_CONFIG}/storage storage_build) +list(APPEND EXTERNAL_TARGETS + openiotsdk-storage +) + +function(sdk_post_build target) + string(REPLACE "_ns" "" APP_NAME ${APP_TARGET}) +if(TFM_SUPPORT) + include(ConvertElfToBin) + include(SignTfmImage) + target_elf_to_bin(${APP_TARGET}) + iotsdk_tf_m_sign_image(${APP_TARGET}) + iotsdk_tf_m_merge_images(${APP_TARGET} 0x10000000 0x38000000 0x28060000) + ExternalProject_Get_Property(trusted-firmware-m-build BINARY_DIR) + # Cleanup + add_custom_command( + TARGET + ${APP_TARGET} + POST_BUILD + DEPENDS + $/tfm_s_signed.bin + $/${APP_TARGET}.bin + $/${APP_TARGET}_signed.bin + $/${APP_TARGET}_merged.hex + $/${APP_TARGET}_merged.elf + COMMAND + # Copy the TF-M secure elf image + ${CMAKE_COMMAND} -E copy + ${BINARY_DIR}/install/outputs/tfm_s.elf + $/ + COMMAND + # Rename output file + ${CMAKE_COMMAND} -E copy + $/${APP_TARGET}_merged.elf + $/${APP_NAME}.elf + COMMAND rm + ARGS -Rf + $/tfm_s_signed.bin + $/${APP_TARGET}.bin + $/${APP_TARGET}_signed.bin + $/${APP_TARGET}_merged.hex + $/${APP_TARGET}_merged.elf + VERBATIM + ) +else() + add_custom_command( + TARGET + ${APP_TARGET} + POST_BUILD + DEPENDS + $/${APP_TARGET}.elf + $/${APP_TARGET}.map + COMMAND + # Rename output elf file + ${CMAKE_COMMAND} -E copy + $/${APP_TARGET}.elf + $/${APP_NAME}.elf + COMMAND + # Rename output map file + ${CMAKE_COMMAND} -E copy + $/${APP_TARGET}.map + $/${APP_NAME}.map + COMMAND rm + ARGS -Rf + $/${APP_TARGET}.elf + $/${APP_TARGET}.map + VERBATIM + ) +endif() #TFM_SUPPORT +endfunction() diff --git a/config/openiotsdk/ld/cs300_gcc.ld b/config/openiotsdk/ld/cs300_gcc.ld index 850e91200bc0d5..97ec041ff09ed6 100644 --- a/config/openiotsdk/ld/cs300_gcc.ld +++ b/config/openiotsdk/ld/cs300_gcc.ld @@ -1,4 +1,20 @@ -; +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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. + */ + MEMORY { ITCM (rx) : ORIGIN = 0x00000000, LENGTH = 32K diff --git a/config/openiotsdk/ld/cs300_gcc_tfm.ld b/config/openiotsdk/ld/cs300_gcc_tfm.ld new file mode 100644 index 00000000000000..523c96e8efb77c --- /dev/null +++ b/config/openiotsdk/ld/cs300_gcc_tfm.ld @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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. + */ + +MEMORY +{ + FLASH (rx) : ORIGIN = ((0x28000000) + (0x60000) + (0x400)), LENGTH = ((0x200000) - (0x400) - (0x800)) + RAM (rwx) : ORIGIN = 0x21000000, LENGTH = 0x100000 +} + +__stack_size__ = 0x1000; + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +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 */ + .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 + + .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__; + + .stack : + { + . = ALIGN(8); + __StackLimit = .; + KEEP(*(.stack*)) + . += __stack_size__; + __StackTop = .; + } > RAM + PROVIDE(__stack = __StackTop); + + .heap (COPY): + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . += (ORIGIN(RAM) + LENGTH(RAM) - .); + __HeapLimit = .; + __heap_limit = .; + } > RAM + + ASSERT(__HeapLimit <= (ORIGIN(RAM) + LENGTH(RAM)), "RAM region overflowed") +} diff --git a/config/openiotsdk/mbedtls/mbedtls_config.h b/config/openiotsdk/mbedtls/mbedtls_config.h index e12878adf14986..316d43c67940d0 100644 --- a/config/openiotsdk/mbedtls/mbedtls_config.h +++ b/config/openiotsdk/mbedtls/mbedtls_config.h @@ -24,12 +24,14 @@ * limitations under the License. */ -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif +/** + * This is an optional version symbol that enables compatibility handling of + * config files. + * + * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that + * introduced the config format we want to be compatible with. + */ +//#define MBEDTLS_CONFIG_VERSION 0x03000000 /** * \name SECTION: System support @@ -47,8 +49,7 @@ * * Used in: * library/aria.c - * library/timing.c - * include/mbedtls/bn_mul.h + * library/bn_mul.h * * Required by: * MBEDTLS_AESNI_C @@ -128,7 +129,12 @@ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and * MBEDTLS_PLATFORM_STD_TIME. * - * Comment if your system does not support time functions + * Comment if your system does not support time functions. + * + * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing + * interface - timing.c will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. */ #define MBEDTLS_HAVE_TIME @@ -219,6 +225,7 @@ * Uncomment a macro to enable alternate implementation of specific base * platform function */ +//#define MBEDTLS_PLATFORM_SETBUF_ALT //#define MBEDTLS_PLATFORM_EXIT_ALT //#define MBEDTLS_PLATFORM_TIME_ALT //#define MBEDTLS_PLATFORM_FPRINTF_ALT @@ -255,73 +262,7 @@ */ //#define MBEDTLS_DEPRECATED_REMOVED -/** - * \def MBEDTLS_CHECK_PARAMS - * - * This configuration option controls whether the library validates more of - * the parameters passed to it. - * - * When this flag is not defined, the library only attempts to validate an - * input parameter if: (1) they may come from the outside world (such as the - * network, the filesystem, etc.) or (2) not validating them could result in - * internal memory errors such as overflowing a buffer controlled by the - * library. On the other hand, it doesn't attempt to validate parameters whose - * values are fully controlled by the application (such as pointers). - * - * When this flag is defined, the library additionally attempts to validate - * parameters that are fully controlled by the application, and should always - * be valid if the application code is fully correct and trusted. - * - * For example, when a function accepts as input a pointer to a buffer that may - * contain untrusted data, and its documentation mentions that this pointer - * must not be NULL: - * - The pointer is checked to be non-NULL only if this option is enabled. - * - The content of the buffer is always validated. - * - * When this flag is defined, if a library function receives a parameter that - * is invalid: - * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). - * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function - * will immediately return. If the function returns an Mbed TLS error code, - * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. - * - * When defining this flag, you also need to arrange a definition for - * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: - * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a - * function mbedtls_param_failed(), but the library does not define this - * function. If you do not make any other arrangements, you must provide - * the function mbedtls_param_failed() in your application. - * See `platform_util.h` for its prototype. - * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the - * library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. - * You can still supply an alternative definition of - * MBEDTLS_PARAM_FAILED(), which may call `assert`. - * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` - * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, - * the library will call the macro that you defined and will not supply - * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, - * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source - * files include ``. - * - * Uncomment to enable validation of application-controlled parameters. - */ -//#define MBEDTLS_CHECK_PARAMS - -/** - * \def MBEDTLS_CHECK_PARAMS_ASSERT - * - * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to - * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. - * - * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to - * calling a function mbedtls_param_failed(). See the documentation of - * #MBEDTLS_CHECK_PARAMS for details. - * - * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. - */ -//#define MBEDTLS_CHECK_PARAMS_ASSERT - -/* \} name SECTION: System support */ +/** \} name SECTION: System support */ /** * \name SECTION: mbed TLS feature support @@ -334,7 +275,7 @@ /** * \def MBEDTLS_TIMING_ALT * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * Uncomment to provide your own alternate implementation for * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() * * Only works if you have MBEDTLS_TIMING_C enabled. @@ -363,16 +304,14 @@ * Uncomment a macro to enable alternate implementation of the corresponding * module. * - * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * \warning MD5, DES and SHA-1 are considered weak and their * use constitutes a security risk. If possible, we recommend * avoiding dependencies on them, and considering stronger message * digests and ciphers instead. * */ //#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT //#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CCM_ALT //#define MBEDTLS_CHACHA20_ALT @@ -383,8 +322,6 @@ //#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_GCM_ALT //#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT //#define MBEDTLS_MD5_ALT //#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT @@ -392,10 +329,9 @@ //#define MBEDTLS_SHA1_ALT //#define MBEDTLS_SHA256_ALT //#define MBEDTLS_SHA512_ALT -//#define MBEDTLS_XTEA_ALT /* - * When replacing the elliptic curve module, pleace consider, that it is + * When replacing the elliptic curve module, please consider, that it is * implemented with two .c files: * - ecp.c * - ecp_curves.c @@ -406,7 +342,7 @@ //#define MBEDTLS_ECP_ALT /** - * \def MBEDTLS_MD2_PROCESS_ALT + * \def MBEDTLS_SHA256_PROCESS_ALT * * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you * alternate core implementation of symmetric crypto or hash function. Keep in @@ -421,20 +357,14 @@ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible * with this definition. * - * \note Because of a signature change, the core AES encryption and decryption routines are - * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, - * respectively. When setting up alternative implementations, these functions should - * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt - * must stay untouched. - * - * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * \note If you use the AES_xxx_ALT macros, then it is recommended to also set * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES * tables. * * Uncomment a macro to enable alternate implementation of the corresponding * function. * - * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * \warning MD5, DES and SHA-1 are considered weak and their use * constitutes a security risk. If possible, we recommend avoiding * dependencies on them, and considering stronger message digests * and ciphers instead. @@ -445,13 +375,9 @@ * alternative implementations should use the RNG only for generating * the ephemeral key and nothing else. If this is not possible, then * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext() - * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is - * desirable). + * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). * */ -//#define MBEDTLS_MD2_PROCESS_ALT -//#define MBEDTLS_MD4_PROCESS_ALT //#define MBEDTLS_MD5_PROCESS_ALT //#define MBEDTLS_RIPEMD160_PROCESS_ALT //#define MBEDTLS_SHA1_PROCESS_ALT @@ -535,23 +461,6 @@ //#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT //#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT -/** - * \def MBEDTLS_TEST_NULL_ENTROPY - * - * Enables testing and use of mbed TLS without any configured entropy sources. - * This permits use of the library on platforms before an entropy source has - * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the - * MBEDTLS_ENTROPY_NV_SEED switches). - * - * WARNING! This switch MUST be disabled in production builds, and is suitable - * only for development. - * Enabling the switch negates any security provided by the library. - * - * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - */ -//#define MBEDTLS_TEST_NULL_ENTROPY - /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * @@ -559,7 +468,8 @@ * hardware entropy collector. * * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * prototype as declared in library/entropy_poll.h, and accept NULL as first + * argument. * * Uncomment to use your own hardware entropy collector. */ @@ -616,6 +526,29 @@ */ //#define MBEDTLS_CAMELLIA_SMALL_MEMORY +/** + * \def MBEDTLS_CHECK_RETURN_WARNING + * + * If this macro is defined, emit a compile-time warning if application code + * calls a function without checking its return value, but the return value + * should generally be checked in portable applications. + * + * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is + * implemented. Otherwise this option has no effect. + * + * Uncomment to get warnings on using fallible functions without checking + * their return value. + * + * \note This feature is a work in progress. + * Warnings will be added to more functions in the future. + * + * \note A few functions are considered critical, and ignoring the return + * value of these functions will trigger a warning even if this + * macro is not defined. To completely disable return value check + * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. + */ +//#define MBEDTLS_CHECK_RETURN_WARNING + /** * \def MBEDTLS_CIPHER_MODE_CBC * @@ -658,8 +591,7 @@ * Warning: Only do so when you know what you are doing. This allows for * encryption or channels without any security! * - * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: + * To enable the following ciphersuites: * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA @@ -707,57 +639,6 @@ */ //#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY -/** - * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES - * - * Remove 3DES ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on 3DES from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible - * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including - * them explicitly. - * - * A man-in-the-browser attacker can recover authentication tokens sent through - * a TLS connection using a 3DES based cipher suite (see "On the Practical - * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan - * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls - * in your threat model or you are unsure, then you should keep this option - * enabled to remove 3DES based cipher suites. - * - * Comment this macro to keep 3DES in the default ciphersuite list. - */ -#define MBEDTLS_REMOVE_3DES_CIPHERSUITES - /** * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED * @@ -793,28 +674,6 @@ */ #define MBEDTLS_ECP_NIST_OPTIM -/** - * \def MBEDTLS_ECP_NO_INTERNAL_RNG - * - * When this option is disabled, mbedtls_ecp_mul() will make use of an - * internal RNG when called with a NULL \c f_rng argument, in order to protect - * against some side-channel attacks. - * - * This protection introduces a dependency of the ECP module on one of the - * DRBG modules. For very constrained implementations that don't require this - * protection (for example, because you're only doing signature verification, - * so not manipulating any secret, or because local/physical side-channel - * attacks are outside your threat model), it might be desirable to get rid of - * that dependency. - * - * \warning Enabling this option makes some uses of ECP vulnerable to some - * side-channel attacks. Only enable it if you know that's not a problem for - * your use case. - * - * Uncomment this macro to disable some counter-measures in ECP. - */ -//#define MBEDTLS_ECP_NO_INTERNAL_RNG - /** * \def MBEDTLS_ECP_RESTARTABLE * @@ -835,39 +694,10 @@ * * \note This option only works with the default software implementation of * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT - * and MBEDTLS_ECDH_LEGACY_CONTEXT. + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. */ //#define MBEDTLS_ECP_RESTARTABLE -/** - * \def MBEDTLS_ECDH_LEGACY_CONTEXT - * - * Use a backward compatible ECDH context. - * - * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context - * defined in `ecdh.h`). For most applications, the choice of format makes - * no difference, since all library functions can work with either format, - * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. - - * The new format used when this option is disabled is smaller - * (56 bytes on a 32-bit platform). In future versions of the library, it - * will support alternative implementations of ECDH operations. - * The new format is incompatible with applications that access - * context fields directly and with restartable ECP operations. - * - * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you - * want to access ECDH context fields directly. Otherwise you should - * comment out this macro definition. - * - * This option has no effect if #MBEDTLS_ECDH_C is not enabled. - * - * \note This configuration option is experimental. Future versions of the - * library may modify the way the ECDH context layout is configured - * and may modify the layout of the new context type. - */ -//#define MBEDTLS_ECDH_LEGACY_CONTEXT - /** * \def MBEDTLS_ECDSA_DETERMINISTIC * @@ -899,8 +729,6 @@ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA */ //#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED @@ -923,8 +751,6 @@ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA * * \warning Using DHE constitutes a security risk as it * is not possible to validate custom DH parameters. @@ -950,8 +776,6 @@ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA */ //#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED @@ -975,8 +799,6 @@ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA */ //#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED @@ -1002,9 +824,6 @@ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 */ //#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED @@ -1030,7 +849,6 @@ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA * * \warning Using DHE constitutes a security risk as it * is not possible to validate custom DH parameters. @@ -1061,8 +879,6 @@ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA */ #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED @@ -1085,8 +901,6 @@ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */ #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED @@ -1099,8 +913,6 @@ * * This enables the following ciphersuites (if other requisites are * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 @@ -1123,8 +935,6 @@ * * This enables the following ciphersuites (if other requisites are * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 @@ -1205,8 +1015,7 @@ /** * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES * - * Do not add default entropy sources. These are the platform specific, - * mbedtls_timing_hardclock and HAVEGE based poll functions. + * Do not add default entropy sources in mbedtls_entropy_init(). * * This is useful to have more control over the added entropy sources in an * application. @@ -1278,7 +1087,7 @@ * which is currently hard-coded to be int32_t. * * Note that this option is meant for internal use only and may be removed - * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO. + * without notice. */ //#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER @@ -1321,7 +1130,7 @@ * * Enable support for PKCS#1 v1.5 encoding. * - * Requires: MBEDTLS_RSA_C + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C * * This enables support for PKCS#1 v1.5 operations. */ @@ -1338,6 +1147,22 @@ */ //#define MBEDTLS_PKCS1_V21 +/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + * + * Enable support for platform built-in keys. If you enable this feature, + * you must implement the function mbedtls_psa_platform_get_builtin_key(). + * See the documentation of that function for more information. + * + * Built-in keys are typically derived from a hardware unique key or + * stored in a secure element. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + /** \def MBEDTLS_PSA_CRYPTO_CLIENT * * Enable support for PSA crypto client. @@ -1360,8 +1185,9 @@ * * Requires: MBEDTLS_PSA_CRYPTO_C * - * \warning This interface is experimental and may change or be removed - * without notice. + * \warning This interface is experimental. We intend to maintain backward + * compatibility with application code that relies on drivers, + * but the driver interfaces may change without notice. */ //#define MBEDTLS_PSA_CRYPTO_DRIVERS @@ -1454,7 +1280,7 @@ * Enable an implementation of SHA-256 that has lower ROM footprint but also * lower performance. * - * The default implementation is meant to be a reasonnable compromise between + * The default implementation is meant to be a reasonable compromise between * performance and size. This version optimizes more aggressively for size at * the expense of performance. Eg on Cortex-M4 it reduces the size of * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about @@ -1474,18 +1300,6 @@ */ //#define MBEDTLS_SHA512_SMALLER -/** - * \def MBEDTLS_SHA512_NO_SHA384 - * - * Disable the SHA-384 option of the SHA-512 module. Use this to save some - * code size on devices that don't use SHA-384. - * - * Requires: MBEDTLS_SHA512_C - * - * Uncomment to disable SHA-384 - */ -//#define MBEDTLS_SHA512_NO_SHA384 - /** * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES * @@ -1500,20 +1314,6 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES -/** - * \def MBEDTLS_SSL_RECORD_CHECKING - * - * Enable the function mbedtls_ssl_check_record() which can be used to check - * the validity and authenticity of an incoming record, to verify that it has - * not been seen before. These checks are performed without modifying the - * externally visible state of the SSL context. - * - * See mbedtls_ssl_check_record() for more information. - * - * Uncomment to enable support for record checking. - */ -//#define MBEDTLS_SSL_RECORD_CHECKING - /** * \def MBEDTLS_SSL_DTLS_CONNECTION_ID * @@ -1524,8 +1324,9 @@ * in the underlying transport. * * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, - * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. - * See the corresponding documentation for more information. + * mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and + * `mbedtls_ssl_conf_cid()`. See the corresponding documentation for + * more information. * * \warning The Connection ID extension is still in draft state. * We make no stability promises for the availability @@ -1606,9 +1407,7 @@ * * This only affects CBC ciphersuites, and is useless if none is defined. * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 * * Comment this macro to disable support for Encrypt-then-MAC */ @@ -1619,37 +1418,17 @@ * Enable support for RFC 7627: Session Hash and Extended Master Secret * Extension. * - * This was introduced as "the proper fix" to the Triple Handshake familiy of + * This was introduced as "the proper fix" to the Triple Handshake family of * attacks, but it is recommended to always use it (even if you disable * renegotiation), since it actually fixes a more fundamental issue in the * original SSL/TLS design, and has implications beyond Triple Handshake. * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 * * Comment this macro to disable support for Extended Master Secret. */ #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET -/** - * \def MBEDTLS_SSL_FALLBACK_SCSV - * - * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV) - * for Preventing Protocol Downgrade Attacks. - * - * For servers, it is recommended to always enable this, unless you support - * only one version of TLS, or know for sure that none of your clients - * implements a fallback strategy. - * - * For clients, you only need this if you're using a fallback strategy, which - * is not recommended in the first place, unless you absolutely need it to - * interoperate with buggy (version-intolerant) servers. - * - * Comment this macro to disable support for FALLBACK_SCSV - */ -//#define MBEDTLS_SSL_FALLBACK_SCSV - /** * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE * @@ -1665,38 +1444,15 @@ * \note This option has no influence on the protection against the * triple handshake attack. Even if it is disabled, Mbed TLS will * still ensure that certificates do not change during renegotiation, - * for exaple by keeping a hash of the peer's certificate. + * for example by keeping a hash of the peer's certificate. + * + * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set. * * Comment this macro to disable storing the peer's certificate * after the handshake. */ //#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE -/** - * \def MBEDTLS_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Uncomment this macro to enable hooking functions. - */ -//#define MBEDTLS_SSL_HW_RECORD_ACCEL - -/** - * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING - * - * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. - * - * This is a countermeasure to the BEAST attack, which also minimizes the risk - * of interoperability issues compared to sending 0-length records. - * - * Comment this macro to disable 1/n-1 record splitting. - */ -//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING - /** * \def MBEDTLS_SSL_RENEGOTIATION * @@ -1719,29 +1475,6 @@ */ //#define MBEDTLS_SSL_RENEGOTIATION -/** - * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (MBEDTLS_SSL_SRV_C). - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Uncomment this macro to enable support for SSLv2 Client Hello messages. - */ -//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - /** * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH * @@ -1752,85 +1485,70 @@ #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH /** - * \def MBEDTLS_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. + * \def MBEDTLS_SSL_PROTO_TLS1_2 * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. + * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C + * (Depends on ciphersuites) * - * Comment this macro to disable support for SSL 3.0 + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 */ -//#define MBEDTLS_SSL_PROTO_SSL3 +#define MBEDTLS_SSL_PROTO_TLS1_2 /** - * \def MBEDTLS_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. + * \def MBEDTLS_SSL_PROTO_TLS1_3 * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C + * Enable support for TLS 1.3. * - * Comment this macro to disable support for TLS 1.0 - */ -//#define MBEDTLS_SSL_PROTO_TLS1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_1 + * \note The support for TLS 1.3 is not comprehensive yet, in particular + * pre-shared keys are not supported. + * See docs/architecture/tls13-support.md for a description of the TLS + * 1.3 support that this option enables. * - * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). + * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * Requires: MBEDTLS_PSA_CRYPTO_C * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C + * Note: even though TLS 1.3 depends on PSA Crypto, if you want it to only use + * PSA for all crypto operations, you need to also enable + * MBEDTLS_USE_PSA_CRYPTO; otherwise X.509 operations, and functions that are + * common with TLS 1.2 (record protection, running handshake hash) will still + * use non-PSA crypto. * - * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 + * Uncomment this macro to enable the support for TLS 1.3. */ -//#define MBEDTLS_SSL_PROTO_TLS1_1 +//#define MBEDTLS_SSL_PROTO_TLS1_3 /** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE * - * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C - * (Depends on ciphersuites) + * Enable TLS 1.3 middlebox compatibility mode. * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + * As specified in Section D.4 of RFC 8446, TLS 1.3 offers a compatibility + * mode to make a TLS 1.3 connection more likely to pass through middle boxes + * expecting TLS 1.2 traffic. * - * This macro is used to selectively enable experimental parts - * of the code that contribute to the ongoing development of - * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide - * no other purpose. + * Turning on the compatibility mode comes at the cost of a few added bytes + * on the wire, but it doesn't affect compatibility with TLS 1.3 implementations + * that don't use it. Therefore, unless transmission bandwidth is critical and + * you know that middlebox compatibility issues won't occur, it is therefore + * recommended to set this option. * - * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS, - * and no feature exposed through this macro is part of the - * public API. In particular, features under the control - * of this macro are experimental and don't come with any - * stability guarantees. + * Comment to disable compatibility mode for TLS 1.3. If + * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. * - * Uncomment this macro to enable experimental and partial - * functionality specific to TLS 1.3. */ -//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +//#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE /** * \def MBEDTLS_SSL_PROTO_DTLS * * Enable support for DTLS (all available versions). * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. * - * Requires: MBEDTLS_SSL_PROTO_TLS1_1 - * or MBEDTLS_SSL_PROTO_TLS1_2 + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 * * Comment this macro to disable support for DTLS */ @@ -1870,7 +1588,7 @@ * unless you know for sure amplification cannot be a problem in the * environment in which your server operates. * - * \warning Disabling this can ba a security risk! (see above) + * \warning Disabling this can be a security risk! (see above) * * Requires: MBEDTLS_SSL_PROTO_DTLS * @@ -1892,7 +1610,7 @@ * (see Section 5 of RFC 5764), are not handled by this feature. * Instead, after successful completion of a handshake negotiating * the use of DTLS-SRTP, the extended key exporter API - * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * mbedtls_ssl_conf_export_keys_cb() should be used to implement * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 * (this is implemented in the SSL example programs). * The resulting key should then be passed to an SRTP stack. @@ -1925,17 +1643,6 @@ */ //#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE -/** - * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT - * - * Enable support for a limit of records with bad MAC. - * - * See mbedtls_ssl_conf_dtls_badmac_limit(). - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT - /** * \def MBEDTLS_SSL_SESSION_TICKETS * @@ -1950,16 +1657,6 @@ */ //#define MBEDTLS_SSL_SESSION_TICKETS -/** - * \def MBEDTLS_SSL_EXPORT_KEYS - * - * Enable support for exporting key block and master secret. - * This is required for certain users of TLS, e.g. EAP-TLS. - * - * Comment this macro to disable support for key export - */ -//#define MBEDTLS_SSL_EXPORT_KEYS - /** * \def MBEDTLS_SSL_SERVER_NAME_INDICATION * @@ -1971,39 +1668,6 @@ */ #define MBEDTLS_SSL_SERVER_NAME_INDICATION -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -//#define MBEDTLS_SSL_TRUNCATED_HMAC - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - * - * Fallback to old (pre-2.7), non-conforming implementation of the truncated - * HMAC extension which also truncates the HMAC key. Note that this option is - * only meant for a transitory upgrade period and will be removed in a future - * version of the library. - * - * \warning The old implementation is non-compliant and has a security weakness - * (2^80 brute force attack on the HMAC key used for a single, - * uninterrupted connection). This should only be enabled temporarily - * when (1) the use of truncated HMAC is essential in order to save - * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use - * the fixed implementation yet (pre-2.7). - * - * \deprecated This option is deprecated and will be removed in a - * future version of Mbed TLS. - * - * Uncomment to fallback to old, non-compliant truncated HMAC implementation. - * - * Requires: MBEDTLS_SSL_TRUNCATED_HMAC - */ -//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - /** * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH * @@ -2103,17 +1767,14 @@ * will still continue to work as usual, so enabling this option should not * break backwards compatibility. * - * \warning The PSA Crypto API is in beta stage. While you're welcome to - * experiment using it, incompatible API changes are still possible, and some - * parts may not have reached the same quality as the rest of Mbed TLS yet. + * \note See docs/use-psa-crypto.md for a complete description of what this + * option currently does, and of parts that are not affected by it so far. * - * \warning This option enables new Mbed TLS APIs that are dependent on the - * PSA Crypto API, so can't come with the same stability guarantees as the - * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for - * now, access to these APIs is opt-in (via enabling the present option), in - * order to clearly differentiate them from the stable Mbed TLS APIs. + * \warning If you enable this option, you need to call `psa_crypto_init()` + * before calling any function from the SSL/TLS, X.509 or PK modules. * * Requires: MBEDTLS_PSA_CRYPTO_C. + * Conflicts with: MBEDTLS_ECP_RESTARTABLE * * Uncomment this to enable internal use of PSA Crypto and new associated APIs. */ @@ -2125,12 +1786,19 @@ * This setting allows support for cryptographic mechanisms through the PSA * API to be configured separately from support through the mbedtls API. * - * Uncomment this to enable use of PSA Crypto configuration settings which - * can be found in include/psa/crypto_config.h. + * When this option is disabled, the PSA API exposes the cryptographic + * mechanisms that can be implemented on top of the `mbedtls_xxx` API + * configured with `MBEDTLS_XXX` symbols. + * + * When this option is enabled, the PSA API exposes the cryptographic + * mechanisms requested by the `PSA_WANT_XXX` symbols defined in + * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are + * automatically enabled if required (i.e. if no PSA driver provides the + * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols + * in mbedtls_config.h. * - * If you enable this option and write your own configuration file, you must - * include mbedtls/config_psa.h in your configuration file. The default - * provided mbedtls/config.h contains the necessary inclusion. + * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies + * an alternative header to include instead of include/psa/crypto_config.h. * * This feature is still experimental and is not ready for production since * it is not completed. @@ -2150,28 +1818,6 @@ */ //#define MBEDTLS_VERSION_FEATURES -/** - * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * \warning Depending on your PKI use, enabling this can be a security risk! - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - /** * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK * @@ -2192,31 +1838,15 @@ //#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK /** - * \def MBEDTLS_X509_CHECK_KEY_USAGE + * \def MBEDTLS_X509_REMOVE_INFO * - * Enable verification of the keyUsage extension (CA and leaf certificates). + * Disable mbedtls_x509_*_info() and related APIs. * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -#define MBEDTLS_X509_CHECK_KEY_USAGE - -/** - * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. + * Uncomment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() + * and other functions/constants only used by these functions, thus reducing + * the code footprint by several KB. */ -#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE +//#define MBEDTLS_X509_REMOVE_INFO /** * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT @@ -2227,32 +1857,7 @@ * Comment this macro to disallow using RSASSA-PSS in certificates. */ //#define MBEDTLS_X509_RSASSA_PSS_SUPPORT - -/** - * \def MBEDTLS_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be applicable to your use case. - * - * \note Currently compression can't be used with DTLS. - * - * \deprecated This feature is deprecated and will be removed - * in the next major revision of the library. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define MBEDTLS_ZLIB_SUPPORT -/* \} name SECTION: mbed TLS feature support */ +/** \} name SECTION: mbed TLS feature support */ /** * \name SECTION: mbed TLS modules @@ -2350,34 +1955,6 @@ */ #define MBEDTLS_AES_C -/** - * \def MBEDTLS_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. If possible, we recommend avoidng dependencies on - * it, and considering stronger ciphers instead. - * - */ -//#define MBEDTLS_ARC4_C - /** * \def MBEDTLS_ASN1_PARSE_C * @@ -2428,22 +2005,13 @@ * library/ecp.c * library/ecdsa.c * library/rsa.c - * library/rsa_internal.c + * library/rsa_alt_helpers.c * library/ssl_tls.c * * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. */ #define MBEDTLS_BIGNUM_C -/** - * \def MBEDTLS_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -//#define MBEDTLS_BLOWFISH_C - /** * \def MBEDTLS_CAMELLIA_C * @@ -2558,25 +2126,14 @@ * * Module: library/ccm.c * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C * * This module enables the AES-CCM ciphersuites, if other requisites are * enabled as well. */ #define MBEDTLS_CCM_C -/** - * \def MBEDTLS_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -//#define MBEDTLS_CERTS_C - /** * \def MBEDTLS_CHACHA20_C * @@ -2603,7 +2160,17 @@ * Enable the generic cipher layer. * * Module: library/cipher.c - * Caller: library/ssl_tls.c + * Caller: library/ccm.c + * library/cmac.c + * library/gcm.c + * library/nist_kw.c + * library/pkcs12.c + * library/pkcs5.c + * library/psa_crypto_aead.c + * library/psa_crypto_mac.c + * library/ssl_ciphersuites.c + * library/ssl_msg.c + * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) * * Uncomment to enable generic cipher wrappers. */ @@ -2615,9 +2182,14 @@ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block * ciphers. * + * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying + * implementation of the CMAC algorithm is provided by an alternate + * implementation, that alternate implementation may opt to not support + * AES-192 or 3DES as underlying block ciphers for the CMAC operation. + * * Module: library/cmac.c * - * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C * */ //#define MBEDTLS_CMAC_C @@ -2648,9 +2220,10 @@ * Enable the debug functions. * * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c + * Caller: library/ssl_msg.c * library/ssl_tls.c + * library/ssl_tls12_*.c + * library/ssl_tls13_*.c * * This module provides debugging functions. */ @@ -2665,19 +2238,6 @@ * Caller: library/pem.c * library/cipher.c * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * * PEM_PARSE uses DES/3DES for decrypting encrypted keys. * * \warning DES is considered a weak cipher and its use constitutes a @@ -2691,8 +2251,9 @@ * Enable the Diffie-Hellman-Merkle module. * * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c * * This module is used by the following key exchanges: * DHE-RSA, DHE-PSK @@ -2712,8 +2273,10 @@ * Enable the elliptic curve Diffie-Hellman library. * * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c + * Caller: library/psa_crypto.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c * * This module is used by the following key exchanges: * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK @@ -2744,9 +2307,9 @@ * * Enable the elliptic curve J-PAKE library. * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. + * \note EC J-PAKE support is based on the Thread v1.0.0 specification. + * It has not been reviewed for compliance with newer standards such as + * Thread v1.1 or RFC 8236. * * Module: library/ecjpake.c * Caller: @@ -2805,36 +2368,14 @@ * * Module: library/gcm.c * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C * * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other * requisites are enabled as well. */ #define MBEDTLS_GCM_C -/** - * \def MBEDTLS_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: MBEDTLS_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define MBEDTLS_HAVEGE_C - /** * \def MBEDTLS_HKDF_C * @@ -2860,7 +2401,7 @@ * * Requires: MBEDTLS_MD_C * - * Uncomment to enable the HMAC_DRBG random number geerator. + * Uncomment to enable the HMAC_DRBG random number generator. */ //#define MBEDTLS_HMAC_DRBG_C @@ -2883,46 +2424,29 @@ * Enable the generic message digest layer. * * Module: library/md.c - * Caller: + * Caller: library/constant_time.c + * library/ecdsa.c + * library/ecjpake.c + * library/hkdf.c + * library/hmac_drbg.c + * library/pk.c + * library/pkcs5.c + * library/pkcs12.c + * library/psa_crypto_ecp.c + * library/psa_crypto_rsa.c + * library/rsa.c + * library/ssl_cookie.c + * library/ssl_msg.c + * library/ssl_tls.c + * library/x509.c + * library/x509_crt.c + * library/x509write_crt.c + * library/x509write_csr.c * * Uncomment to enable generic message digest wrappers. */ #define MBEDTLS_MD_C -/** - * \def MBEDTLS_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - * - * \warning MD2 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD2_C - -/** - * \def MBEDTLS_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - * - * \warning MD4 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD4_C - /** * \def MBEDTLS_MD5_C * @@ -2933,10 +2457,9 @@ * library/pem.c * library/ssl_tls.c * - * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 - * depending on the handshake parameters. Further, it is used for checking - * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded - * encrypted keys. + * This module is required for TLS 1.2 depending on the handshake parameters. + * Further, it is used for checking MD5-signed certificates, and for PBKDF1 + * when decrypting PEM-encoded encrypted keys. * * \warning MD5 is considered a weak message digest and its use constitutes a * security risk. If possible, we recommend avoiding dependencies on @@ -3054,14 +2577,16 @@ /** * \def MBEDTLS_PK_C * - * Enable the generic public (asymetric) key layer. + * Enable the generic public (asymmetric) key layer. * * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c + * Caller: library/psa_crypto_rsa.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * library/x509.c * - * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C * * Uncomment to enable generic public key wrappers. */ @@ -3070,7 +2595,7 @@ /** * \def MBEDTLS_PK_PARSE_C * - * Enable the generic public (asymetric) key parser. + * Enable the generic public (asymmetric) key parser. * * Module: library/pkparse.c * Caller: library/x509_crt.c @@ -3085,7 +2610,7 @@ /** * \def MBEDTLS_PK_WRITE_C * - * Enable the generic public (asymetric) key writer. + * Enable the generic public (asymmetric) key writer. * * Module: library/pkwrite.c * Caller: library/x509write.c @@ -3103,30 +2628,12 @@ * * Module: library/pkcs5.c * - * Requires: MBEDTLS_MD_C + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C * * This module adds support for the PKCS#5 functions. */ #define MBEDTLS_PKCS5_C -/** - * \def MBEDTLS_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support via the pkcs11-helper library. - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: MBEDTLS_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define MBEDTLS_PKCS11_C - /** * \def MBEDTLS_PKCS12_C * @@ -3137,7 +2644,6 @@ * Caller: library/pkparse.c * * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * Can use: MBEDTLS_ARC4_C * * This module enables PKCS#12 functions. */ @@ -3178,27 +2684,24 @@ * * Enable the Platform Security Architecture cryptography API. * - * \warning The PSA Crypto API is still beta status. While you're welcome to - * experiment using it, incompatible API changes are still possible, and some - * parts may not have reached the same quality as the rest of Mbed TLS yet. - * * Module: library/psa_crypto.c * - * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, + * Requires: MBEDTLS_CIPHER_C, + * either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. * */ -//#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_C /** * \def MBEDTLS_PSA_CRYPTO_SE_C * - * Enable secure element support in the Platform Security Architecture + * Enable dynamic secure element support in the Platform Security Architecture * cryptography API. * - * \warning This feature is not yet suitable for production. It is provided - * for API evaluation and testing purposes only. + * \deprecated This feature is deprecated. Please switch to the driver + * interface enabled by #MBEDTLS_PSA_CRYPTO_DRIVERS. * * Module: library/psa_crypto_se.c * @@ -3249,11 +2752,12 @@ * Enable the RSA public-key cryptosystem. * * Module: library/rsa.c - * library/rsa_internal.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c + * library/rsa_alt_helpers.c + * Caller: library/pk.c + * library/psa_crypto.c * library/ssl_tls.c - * library/x509.c + * library/ssl*_client.c + * library/ssl*_server.c * * This module is used by the following key exchanges: * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK @@ -3269,13 +2773,10 @@ * * Module: library/sha1.c * Caller: library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c + * library/psa_crypto_hash.c * - * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 - * depending on the handshake parameters, and for SHA1-signed certificates. + * This module is required for TLS 1.2 depending on the handshake parameters, + * and for SHA1-signed certificates. * * \warning SHA-1 is considered a weak message digest and its use constitutes * a security risk. If possible, we recommend avoiding dependencies @@ -3284,37 +2785,177 @@ */ #define MBEDTLS_SHA1_C +/** + * \def MBEDTLS_SHA224_C + * + * Enable the SHA-224 cryptographic hash algorithm. + * + * Requires: MBEDTLS_SHA256_C. The library does not currently support enabling + * SHA-224 without SHA-256. + * + * Module: library/sha256.c + * Caller: library/md.c + * library/ssl_cookie.c + * + * This module adds support for SHA-224. + */ +#define MBEDTLS_SHA224_C + /** * \def MBEDTLS_SHA256_C * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * Enable the SHA-256 cryptographic hash algorithm. + * + * Requires: MBEDTLS_SHA224_C. The library does not currently support enabling + * SHA-256 without SHA-224. * * Module: library/sha256.c * Caller: library/entropy.c * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c * - * This module adds support for SHA-224 and SHA-256. + * This module adds support for SHA-256. * This module is required for the SSL/TLS 1.2 PRF function. */ #define MBEDTLS_SHA256_C +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building + * for a non-Aarch64 build it will be silently ignored. + * + * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum + * of \c -march=armv8-a+crypto. + * + * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library check for the A64 SHA-256 crypto extensions + * and use them if available. + */ +//#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + * + * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum + * of \c -march=armv8-a+crypto. + * + * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library use the A64 SHA-256 crypto extensions + * unconditionally. + */ +//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + +/** + * \def MBEDTLS_SHA384_C + * + * Enable the SHA-384 cryptographic hash algorithm. + * + * Requires: MBEDTLS_SHA512_C + * + * Module: library/sha512.c + * Caller: library/md.c + * library/psa_crypto_hash.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * Comment to disable SHA-384 + */ +//#define MBEDTLS_SHA384_C + /** * \def MBEDTLS_SHA512_C * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * Enable SHA-512 cryptographic hash algorithms. * * Module: library/sha512.c * Caller: library/entropy.c * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c + * library/ssl_tls.c + * library/ssl_cookie.c * - * This module adds support for SHA-384 and SHA-512. + * This module adds support for SHA-512. */ //#define MBEDTLS_SHA512_C +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building + * for a non-Aarch64 build it will be silently ignored. + * + * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or + * Clang >= 7, and \c CFLAGS must be set to a minimum of + * \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the + * fastest code. + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library check for the A64 SHA-512 crypto extensions + * and use them if available. + */ +//#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or + * Clang >= 7, and \c CFLAGS must be set to a minimum of + * \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the + * fastest code. + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library use the A64 SHA-512 crypto extensions + * unconditionally. + */ +//#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY /** * \def MBEDTLS_SSL_CACHE_C @@ -3346,7 +2987,7 @@ * Module: library/ssl_ticket.c * Caller: * - * Requires: MBEDTLS_CIPHER_C + * Requires: MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO */ //#define MBEDTLS_SSL_TICKET_C @@ -3355,7 +2996,7 @@ * * Enable the SSL/TLS client code. * - * Module: library/ssl_cli.c + * Module: library/ssl*_client.c * Caller: * * Requires: MBEDTLS_SSL_TLS_C @@ -3369,7 +3010,7 @@ * * Enable the SSL/TLS server code. * - * Module: library/ssl_srv.c + * Module: library/ssl*_server.c * Caller: * * Requires: MBEDTLS_SSL_TLS_C @@ -3384,8 +3025,8 @@ * Enable the generic SSL/TLS code. * * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c + * Caller: library/ssl*_client.c + * library/ssl*_server.c * * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C * and at least one of the MBEDTLS_SSL_PROTO_XXX defines @@ -3428,14 +3069,15 @@ * your own implementation of the whole module by setting * \c MBEDTLS_TIMING_ALT in the current file. * + * \note The timing module will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. + * * \note See also our Knowledge Base article about porting to a new * environment: * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS * * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. */ //#define MBEDTLS_TIMING_C @@ -3473,9 +3115,9 @@ * Enable X.509 certificate parsing. * * Module: library/x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c * * Requires: MBEDTLS_X509_USE_C * @@ -3550,17 +3192,89 @@ */ #define MBEDTLS_X509_CSR_WRITE_C +/** \} name SECTION: mbed TLS modules */ + /** - * \def MBEDTLS_XTEA_C + * \name SECTION: General configuration options * - * Enable the XTEA block cipher. + * This section contains Mbed TLS build settings that are not associated + * with a particular module. * - * Module: library/xtea.c - * Caller: + * \{ */ -//#define MBEDTLS_XTEA_C -/* \} name SECTION: mbed TLS modules */ +/** + * \def MBEDTLS_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"mbedtls/mbedtls_config.h"`. + * This header file specifies the compile-time configuration of Mbed TLS. + * Unlike other configuration options, this one must be defined on the + * compiler command line: a definition in `mbedtls_config.h` would have + * no effect. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" + +/** + * \def MBEDTLS_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_config.h"`. + * This header file specifies which cryptographic mechanisms are available + * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and + * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" + +/** \} name SECTION: General configuration options */ /** * \name SECTION: Module configuration options @@ -3571,22 +3285,26 @@ * * Our advice is to enable options and change their values here * only if you have a good reason and know the consequences. - * - * Please check the respective header file for documentation on these - * parameters (to prevent duplicate documentation). * \{ */ +/* The Doxygen documentation here is used when a user comments out a + * setting and runs doxygen themselves. On the other hand, when we typeset + * the full documentation including disabled settings, the documentation + * in specific modules' header files is used if present. When editing this + * file, make sure that each option is documented in exactly one place, + * plus optionally a same-line Doxygen comment here if there is a Doxygen + * comment in the specific module. */ /* MPI / BIGNUM options */ //#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ //#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ /* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with -// SHA-512, 32 with SHA-256) */ #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is -// performed by default */ #define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input -// bytes */ #define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with +// SHA-256) */ #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ #define +// MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ #define +// MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ #define +// MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ /* HMAC_DRBG options */ //#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ @@ -3595,88 +3313,74 @@ //#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ /* ECP options */ -//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ -//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ //#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ /* Entropy options */ //#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ //#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware -// entropy source mbedtls_hardware_poll() before entropy is released */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy +// source mbedtls_hardware_poll() before entropy is released */ /* Memory buffer allocator options */ //#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ /* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is -// defined. Don't define if no header is needed. */ #define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default -// allocator to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can -// be undefined */ #define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must -// be enabled */ #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't +// define if no header is needed. */ #define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be +// undefined */ #define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ #define +// MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_EXIT exit +///**< Default exit to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be +// undefined. MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, +// can be undefined */ #define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ /* Note: your snprintf must correctly zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to -// use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default -// nv_seed_write function to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed -// file to read/write with default implementation */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be +// undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function +// to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default +// implementation */ /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ //#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. -// MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to -// use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< -// Default fprintf macro to use, can be undefined */ #define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default -// printf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be +// enabled */ #define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. +// MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can +// be undefined */ #define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ /* Note: your snprintf must correctly zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to -// use, can be undefined */ #define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< -// Default nv_seed_write function to use, can be undefined */ - -/** - * \brief This macro is invoked by the library when an invalid parameter - * is detected that is only checked with #MBEDTLS_CHECK_PARAMS - * (see the documentation of that option for context). - * - * When you leave this undefined here, the library provides - * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT - * is defined, the default definition is `assert(cond)`, - * otherwise the default definition calls a function - * mbedtls_param_failed(). This function is declared in - * `platform_util.h` for the benefit of the library, but - * you need to define in your application. - * - * When you define this here, this replaces the default - * definition in platform_util.h (which no longer declares the - * function mbedtls_param_failed()) and it is your responsibility - * to make sure this macro expands to something suitable (in - * particular, that all the necessary declarations are visible - * from within the library - you can ensure that by providing - * them in this file next to the macro definition). - * If you define this macro to call `assert`, also define - * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files - * include ``. - * - * Note that you may define this macro to expand to nothing, in - * which case you don't have to worry about declarations or - * definitions. However, you will then be notified about invalid - * parameters only in non-void functions, and void function will - * just silently return early on invalid parameters, which - * partially negates the benefits of enabling - * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. - * - * \param cond The expression that should evaluate to true, but doesn't. - */ -//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be +// undefined */ #define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function +// to use, can be undefined */ + +/** \def MBEDTLS_CHECK_RETURN + * + * This macro is used at the beginning of the declaration of a function + * to indicate that its return value should be checked. It should + * instruct the compiler to emit a warning or an error if the function + * is called without checking its return value. + * + * There is a default implementation for popular compilers in platform_util.h. + * You can override the default implementation by defining your own here. + * + * If the implementation here is empty, this will effectively disable the + * checking of functions' return values. + */ +//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) + +/** \def MBEDTLS_IGNORE_RETURN + * + * This macro requires one argument, which should be a C function call. + * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this + * warning is suppressed. + */ +//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) /* PSA options */ /** @@ -3708,32 +3412,6 @@ /* SSL options */ -/** \def MBEDTLS_SSL_MAX_CONTENT_LEN - * - * Maximum length (in bytes) of incoming and outgoing plaintext fragments. - * - * This determines the size of both the incoming and outgoing TLS I/O buffers - * in such a way that both are capable of holding the specified amount of - * plaintext data, regardless of the protection mechanism used. - * - * To configure incoming and outgoing I/O buffers separately, use - * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, - * which overwrite the value set by this option. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of both - * incoming and outgoing I/O buffers. - */ -#define MBEDTLS_SSL_MAX_CONTENT_LEN 8192 - /** \def MBEDTLS_SSL_IN_CONTENT_LEN * * Maximum length (in bytes) of incoming plaintext fragments. @@ -3742,9 +3420,6 @@ * that it is capable of holding the specified amount of plaintext data, * regardless of the protection mechanism used. * - * If this option is undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * * \note When using a value less than the default of 16KB on the client, it is * recommended to use the Maximum Fragment Length (MFL) extension to * inform the server about this limitation. On the server, there @@ -3754,8 +3429,7 @@ * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN * while keeping the default value of 16KB for the incoming buffer. * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer - * independently of the outgoing I/O buffer. + * Uncomment to set the maximum plaintext size of the incoming I/O buffer. */ //#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 @@ -3773,27 +3447,10 @@ */ //#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 -/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * when using the Connection ID extension in DTLS 1.2. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - * - */ -//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 - -/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY +/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY * * This option controls the use of record plaintext padding - * in TLS 1.3. + * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. * * The padding will always be chosen so that the length of the * padded plaintext is a multiple of the value of this option. @@ -3804,7 +3461,7 @@ * Note: On systems lacking division instructions, * a power of two should be preferred. */ -//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 +//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 /** \def MBEDTLS_SSL_OUT_CONTENT_LEN * @@ -3814,9 +3471,6 @@ * that it is capable of holding the specified amount of plaintext data, * regardless of the protection mechanism used. * - * If this option undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * * It is possible to save RAM by setting a smaller outward buffer, while keeping * the default inward 16384 byte buffer to conform to the TLS specification. * @@ -3825,8 +3479,7 @@ * The specific size requirement depends on the configured ciphers and any * certificate data which is sent during the handshake. * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer - * independently of the incoming I/O buffer. + * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. */ //#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 @@ -3835,7 +3488,7 @@ * Maximum number of heap-allocated bytes for the purpose of * DTLS handshake message reassembly and future message buffering. * - * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN + * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN * to account for a reassembled handshake message of maximum size, * together with its reassembly bitmap. * @@ -3847,10 +3500,20 @@ */ //#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 -//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, -// or in number of cookies issued */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number +// of cookies issued */ + +/** \def MBEDTLS_TLS_EXT_CID + * + * At the time of writing, the CID extension has not been assigned its + * final value. Set this configuration option to make Mbed TLS use a + * different value. + * + * A future minor revision of Mbed TLS may change the default value of + * this option to match evolving standards and usage. + */ +//#define MBEDTLS_TLS_EXT_CID 254 /** * Complete list of ciphersuites to use, in order of preference. @@ -3864,44 +3527,12 @@ * * The value below is only an example, not the default. */ -//#define MBEDTLS_SSL_CIPHERSUITES -// MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 /* X509 options */ //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the -// null terminator character ('\0'). */ - -/** - * Allow SHA-1 in the default TLS configuration for certificate signing. - * Without this build-time option, SHA-1 support must be activated explicitly - * through mbedtls_ssl_conf_cert_profile. Turning on this option is not - * recommended because of it is possible to generate SHA-1 collisions, however - * this may be safe for legacy infrastructure where additional controls apply. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES - -/** - * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake - * signature and ciphersuite selection. Without this build-time option, SHA-1 - * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. - * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by - * default. At the time of writing, there is no practical attack on the use - * of SHA-1 in handshake signatures, hence this option is turned on by default - * to preserve compatibility with existing peers, but the general - * warning applies nonetheless: - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null +// terminator character ('\0'). */ /** * Uncomment the macro to let mbed TLS use your alternate implementation of @@ -3951,10 +3582,4 @@ */ //#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) -#include "mbedtls/config_psa.h" -#endif - -#include "mbedtls/check_config.h" - -#endif /* MBEDTLS_CONFIG_H */ +/** \} name SECTION: Module configuration options */ diff --git a/config/openiotsdk/storage/CMakeLists.txt b/config/openiotsdk/storage/CMakeLists.txt new file mode 100644 index 00000000000000..a7f1e0b53f0e4a --- /dev/null +++ b/config/openiotsdk/storage/CMakeLists.txt @@ -0,0 +1,34 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# + +cmake_minimum_required(VERSION 3.21) + +# Declare Open IoT SDK app interface target +add_library(openiotsdk-storage + FlashBlockDevice.cpp +) + +target_include_directories(openiotsdk-storage + PUBLIC + . + ${CHIP_ROOT}/src/platform/openiotsdk +) + +target_link_libraries(openiotsdk-storage + PUBLIC + mcu-driver-hal + iotsdk-blockdevice +) diff --git a/config/openiotsdk/storage/FlashBlockDevice.cpp b/config/openiotsdk/storage/FlashBlockDevice.cpp new file mode 100644 index 00000000000000..e876dec9eaed19 --- /dev/null +++ b/config/openiotsdk/storage/FlashBlockDevice.cpp @@ -0,0 +1,287 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 + * Utilities for interacting with the the Open IoT SDK key-value storage. + */ + +#include + +#include "FlashBlockDevice.h" +#include + +extern "C" { +#include +} + +#define FLASH_BASE_ADDRESS (SRAM_BASE_NS) /* 0x01000000 */ +#define FLASH_TOTAL_SIZE (SRAM_SIZE) /* 2 MB */ +#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB */ +#define FLASH_PAGE_SIZE 256 +#define FLASH_END_ADDRESS (FLASH_BASE_ADDRESS + FLASH_TOTAL_SIZE) +#define FLASH_READ_SIZE 1 +#define FLASH_ERASE_VALUE 0xFFU + +namespace iotsdk { +namespace storage { + +FlashBlockDevice::FlashBlockDevice(uint32_t address, uint32_t size) : _base(address), _size(size), _is_initialized(false) {} + +FlashBlockDevice::~FlashBlockDevice() {} + +bd_status FlashBlockDevice::init() +{ + if (!_base) + { + _base = FLASH_BASE_ADDRESS; + } + + if (!_size) + { + _size = FLASH_TOTAL_SIZE - (_base - FLASH_BASE_ADDRESS); + } + + if (_size + _base > FLASH_TOTAL_SIZE + FLASH_BASE_ADDRESS) + { + return bd_status::INCORRECT_SIZE; + } + + if (_base < FLASH_BASE_ADDRESS) + { + return bd_status::INCORRECT_ADDRESS; + } + + _is_initialized = true; + return bd_status::OK; +} + +bd_status FlashBlockDevice::deinit() +{ + if (!_is_initialized) + { + return bd_status::OK; + } + + _is_initialized = false; + + return bd_status::OK; +} + +bd_status FlashBlockDevice::read(void * buffer, bd_addr_t virtual_address, bd_size_t size) +{ + if (!_is_initialized) + { + return bd_status::DEVICE_NOT_INITIALIZED; + } + + /* Check that the address and size are properly aligned and fit. */ + bd_status status = is_valid_read(virtual_address, size); + if (status != bd_status::OK) + { + return status; + } + + /* Convert virtual address to the physical address for the device. */ + const auto physical_address = static_cast(_base + virtual_address); + + /* Read data */ + memcpy(static_cast(buffer), (void *) physical_address, static_cast(size)); + + return bd_status::OK; +} + +bd_status FlashBlockDevice::program(const void * buffer, bd_addr_t virtual_address, bd_size_t size) +{ + if (!_is_initialized) + { + return bd_status::DEVICE_NOT_INITIALIZED; + } + + /* Check that the address and size are properly aligned and fit. */ + bd_status status = is_valid_program(virtual_address, size); + if (status != bd_status::OK) + { + return status; + } + + /* Convert virtual address to the physical address for the device. */ + auto physical_address = static_cast(_base + virtual_address); + auto remaining_size = static_cast(size); + const auto * buf = static_cast(buffer); + + while (remaining_size > 0) + { + /* Multiple pages can be programmed at once but cannot cross sector boundaries */ + const auto sector_size = FLASH_AREA_IMAGE_SECTOR_SIZE; + const auto sector_end = (physical_address / sector_size + 1) * sector_size; + const auto chunk = (physical_address + remaining_size > sector_end) ? (sector_end - physical_address) : remaining_size; + /* Write data */ + memcpy((void *) physical_address, buf, chunk); + physical_address += chunk; + remaining_size -= chunk; + buf += chunk; + } + + return bd_status::OK; +} + +bd_status FlashBlockDevice::erase(bd_addr_t virtual_address, bd_size_t size) +{ + if (!_is_initialized) + { + return bd_status::DEVICE_NOT_INITIALIZED; + } + + /* Check that the address and size are properly aligned and fit. */ + const bd_status status = is_valid_erase(virtual_address, size); + if (status != bd_status::OK) + { + return status; + } + + /* Convert virtual address to the physical address for the device. */ + auto physical_address = static_cast(_base + virtual_address); + const auto sector_size = FLASH_AREA_IMAGE_SECTOR_SIZE; + const auto erase_region = (physical_address + size) - sector_size; + + while (physical_address <= erase_region) + { + memset((void *) physical_address, FLASH_ERASE_VALUE, FLASH_AREA_IMAGE_SECTOR_SIZE); + physical_address += sector_size; + } + + return bd_status::OK; +} + +bd_size_t FlashBlockDevice::get_read_size() const +{ + return FLASH_READ_SIZE; +} + +bd_size_t FlashBlockDevice::get_program_size() const +{ + if (!_is_initialized) + { + return 0; + } + + return FLASH_PAGE_SIZE; +} + +bd_size_t FlashBlockDevice::get_erase_size() const +{ + return 0; +} + +bd_size_t FlashBlockDevice::get_erase_size(bd_addr_t addr) const +{ + if (!_is_initialized) + { + return 0; + } + + if (static_cast(_base) + addr > UINT32_MAX) + { + return 0; + } + + return FLASH_AREA_IMAGE_SECTOR_SIZE; +} + +int FlashBlockDevice::get_erase_value() const +{ + if (!_is_initialized) + { + return -1; + } + + return FLASH_ERASE_VALUE; +} + +bd_size_t FlashBlockDevice::size() const +{ + return _size; +} + +const char * FlashBlockDevice::get_type() const +{ + return "FLASH_BD"; +} + +bd_status FlashBlockDevice::is_valid_read(bd_addr_t addr, bd_size_t size) const +{ + if (static_cast(_base) + addr > UINT32_MAX) + { + return bd_status::INCORRECT_ADDRESS; + } + + if (size > UINT32_MAX) + { + return bd_status::INCORRECT_SIZE; + } + + return BlockDevice::is_valid_read(addr, size); +} + +bd_status FlashBlockDevice::is_valid_program(bd_addr_t addr, bd_size_t size) const +{ + if (static_cast(_base) + addr > UINT32_MAX) + { + return bd_status::INCORRECT_ADDRESS; + } + + if (size > UINT32_MAX) + { + return bd_status::INCORRECT_SIZE; + } + + return BlockDevice::is_valid_program(addr, size); +} + +bd_status FlashBlockDevice::is_valid_erase(bd_addr_t addr, bd_size_t size) const +{ + if (static_cast(_base) + addr > UINT32_MAX) + { + return bd_status::INCORRECT_ADDRESS; + } + + if (size > UINT32_MAX) + { + return bd_status::INCORRECT_SIZE; + } + + return BlockDevice::is_valid_erase(addr, size); +} + +} // namespace storage +} // namespace iotsdk + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +static iotsdk::storage::FlashBlockDevice gBlockDevice(0, 0); + +iotsdk::storage::BlockDevice * GetBlockDevice() +{ + return &gBlockDevice; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/config/openiotsdk/storage/FlashBlockDevice.h b/config/openiotsdk/storage/FlashBlockDevice.h new file mode 100644 index 00000000000000..95ba8375e7c9db --- /dev/null +++ b/config/openiotsdk/storage/FlashBlockDevice.h @@ -0,0 +1,185 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * 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 + */ + +#ifndef IOTSDK_FLASH_BLOCKDEVICE_H +#define IOTSDK_FLASH_BLOCKDEVICE_H + +#include "iotsdk/BlockDevice.h" + +#include + +namespace iotsdk { +namespace storage { +/** BlockDevice using the flash memory for TF-M application + * + */ +class FlashBlockDevice final : public BlockDevice +{ +public: + /** Creates a FlashBlockDevice + * @param address Physical address where the block device start + * @param size The block device size + */ + FlashBlockDevice(uint32_t address, uint32_t size); + + ~FlashBlockDevice(); + + /** Initialize a block device + * + * This method must be called before attempting any further block device operations. + * + * @return bd_status::OK on success or an error status on failure + */ + bd_status init() override; + + /** Deinitialize a block device + * + * @return bd_status::OK on success or an error status on failure + */ + bd_status deinit() override; + + /** Read blocks from a block device + * + * If a failure occurs, it is not possible to determine how many bytes succeeded. + * + * @param buffer Buffer to write blocks to + * @param addr Address of block to begin reading from + * @param size Size to read in bytes, must be a multiple of the read block size + * @return bd_status::OK on success or an error status on failure + */ + bd_status read(void * buffer, bd_addr_t addr, bd_size_t size) override; + + /** Program blocks to a block device + * + * The blocks must have been erased prior to being programmed. + * + * If a failure occurs, it is not possible to determine how many bytes succeeded. + * + * @param buffer Buffer of data to write to blocks + * @param addr Address of block to begin writing to + * @param size Size to write in bytes, must be a multiple of the program block size + * @return bd_status::OK on success or an error status on failure + */ + bd_status program(const void * buffer, bd_addr_t addr, bd_size_t size) override; + + /** Erase blocks on a block device + * + * The state of an erased block is undefined until it has been programmed, + * unless get_erase_value returns a non-negative byte value. + * + * @param addr Address of block to begin erasing + * @param size Size to erase in bytes, must be a multiple of the erase block size + * @return bd_status::OK on success or an error status on failure + */ + bd_status erase(bd_addr_t addr, bd_size_t size) override; + + /** Get the size of a readable block + * + * @return Size of a readable block in bytes + */ + bd_size_t get_read_size() const override; + + /** Get the size of a programmable block + * + * @return Size of a programmable block in bytes + * @note Must be a multiple of the read size + */ + bd_size_t get_program_size() const override; + + /** Get the size of an erasable block for the whole device + * + * @return Size of an erasable block in bytes for the whole device + * @note Must be a multiple of the program size, or 0 if no common erase size exists + * across all regions or the underlying implementation does not provide this + * information in which case you need to call get_erase_size(bd_addr_t) instead + * @note For FlashBlockDevice, this always returns 0 because the underlying + * MCU-Driver-HAL flash API does not indicate whether all sectors have the same + * size + */ + bd_size_t get_erase_size() const override; + + /** Get the size of an erasable block given address + * + * @param addr Address within the erasable block + * @return Size of an erasable block in bytes + * @note Must be a multiple of the program size + */ + bd_size_t get_erase_size(bd_addr_t addr) const override; + + /** Get the value of storage when erased + * + * If get_erase_value returns a non-negative byte value, the underlying + * storage is set to that value when erased, and storage containing + * that value can be programmed without another erase. + * + * @return The value of storage when erased, or -1 if you can't + * rely on the value of the erased storage + */ + int get_erase_value() const override; + + /** Get the total size of the underlying device + * + * @return Size of the underlying device in bytes + */ + bd_size_t size() const override; + + /** Convenience function for checking block read validity + * + * @param addr Address of block to begin reading from + * @param size Size to read in bytes + * @return bd_status::OK if read is valid for underlying block device + */ + bd_status is_valid_read(bd_addr_t addr, bd_size_t size) const override; + + /** Convenience function for checking block program validity + * + * @param addr Address of block to begin writing to + * @param size Size to write in bytes + * @return bd_status::OK if program is valid for underlying block device + */ + bd_status is_valid_program(bd_addr_t addr, bd_size_t size) const override; + + /** Convenience function for checking block erase validity + * + * @param addr Address of block to begin erasing + * @param size Size to erase in bytes + * @return bd_status::OK if erase is valid for underlying block device + */ + bd_status is_valid_erase(bd_addr_t addr, bd_size_t size) const override; + + /** Get the BlockDevice class type. + * + * @return A string represent the BlockDevice class type. + */ + const char * get_type() const override; + +private: + // Device configuration + uint32_t _base; + uint32_t _size; + bool _is_initialized; +}; + +} // namespace storage +} // namespace iotsdk + +#endif /* IOTSDK_FLASH_BLOCKDEVICE_H */ diff --git a/config/openiotsdk/util.cmake b/config/openiotsdk/util.cmake index 23e0aabe662ee3..cfa34725f781fa 100644 --- a/config/openiotsdk/util.cmake +++ b/config/openiotsdk/util.cmake @@ -137,16 +137,3 @@ function(convert_list_of_flags_to_string_of_flags ptr_list_of_flags string_of_fl # Set the output variable in the parent scope set(${string_of_flags} ${locally_scoped_string_of_flags} PARENT_SCOPE) endfunction() - - -function (get_all_cmake_targets out_var current_dir) - get_property(targets DIRECTORY ${current_dir} PROPERTY BUILDSYSTEM_TARGETS) - get_property(subdirs DIRECTORY ${current_dir} PROPERTY SUBDIRECTORIES) - - foreach(subdir ${subdirs}) - get_all_cmake_targets(subdir_targets ${subdir}) - list(APPEND targets ${subdir_targets}) - endforeach() - - set(${out_var} ${targets} PARENT_SCOPE) -endfunction() \ No newline at end of file diff --git a/docs/examples/openiotsdk_examples.md b/docs/examples/openiotsdk_examples.md index 36e12236c62172..6cdca9c5a8fdf1 100644 --- a/docs/examples/openiotsdk_examples.md +++ b/docs/examples/openiotsdk_examples.md @@ -140,6 +140,51 @@ Then add the GDB plugin to your development environment: arguments with `docker run` command. Remember add GDB plugin path to environment variable as FAST_MODEL_PLUGINS_PATH inside container. +## Configuration + +### Trusted Firmware-M + +To add [TF-M](https://tf-m-user-guide.trustedfirmware.org) support to Matter +example you need to set `TFM_SUPPORT` variable inside main application +`CMakeLists.txt` file. + +``` +set(TFM_SUPPORT YES) +``` + +This causes the Matter example to be built as non-secure application in +Non-secure Processing Environment (`NSPE`). The bootloader and the secure part +are also built from `TF-M` sources. All components are merged into a single +executable file at the end of the building process. + +You can also provide the own version of Matter example by setting +`TFM_NS_APP_VERSION` variable. + +``` +set(TFM_NS_APP_VERSION "0.0.1") +``` + +### Trusted Firmware-M Protected Storage + +There is an option to add +[TF-M Protected Storage Service](https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_ps_integration_guide.html) +support for `key-value` storage component in Matter examples. You need to set +`CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS` variable inside main application +`CMakeLists.txt` fi + +``` +set(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS YES) +``` + +This option causes `key-value` objects will be stored in a secure part of flash +memory and the Protected Storage Service takes care of their encryption and +authentication. + +**NOTE** + +The `TF-M Protected Storage` option requires enabling +[TF-M](#trusted-firmware-m) support. + ## Building You build using a vscode task or call the script directly from the command line. diff --git a/docs/guides/openiotsdk_platform_overview.md b/docs/guides/openiotsdk_platform_overview.md index 2c4d04754dcc4a..211cd1af852179 100644 --- a/docs/guides/openiotsdk_platform_overview.md +++ b/docs/guides/openiotsdk_platform_overview.md @@ -93,3 +93,23 @@ This becomes the lower bound for timers. Drivers are provided by [Reference MCU-Driver-HAL driver implementation for Arm platforms](https://gitlab.arm.com/iot/open-iot-sdk/mcu-driver-hal/mcu-driver-reference-platforms-for-arm) which is provided by Open IoT SDK. + +## Trusted Firmware-M + +[Trusted Firmware-M](https://tf-m-user-guide.trustedfirmware.org) (`TF-M`) +implements the Secure Processing Environment (`SPE`) for `Armv8-M`, `Armv8.1-M` +architectures and dual-core platforms. It is the platform security architecture +reference implementation aligning with `PSA` Certified guidelines, enabling +chips, Real Time Operating Systems and devices to become `PSA` Certified. `TF-M` +relies on an isolation boundary between the Non-secure Processing Environment +(`NSPE`) and the Secure Processing Environment (`SPE`). + +`TF-M` consists of: + +- Secure Boot to authenticate `NSPE` and `SPE` images + +- `TF-M Core` for controlling the isolation, communication and execution + within `SPE` and with `NSPE` + +- Crypto, Internal Trusted Storage (`ITS`), Protected Storage (`PS`), Firmware + Update and Attestation secure services diff --git a/examples/lock-app/openiotsdk/CMakeLists.txt b/examples/lock-app/openiotsdk/CMakeLists.txt index 1e0125b99c0497..ec75b81afdf3d2 100644 --- a/examples/lock-app/openiotsdk/CMakeLists.txt +++ b/examples/lock-app/openiotsdk/CMakeLists.txt @@ -19,11 +19,15 @@ cmake_minimum_required(VERSION 3.21) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(OPEN_IOT_SDK_CONFIG ${CHIP_ROOT}/config/openiotsdk REALPATH) get_filename_component(OPEN_IOT_SDK_EXAMPLE_COMMON ${CHIP_ROOT}/examples/platform/openiotsdk REALPATH) -get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) -set(APP_TARGET chip-openiotsdk-lock-app-example) +set(APP_TARGET chip-openiotsdk-lock-app-example_ns) + +set(TFM_SUPPORT YES) +set(TFM_PROJECT_CONFIG_HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/tf-m-config/TfmProjectConfig.h") +set(TFM_NS_APP_VERSION "0.0.1") +set(CONFIG_CHIP_OPEN_IOT_SDK_USE_PSA_PS YES) # Toolchain files need to exist before first call to project include(toolchain) @@ -55,16 +59,16 @@ include(chip) add_subdirectory(${OPEN_IOT_SDK_EXAMPLE_COMMON}/app ./app_build) -target_include_directories(${APP_TARGET} +chip_add_data_model(openiotsdk-app PUBLIC lock) + +target_include_directories(${APP_TARGET} PRIVATE main/include - ${GEN_DIR}/app-common - ${GEN_DIR}/lock-app ) -target_sources(${APP_TARGET} +target_sources(${APP_TARGET} PRIVATE - main/main.cpp + main/main_ns.cpp main/ZclCallbacks.cpp main/LockManager.cpp main/LockEndpoint.cpp @@ -74,11 +78,7 @@ target_link_libraries(${APP_TARGET} openiotsdk-app ) -include(${CHIP_ROOT}/src/app/chip_data_model.cmake) -chip_configure_data_model(${APP_TARGET} - INCLUDE_SERVER - ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lock-common/lock-app.zap -) - include(linker) set_target_link(${APP_TARGET}) + +sdk_post_build(${APP_TARGET}) diff --git a/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h b/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h index 3921500daecafb..e86df2b4e44e06 100644 --- a/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h +++ b/examples/lock-app/openiotsdk/cmsis-config/RTE_Components.h @@ -19,6 +19,4 @@ #ifndef RTE_COMPONENTS_H #define RTE_COMPONENTS_H -#define OS_STACK_SIZE (4 * 1024) - #endif // RTE_COMPONENTS_H diff --git a/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h index c95af61db3c84d..bfcd8f09e9b4aa 100644 --- a/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h +++ b/examples/lock-app/openiotsdk/freertos-config/FreeRTOSConfig.h @@ -190,7 +190,7 @@ extern uint32_t SystemCoreClock; // Use TrustZone Secure Side Only // This settings prevents FreeRTOS contex switch to Non-Secure side. // Enable this setting when FreeRTOS runs on the Secure side only. -#define configRUN_FREERTOS_SECURE_ONLY 1 +#define configRUN_FREERTOS_SECURE_ONLY CONFIG_RUN_FREERTOS_SECURE_ONLY // Use TrustZone Security Extension // Using TrustZone affects context handling. diff --git a/examples/lock-app/openiotsdk/main/main.cpp b/examples/lock-app/openiotsdk/main/main_ns.cpp similarity index 63% rename from examples/lock-app/openiotsdk/main/main.cpp rename to examples/lock-app/openiotsdk/main/main_ns.cpp index fbd72e0542fc85..2b6484b05180c2 100644 --- a/examples/lock-app/openiotsdk/main/main.cpp +++ b/examples/lock-app/openiotsdk/main/main_ns.cpp @@ -18,48 +18,23 @@ #include #include -#include #include -#include - -#include -#include -#include -#include #include "openiotsdk_platform.h" -using namespace ::chip; -using namespace ::chip::DeviceLayer; - static void app_thread(void * argument) { - CHIP_ERROR error; - if (openiotsdk_network_init(true)) { ChipLogError(NotSpecified, "Network initialization failed"); goto exit; } - // Init ZCL Data Model and start server - static chip::CommonCaseDeviceServerInitParams initParams; - (void) initParams.InitializeStaticResourcesBeforeServerInit(); - initParams.operationalServicePort = CHIP_PORT; - initParams.userDirectedCommissioningPort = CHIP_UDC_PORT; - - error = Server::GetInstance().Init(initParams); - SuccessOrExit(error); - - // Now that the server has started and we are done with our startup logging, - // log our discovery/onboarding information again so it's not lost in the - // noise. - ConfigurationMgr().LogDeviceConfig(); - - PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kOnNetwork)); - - // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Credentials::Examples::GetExampleDACProvider()); + if (openiotsdk_chip_run()) + { + ChipLogError(NotSpecified, "CHIP stack run failed"); + goto exit; + } ChipLogProgress(NotSpecified, "Open IoT SDK lock-app example application run"); @@ -69,7 +44,7 @@ static void app_thread(void * argument) osDelay(osWaitForever); } - Server::GetInstance().Shutdown(); + openiotsdk_chip_shutdown(); exit: osThreadTerminate(osThreadGetId()); diff --git a/examples/lock-app/openiotsdk/tf-m-config/TfmProjectConfig.h b/examples/lock-app/openiotsdk/tf-m-config/TfmProjectConfig.h new file mode 100644 index 00000000000000..a792f400bd2660 --- /dev/null +++ b/examples/lock-app/openiotsdk/tf-m-config/TfmProjectConfig.h @@ -0,0 +1,165 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * 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 TFM_PROJECT_CONFIG_H +#define TFM_PROJECT_CONFIG_H + +/* Platform Partition Configs */ + +/* Size of input buffer in platform service */ +#define PLATFORM_SERVICE_INPUT_BUFFER_SIZE 64 + +/* Size of output buffer in platform service */ +#define PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE 64 + +/* The stack size of the Platform Secure Partition */ +#define PLATFORM_SP_STACK_SIZE 0x500 + +/* Disable Non-volatile counter module */ +#define PLATFORM_NV_COUNTER_MODULE_DISABLED 0 + +/* Crypto Partition Configs */ + +/* + * Heap size for the crypto backend + * CRYPTO_ENGINE_BUF_SIZE needs to be >8KB for EC signing by attest module. + */ +#define CRYPTO_ENGINE_BUF_SIZE 0x2080 + +/* The max number of concurrent operations that can be active (allocated) at any time in Crypto */ +#define CRYPTO_CONC_OPER_NUM 8 + +/* Enable PSA Crypto random number generator module */ +#define CRYPTO_RNG_MODULE_ENABLED 1 + +/* Enable PSA Crypto Key module */ +#define CRYPTO_KEY_MODULE_ENABLED 1 + +/* Enable PSA Crypto AEAD module */ +#define CRYPTO_AEAD_MODULE_ENABLED 1 + +/* Enable PSA Crypto MAC module */ +#define CRYPTO_MAC_MODULE_ENABLED 1 + +/* Enable PSA Crypto Hash module */ +#define CRYPTO_HASH_MODULE_ENABLED 1 + +/* Enable PSA Crypto Cipher module */ +#define CRYPTO_CIPHER_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key signature module */ +#define CRYPTO_ASYM_SIGN_MODULE_ENABLED 1 + +/* Enable PSA Crypto asymmetric key encryption module */ +#define CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED 0 + +/* Enable PSA Crypto key derivation module */ +#define CRYPTO_KEY_DERIVATION_MODULE_ENABLED 1 + +/* Default size of the internal scratch buffer used for PSA FF IOVec allocations */ +#define CRYPTO_IOVEC_BUFFER_SIZE 5120 + +/* Use stored NV seed to provide entropy */ +#define CRYPTO_NV_SEED 1 + +/* + * Only enable multi-part operations in Hash, MAC, AEAD and symmetric ciphers, + * to optimize memory footprint in resource-constrained devices. + */ +#define CRYPTO_SINGLE_PART_FUNCS_DISABLED 0 + +/* The stack size of the Crypto Secure Partition */ +#define CRYPTO_STACK_SIZE 0x1B00 + +/* FWU Partition Configs */ + +/* Size of the FWU internal data transfer buffer */ +#define TFM_FWU_BUF_SIZE PSA_FWU_MAX_WRITE_SIZE + +/* The stack size of the Firmware Update Secure Partition */ +#define FWU_STACK_SIZE 0x600 + +/* Attest Partition Configs */ + +/* Include optional claims in initial attestation token */ +#define ATTEST_INCLUDE_OPTIONAL_CLAIMS 1 + +/* Include COSE key-id in initial attestation token */ +#define ATTEST_INCLUDE_COSE_KEY_ID 0 + +/* The stack size of the Initial Attestation Secure Partition */ +#define ATTEST_STACK_SIZE 0x700 + +/* Set the initial attestation token profile */ +#define ATTEST_TOKEN_PROFILE_PSA_IOT_1 1 + +/* ITS Partition Configs */ + +/* Create flash FS if it doesn't exist for Internal Trusted Storage partition */ +#define ITS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Internal Trusted Storage partition */ +#define ITS_RAM_FS 0 + +/* Validate filesystem metadata every time it is read from flash */ +#define ITS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Internal Trusted Storage */ +#define ITS_MAX_ASSET_SIZE 512 + +/* Size of the ITS internal data transfer buffer */ +#define ITS_BUF_SIZE 32 + +/* The maximum number of assets to be stored in the Internal Trusted Storage */ +#define ITS_NUM_ASSETS 10 + +/* The stack size of the Internal Trusted Storage Secure Partition */ +#define ITS_STACK_SIZE 0x720 + +/* PS Partition Configs */ + +/* Create flash FS if it doesn't exist for Protected Storage partition */ +#define PS_CREATE_FLASH_LAYOUT 1 + +/* Enable emulated RAM FS for platforms that don't have flash for Protected Storage partition */ +#define PS_RAM_FS 0 + +/* Enable rollback protection for Protected Storage partition */ +#define PS_ROLLBACK_PROTECTION 1 + +/* Validate filesystem metadata every time it is read from flash */ +#define PS_VALIDATE_METADATA_FROM_FLASH 1 + +/* The maximum asset size to be stored in the Protected Storage */ +#define PS_MAX_ASSET_SIZE 2048 + +/* The maximum number of assets to be stored in the Protected Storage */ +#define PS_NUM_ASSETS 30 + +/* The stack size of the Protected Storage Secure Partition */ +#define PS_STACK_SIZE 0x700 + +/* SPM Partition Configs */ + +/* The maximal number of secure services that are connected or requested at the same time */ +#define CONFIG_TFM_CONN_HANDLE_MAX_NUM 8 + +/* Enable the doorbell APIs */ +#define CONFIG_TFM_DOORBELL_API 1 + +#endif /* TFM_PROJECT_CONFIG_H */ diff --git a/examples/platform/openiotsdk/app/CMakeLists.txt b/examples/platform/openiotsdk/app/CMakeLists.txt index 191409ac8c815c..0a37f4d2b495a5 100644 --- a/examples/platform/openiotsdk/app/CMakeLists.txt +++ b/examples/platform/openiotsdk/app/CMakeLists.txt @@ -31,5 +31,12 @@ target_include_directories(openiotsdk-app target_link_libraries(openiotsdk-app PUBLIC openiotsdk-chip - cmsis-rtos-implementation + $ ) + +if(TFM_SUPPORT) + target_compile_definitions(openiotsdk-app + PUBLIC + TFM_SUPPORT + ) +endif() diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp index 18ca62d06b4ac2..829980d31f2392 100644 --- a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp @@ -29,16 +29,33 @@ #include "mbedtls/platform.h" #include -#include #include #include -#include #include +#include +#include + +#ifdef USE_CHIP_DATA_MODEL +#include +#include +#include +#include +#include +#endif // USE_CHIP_DATA_MODEL + +#ifdef TFM_SUPPORT +#include "psa/fwu_config.h" +#include "psa/update.h" +#include "tfm_ns_interface.h" +#endif // TFM_SUPPORT + using namespace ::chip; using namespace ::chip::Platform; using namespace ::chip::DeviceLayer; +constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; + #define NETWORK_UP_FLAG 0x00000001U #define NETWORK_DOWN_FLAG 0x00000002U #define ALL_EVENTS_FLAGS (NETWORK_UP_FLAG | NETWORK_DOWN_FLAG) @@ -49,6 +66,13 @@ static osEventFlagsId_t event_flags_id; static DeviceLayer::DeviceInfoProviderImpl gDeviceInfoProvider; +#ifdef TFM_SUPPORT +extern "C" { +// RTOS-specific initialization that is not declared in any header file +uint32_t tfm_ns_interface_init(void); +} +#endif // TFM_SUPPORT + /** Wait for specific event and check error */ static int wait_for_event(uint32_t event) { @@ -111,6 +135,36 @@ static void network_state_callback(network_state_callback_event_t event) } } +#ifdef TFM_SUPPORT +static int get_psa_images_details() +{ + psa_status_t status; + psa_fwu_component_info_t image_info; + + status = psa_fwu_query(FWU_COMPONENT_ID_SECURE, &image_info); + if (status != PSA_SUCCESS) + { + ChipLogError(NotSpecified, "Failed to query secure firmware information. Error %ld", status); + return EXIT_FAILURE; + } + + ChipLogProgress(NotSpecified, "Secure firmware version: %u.%u.%u-%lu\r\n", image_info.version.major, image_info.version.minor, + image_info.version.patch, image_info.version.build); + + status = psa_fwu_query(FWU_COMPONENT_ID_NONSECURE, &image_info); + if (status != PSA_SUCCESS) + { + ChipLogError(NotSpecified, "Failed to query non-secure firmware information. Error %ld", status); + return EXIT_FAILURE; + } + + ChipLogProgress(NotSpecified, "Non-secure firmware version: %u.%u.%u-%lu\r\n", image_info.version.major, + image_info.version.minor, image_info.version.patch, image_info.version.build); + + return EXIT_SUCCESS; +} +#endif // TFM_SUPPORT + int openiotsdk_platform_init(void) { int ret; @@ -123,6 +177,22 @@ int openiotsdk_platform_init(void) return EXIT_FAILURE; } +#ifdef TFM_SUPPORT + ret = tfm_ns_interface_init(); + if (ret != 0) + { + ChipLogError(NotSpecified, "TF-M initialization failed: %d", ret); + return EXIT_FAILURE; + } + + ret = get_psa_images_details(); + if (ret != 0) + { + ChipLogError(NotSpecified, "Get PSA image details failed: %d", ret); + return EXIT_FAILURE; + } +#endif // TFM_SUPPORT + ret = osKernelInitialize(); if (ret != osOK) { @@ -216,3 +286,50 @@ int openiotsdk_network_init(bool wait) return EXIT_SUCCESS; } + +int openiotsdk_chip_run(void) +{ + CHIP_ERROR err; + +#ifdef USE_CHIP_DATA_MODEL + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + err = initParams.InitializeStaticResourcesBeforeServerInit(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Initialize static resources before server init failed: %s", err.AsString()); + return EXIT_FAILURE; + } + initParams.operationalServicePort = CHIP_PORT; + initParams.userDirectedCommissioningPort = CHIP_UDC_PORT; + + err = Server::GetInstance().Init(initParams); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Initialize server failed: %s", err.AsString()); + return EXIT_FAILURE; + } + + // Now that the server has started and we are done with our startup logging, + // log our discovery/onboarding information again so it's not lost in the + // noise. + ConfigurationMgr().LogDeviceConfig(); + + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kOnNetwork)); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Credentials::Examples::GetExampleDACProvider()); + + // We only have network commissioning on endpoint 0. + emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); +#endif // USE_CHIP_DATA_MODEL + + return EXIT_SUCCESS; +} + +void openiotsdk_chip_shutdown() +{ +#ifdef USE_CHIP_DATA_MODEL + Server::GetInstance().Shutdown(); +#endif // USE_CHIP_DATA_MODEL +} diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.h b/examples/platform/openiotsdk/app/openiotsdk_platform.h index 5dee7b82c7049d..cba0e48e724218 100644 --- a/examples/platform/openiotsdk/app/openiotsdk_platform.h +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.h @@ -66,4 +66,18 @@ int openiotsdk_platform_run(void); */ int openiotsdk_network_init(bool wait); +/** + * @brief Run the CHIP sources/components + * Initialize ZCL Data Model and start server + * + * @return EXIT_SUCCESS or EXIT_FAILURE + */ +int openiotsdk_chip_run(void); + +/** + * @brief Shutdown the CHIP sources/components + * Stop chip server + */ +void openiotsdk_chip_shutdown(void); + #endif /* ! OPENIOTSDK_PLATFORM_H */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/CMakeLists.txt b/examples/platform/openiotsdk/tf-m/targets/an552/CMakeLists.txt new file mode 100755 index 00000000000000..427591f64c2d08 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/CMakeLists.txt @@ -0,0 +1,204 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020-2022, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +#========================= Platform region defs ===============================# + +target_include_directories(platform_region_defs + INTERFACE + partition +) + +#========================= Platform common defs ===============================# + +if (${CMAKE_C_COMPILER_ID} STREQUAL ARMClang) + if (${CMAKE_C_COMPILER_VERSION} VERSION_LESS "6.14") + message(FATAL_ERROR "CPU (Cortex-M55) is only supported in ARMCLANG version 6.14 or newer.") + endif() +endif() + +# Specify the location of platform specific build dependencies. +target_sources(tfm_s + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_an552.c +) +target_add_scatter_file(tfm_s + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/armclang/tfm_common_s.sct> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/gcc/tfm_common_s.ld> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/iar/tfm_common_s.icf> +) + +if(NS) + target_sources(tfm_ns + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_an552.c + ) + target_add_scatter_file(tfm_ns + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/armclang/tfm_common_ns.sct> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/gcc/tfm_common_ns.ld> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/iar/tfm_common_ns.icf> + ) + target_link_libraries(CMSIS_5_tfm_ns + INTERFACE + $<$:CMSIS_5_RTX_V8MMN> + $<$,$,$>>:CMSIS_5_RTX_V8MMFN> + $<$,$,$>>>:CMSIS_5_RTX_V8MMN> + $<$:CMSIS_5_RTX_V81MMN> + ) + target_compile_options(tfm_ns + PUBLIC + ${COMPILER_CP_FLAG} + ) + target_link_options(tfm_ns + PUBLIC + ${LINKER_CP_OPTION} + ) +endif() + +if(BL2) + target_sources(bl2 + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/device/source/startup_an552.c + ) + target_add_scatter_file(bl2 + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/armclang/tfm_common_bl2.sct> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/gcc/tfm_common_bl2.ld> + $<$:${CMAKE_SOURCE_DIR}/platform/ext/common/iar/tfm_common_bl2.icf> + ) +endif() + +#========================= Platform Secure ====================================# + +target_include_directories(platform_s + PUBLIC + . + ../common + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + services/src + ${PLATFORM_DIR}/.. +) + +target_sources(platform_s + PRIVATE + cmsis_drivers/Driver_Flash.c + cmsis_drivers/Driver_AN552_MPC.c + cmsis_drivers/Driver_SSE300_PPC.c + cmsis_drivers/Driver_USART.c + device/source/device_definition.c + device/source/system_core_init.c + native_drivers/mpc_sie_drv.c + native_drivers/mpu_armv8m_drv.c + native_drivers/ppc_sse300_drv.c + native_drivers/emulated_flash_drv.c + native_drivers/syscounter_armv8-m_cntrl_drv.c + native_drivers/uart_cmsdk_drv.c + tfm_peripherals_def.c + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c> +) + +target_sources(tfm_sprt + PRIVATE + # SLIH test Partition and FLIH test Partition access the timer as ARoT Partitions. + # Put the driver to SPRT so that both SLIH and FLIH tests can access it. + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/systimer_armv8-m_drv.c> +) + +target_compile_options(platform_s + PUBLIC + ${COMPILER_CMSE_FLAG} +) + +# To configure S and NS timer in S side for FP interrupt test +target_compile_definitions(platform_s + PUBLIC + $<$:TEST_NS_FPU> + $<$:TEST_S_FPU> +) + +#========================= Platform Non-Secure ================================# + +target_sources(platform_ns + PRIVATE + cmsis_drivers/Driver_Flash.c + cmsis_drivers/Driver_USART.c + device/source/device_definition.c + device/source/system_core_init.c + native_drivers/uart_cmsdk_drv.c + native_drivers/systimer_armv8-m_drv.c + INTERFACE + $<$:${CMAKE_CURRENT_SOURCE_DIR}/device/source/an552_ns_init.c> +) + +target_include_directories(platform_ns + PUBLIC + . + ../common + ${PLATFORM_DIR}/.. + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + ${CMAKE_SOURCE_DIR}/platform/ext/cmsis +) + +#========================= Platform BL2 =======================================# + +if(BL2) + target_sources(platform_bl2 + PRIVATE + cmsis_drivers/Driver_Flash.c + cmsis_drivers/Driver_USART.c + device/source/device_definition.c + device/source/system_core_init.c + native_drivers/uart_cmsdk_drv.c + native_drivers/emulated_flash_drv.c + boot_hal_bl2.c + ) + + target_include_directories(platform_bl2 + PUBLIC + cmsis_drivers + cmsis_drivers/config + device + device/config + device/include + device/source/armclang + native_drivers + partition + services/src + + PRIVATE + . + ${PLATFORM_DIR}/.. + native_drivers + ) +endif() + +#========================= tfm_spm ============================================# + +target_sources(tfm_spm + PRIVATE + target_cfg.c + tfm_hal_isolation.c + tfm_hal_platform.c + faults.c + ${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c +) diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/boot_hal_bl2.c b/examples/platform/openiotsdk/tf-m/targets/an552/boot_hal_bl2.c new file mode 100644 index 00000000000000..4760882ee47de7 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/boot_hal_bl2.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "Driver_Flash.h" +#include "boot_hal.h" +#include "cmsis.h" +#include "flash_layout.h" +#include "region.h" +#include "target_cfg.h" + +/* Flash device name must be specified by target */ +extern ARM_DRIVER_FLASH FLASH_DEV_NAME_0; + +REGION_DECLARE(Image$$, ER_DATA, $$Base)[]; +REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[]; +REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base); + +int flash_device_base(uint8_t fd_id, uintptr_t * ret) +{ + if (fd_id == FLASH_DEVICE_ID_0) + { + *ret = FLASH0_BASE_ADDRESS; + } + else if (fd_id == FLASH_DEVICE_ID_1) + { + *ret = FLASH0_BASE_ADDRESS; + } + else if (fd_id == FLASH_DEVICE_ID_SCRATCH) + { + *ret = FLASH0_BASE_ADDRESS; + } + else + { + return -1; + } + + return 0; +} + +int32_t boot_platform_init(void) +{ + int32_t result; + + /* Initialize stack limit register */ + uint32_t msp_stack_bottom = (uint32_t) ®ION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base); + + __set_MSPLIM(msp_stack_bottom); + + result = FLASH_DEV_NAME_0.Initialize(NULL); + if (result != ARM_DRIVER_OK) + { + return 1; + } + + return 0; +} + +void boot_platform_quit(struct boot_arm_vector_table * vt) +{ + /* Clang at O0, stores variables on the stack with SP relative addressing. + * When manually set the SP then the place of reset vector is lost. + * Static variables are stored in 'data' or 'bss' section, change of SP has + * no effect on them. + */ + static struct boot_arm_vector_table * vt_cpy; + int32_t result; + + result = FLASH_DEV_NAME_0.Uninitialize(); + if (result != ARM_DRIVER_OK) + { + while (1) + ; + } + + vt_cpy = vt; + + __set_MSPLIM(0); + __set_MSP(vt->msp); + __DSB(); + __ISB(); + + boot_jump_to_next_image(vt_cpy->reset); +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_AN552_MPC.c b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_AN552_MPC.c new file mode 100755 index 00000000000000..dee2a498973990 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_AN552_MPC.c @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2016-2022 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 "RTE_Device.h" +#include "cmsis_driver_config.h" +#include "mpc_sie_drv.h" + +/* Driver version */ +#define ARM_MPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) + +#if (defined(RTE_SRAM_MPC) && (RTE_SRAM_MPC == 1)) || (defined(RTE_ISRAM0_MPC) && (RTE_ISRAM0_MPC == 1)) || \ + (defined(RTE_ISRAM1_MPC) && (RTE_ISRAM1_MPC == 1)) || (defined(RTE_QSPI_MPC) && (RTE_QSPI_MPC == 1)) || \ + (defined(RTE_DDR4_MPC) && (RTE_DDR4_MPC == 1)) + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { ARM_MPC_API_VERSION, ARM_MPC_DRV_VERSION }; + +static ARM_DRIVER_VERSION ARM_MPC_GetVersion(void) +{ + return DriverVersion; +} + +/* + * \brief Translates error codes from native API to CMSIS API. + * + * \param[in] err Error code to translate (\ref mpc_sie_error_t). + * + * \return Returns CMSIS error code. + */ +static int32_t error_trans(enum mpc_sie_error_t err) +{ + switch (err) + { + case MPC_SIE_ERR_NONE: + return ARM_DRIVER_OK; + case MPC_SIE_INVALID_ARG: + return ARM_DRIVER_ERROR_PARAMETER; + case MPC_SIE_NOT_INIT: + return ARM_MPC_ERR_NOT_INIT; + case MPC_SIE_ERR_NOT_IN_RANGE: + return ARM_MPC_ERR_NOT_IN_RANGE; + case MPC_SIE_ERR_NOT_ALIGNED: + return ARM_MPC_ERR_NOT_ALIGNED; + case MPC_SIE_ERR_INVALID_RANGE: + return ARM_MPC_ERR_INVALID_RANGE; + case MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE: + return ARM_MPC_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE; + case MPC_SIE_UNSUPPORTED_HARDWARE_VERSION: + case MPC_SIE_ERR_GATING_NOT_PRESENT: + default: + return ARM_MPC_ERR_UNSPECIFIED; + } +} + +#if (defined(RTE_SRAM_MPC) && (RTE_SRAM_MPC == 1)) +/* Ranges controlled by this SRAM_MPC */ +static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_S = { + .base = MPC_SRAM_RANGE_BASE_S, .limit = MPC_SRAM_RANGE_LIMIT_S, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_SRAM_RANGE_NS = { + .base = MPC_SRAM_RANGE_BASE_NS, .limit = MPC_SRAM_RANGE_LIMIT_NS, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_SRAM_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t * MPC_SRAM_RANGE_LIST[MPC_SRAM_RANGE_LIST_LEN] = { &MPC_SRAM_RANGE_S, + &MPC_SRAM_RANGE_NS }; + +/* SRAM_MPC Driver wrapper functions */ +static int32_t SRAM_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_SRAM_DEV, MPC_SRAM_RANGE_LIST, MPC_SRAM_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t SRAM_MPC_GetBlockSize(uint32_t * blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_SRAM_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_GetCtrlConfig(uint32_t * ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_SRAM_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_SRAM_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_GetRegionConfig(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR * attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_SRAM_DEV, base, limit, (enum mpc_sie_sec_attr_t *) attr); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_ConfigRegion(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_SRAM_DEV, base, limit, (enum mpc_sie_sec_attr_t) attr); + + return error_trans(ret); +} + +static int32_t SRAM_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_SRAM_DEV); + + return error_trans(ret); +} + +static void SRAM_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_SRAM_DEV); +} + +static void SRAM_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_SRAM_DEV); +} + +static uint32_t SRAM_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_SRAM_DEV); +} + +static int32_t SRAM_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_SRAM_DEV); +} + +/* SRAM_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_SRAM_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = SRAM_MPC_Initialize, + .Uninitialize = SRAM_MPC_Uninitialize, + .GetBlockSize = SRAM_MPC_GetBlockSize, + .GetCtrlConfig = SRAM_MPC_GetCtrlConfig, + .SetCtrlConfig = SRAM_MPC_SetCtrlConfig, + .ConfigRegion = SRAM_MPC_ConfigRegion, + .GetRegionConfig = SRAM_MPC_GetRegionConfig, + .EnableInterrupt = SRAM_MPC_EnableInterrupt, + .DisableInterrupt = SRAM_MPC_DisableInterrupt, + .ClearInterrupt = SRAM_MPC_ClearInterrupt, + .InterruptState = SRAM_MPC_InterruptState, + .LockDown = SRAM_MPC_LockDown, +}; +#endif /* RTE_SRAM_MPC */ + +#if (defined(RTE_ISRAM0_MPC) && (RTE_ISRAM0_MPC == 1)) +/* Ranges controlled by this ISRAM0_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_S = { + .base = MPC_ISRAM0_RANGE_BASE_S, .limit = MPC_ISRAM0_RANGE_LIMIT_S, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM0_RANGE_NS = { + .base = MPC_ISRAM0_RANGE_BASE_NS, .limit = MPC_ISRAM0_RANGE_LIMIT_NS, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM0_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t * MPC_ISRAM0_RANGE_LIST[MPC_ISRAM0_RANGE_LIST_LEN] = { &MPC_ISRAM0_RANGE_S, + &MPC_ISRAM0_RANGE_NS }; + +/* ISRAM0_MPC Driver wrapper functions */ +static int32_t ISRAM0_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM0_DEV, MPC_ISRAM0_RANGE_LIST, MPC_ISRAM0_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM0_MPC_GetBlockSize(uint32_t * blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM0_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_GetCtrlConfig(uint32_t * ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM0_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM0_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_GetRegionConfig(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR * attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_ISRAM0_DEV, base, limit, (enum mpc_sie_sec_attr_t *) attr); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_ConfigRegion(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_ISRAM0_DEV, base, limit, (enum mpc_sie_sec_attr_t) attr); + + return error_trans(ret); +} + +static int32_t ISRAM0_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM0_DEV); + + return error_trans(ret); +} + +static void ISRAM0_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM0_DEV); +} + +static void ISRAM0_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM0_DEV); +} + +static uint32_t ISRAM0_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM0_DEV); +} + +static int32_t ISRAM0_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM0_DEV); +} + +/* ISRAM0_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM0_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM0_MPC_Initialize, + .Uninitialize = ISRAM0_MPC_Uninitialize, + .GetBlockSize = ISRAM0_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM0_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM0_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM0_MPC_ConfigRegion, + .GetRegionConfig = ISRAM0_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM0_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM0_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM0_MPC_ClearInterrupt, + .InterruptState = ISRAM0_MPC_InterruptState, + .LockDown = ISRAM0_MPC_LockDown, +}; +#endif /* RTE_ISRAM0_MPC */ + +#if (defined(RTE_ISRAM1_MPC) && (RTE_ISRAM1_MPC == 1)) +/* Ranges controlled by this ISRAM1_MPC */ +static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_S = { + .base = MPC_ISRAM1_RANGE_BASE_S, .limit = MPC_ISRAM1_RANGE_LIMIT_S, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_ISRAM1_RANGE_NS = { + .base = MPC_ISRAM1_RANGE_BASE_NS, .limit = MPC_ISRAM1_RANGE_LIMIT_NS, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_ISRAM1_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t * MPC_ISRAM1_RANGE_LIST[MPC_ISRAM1_RANGE_LIST_LEN] = { &MPC_ISRAM1_RANGE_S, + &MPC_ISRAM1_RANGE_NS }; + +/* ISRAM1_MPC Driver wrapper functions */ +static int32_t ISRAM1_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_ISRAM1_DEV, MPC_ISRAM1_RANGE_LIST, MPC_ISRAM1_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t ISRAM1_MPC_GetBlockSize(uint32_t * blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_ISRAM1_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_GetCtrlConfig(uint32_t * ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_ISRAM1_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_ISRAM1_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_GetRegionConfig(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR * attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_ISRAM1_DEV, base, limit, (enum mpc_sie_sec_attr_t *) attr); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_ConfigRegion(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_ISRAM1_DEV, base, limit, (enum mpc_sie_sec_attr_t) attr); + + return error_trans(ret); +} + +static int32_t ISRAM1_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_ISRAM1_DEV); + + return error_trans(ret); +} + +static void ISRAM1_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_ISRAM1_DEV); +} + +static void ISRAM1_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_ISRAM1_DEV); +} + +static uint32_t ISRAM1_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_ISRAM1_DEV); +} + +static int32_t ISRAM1_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_ISRAM1_DEV); +} + +/* ISRAM1_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_ISRAM1_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = ISRAM1_MPC_Initialize, + .Uninitialize = ISRAM1_MPC_Uninitialize, + .GetBlockSize = ISRAM1_MPC_GetBlockSize, + .GetCtrlConfig = ISRAM1_MPC_GetCtrlConfig, + .SetCtrlConfig = ISRAM1_MPC_SetCtrlConfig, + .ConfigRegion = ISRAM1_MPC_ConfigRegion, + .GetRegionConfig = ISRAM1_MPC_GetRegionConfig, + .EnableInterrupt = ISRAM1_MPC_EnableInterrupt, + .DisableInterrupt = ISRAM1_MPC_DisableInterrupt, + .ClearInterrupt = ISRAM1_MPC_ClearInterrupt, + .InterruptState = ISRAM1_MPC_InterruptState, + .LockDown = ISRAM1_MPC_LockDown, +}; +#endif /* RTE_ISRAM1_MPC */ + +#if (defined(RTE_QSPI_MPC) && (RTE_QSPI_MPC == 1)) +/* Ranges controlled by this QSPI_MPC */ +static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_S = { + .base = MPC_QSPI_RANGE_BASE_S, .limit = MPC_QSPI_RANGE_LIMIT_S, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_QSPI_RANGE_NS = { + .base = MPC_QSPI_RANGE_BASE_NS, .limit = MPC_QSPI_RANGE_LIMIT_NS, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_QSPI_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t * MPC_QSPI_RANGE_LIST[MPC_QSPI_RANGE_LIST_LEN] = { &MPC_QSPI_RANGE_S, + &MPC_QSPI_RANGE_NS }; + +/* QSPI_MPC Driver wrapper functions */ +static int32_t QSPI_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_QSPI_DEV, MPC_QSPI_RANGE_LIST, MPC_QSPI_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t QSPI_MPC_GetBlockSize(uint32_t * blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_QSPI_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_GetCtrlConfig(uint32_t * ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_QSPI_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_QSPI_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_GetRegionConfig(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR * attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_QSPI_DEV, base, limit, (enum mpc_sie_sec_attr_t *) attr); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_ConfigRegion(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_QSPI_DEV, base, limit, (enum mpc_sie_sec_attr_t) attr); + + return error_trans(ret); +} + +static int32_t QSPI_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_QSPI_DEV); + + return error_trans(ret); +} + +static void QSPI_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_QSPI_DEV); +} + +static void QSPI_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_QSPI_DEV); +} + +static uint32_t QSPI_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_QSPI_DEV); +} + +static int32_t QSPI_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_QSPI_DEV); +} + +/* QSPI_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_QSPI_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = QSPI_MPC_Initialize, + .Uninitialize = QSPI_MPC_Uninitialize, + .GetBlockSize = QSPI_MPC_GetBlockSize, + .GetCtrlConfig = QSPI_MPC_GetCtrlConfig, + .SetCtrlConfig = QSPI_MPC_SetCtrlConfig, + .ConfigRegion = QSPI_MPC_ConfigRegion, + .GetRegionConfig = QSPI_MPC_GetRegionConfig, + .EnableInterrupt = QSPI_MPC_EnableInterrupt, + .DisableInterrupt = QSPI_MPC_DisableInterrupt, + .ClearInterrupt = QSPI_MPC_ClearInterrupt, + .InterruptState = QSPI_MPC_InterruptState, + .LockDown = QSPI_MPC_LockDown, +}; +#endif /* RTE_QSPI_MPC */ + +#if (defined(RTE_DDR4_MPC) && (RTE_DDR4_MPC == 1)) +/* Ranges controlled by this DDR4_MPC */ +static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_S = { + .base = MPC_DDR4_RANGE_BASE_S, .limit = MPC_DDR4_RANGE_LIMIT_S, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_SECURE +}; + +static const struct mpc_sie_memory_range_t MPC_DDR4_RANGE_NS = { + .base = MPC_DDR4_RANGE_BASE_NS, .limit = MPC_DDR4_RANGE_LIMIT_NS, .range_offset = 0, .attr = MPC_SIE_SEC_ATTR_NONSECURE +}; + +#define MPC_DDR4_RANGE_LIST_LEN 2u +static const struct mpc_sie_memory_range_t * MPC_DDR4_RANGE_LIST[MPC_DDR4_RANGE_LIST_LEN] = { &MPC_DDR4_RANGE_S, + &MPC_DDR4_RANGE_NS }; + +/* DDR4_MPC Driver wrapper functions */ +static int32_t DDR4_MPC_Initialize(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_init(&MPC_DDR4_DEV, MPC_DDR4_RANGE_LIST, MPC_DDR4_RANGE_LIST_LEN); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_Uninitialize(void) +{ + /* Nothing to be done */ + return ARM_DRIVER_OK; +} + +static int32_t DDR4_MPC_GetBlockSize(uint32_t * blk_size) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_block_size(&MPC_DDR4_DEV, blk_size); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_GetCtrlConfig(uint32_t * ctrl_val) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_ctrl(&MPC_DDR4_DEV, ctrl_val); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_SetCtrlConfig(uint32_t ctrl) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_set_ctrl(&MPC_DDR4_DEV, ctrl); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_GetRegionConfig(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR * attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_get_region_config(&MPC_DDR4_DEV, base, limit, (enum mpc_sie_sec_attr_t *) attr); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_ConfigRegion(uintptr_t base, uintptr_t limit, ARM_MPC_SEC_ATTR attr) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_config_region(&MPC_DDR4_DEV, base, limit, (enum mpc_sie_sec_attr_t) attr); + + return error_trans(ret); +} + +static int32_t DDR4_MPC_EnableInterrupt(void) +{ + enum mpc_sie_error_t ret; + + ret = mpc_sie_irq_enable(&MPC_DDR4_DEV); + + return error_trans(ret); +} + +static void DDR4_MPC_DisableInterrupt(void) +{ + mpc_sie_irq_disable(&MPC_DDR4_DEV); +} + +static void DDR4_MPC_ClearInterrupt(void) +{ + mpc_sie_clear_irq(&MPC_DDR4_DEV); +} + +static uint32_t DDR4_MPC_InterruptState(void) +{ + return mpc_sie_irq_state(&MPC_DDR4_DEV); +} + +static int32_t DDR4_MPC_LockDown(void) +{ + return mpc_sie_lock_down(&MPC_DDR4_DEV); +} + +/* DDR4_MPC Driver CMSIS access structure */ +ARM_DRIVER_MPC Driver_DDR4_MPC = { + .GetVersion = ARM_MPC_GetVersion, + .Initialize = DDR4_MPC_Initialize, + .Uninitialize = DDR4_MPC_Uninitialize, + .GetBlockSize = DDR4_MPC_GetBlockSize, + .GetCtrlConfig = DDR4_MPC_GetCtrlConfig, + .SetCtrlConfig = DDR4_MPC_SetCtrlConfig, + .ConfigRegion = DDR4_MPC_ConfigRegion, + .GetRegionConfig = DDR4_MPC_GetRegionConfig, + .EnableInterrupt = DDR4_MPC_EnableInterrupt, + .DisableInterrupt = DDR4_MPC_DisableInterrupt, + .ClearInterrupt = DDR4_MPC_ClearInterrupt, + .InterruptState = DDR4_MPC_InterruptState, + .LockDown = DDR4_MPC_LockDown, +}; +#endif /* RTE_DDR4_MPC */ +#endif diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_Flash.c b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_Flash.c new file mode 100755 index 00000000000000..0fca991f9cddeb --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_Flash.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2013-2022 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 "Driver_Flash.h" +#include "RTE_Device.h" +#include "emulated_flash_drv.h" +#include "platform_base_address.h" +#include +#include + +#ifndef ARG_UNUSED +#define ARG_UNUSED(arg) ((void) arg) +#endif + +#define FLASH0_BASE_S QSPI_SRAM_BASE_S +#define FLASH0_BASE_NS QSPI_SRAM_BASE_NS +#define FLASH0_SIZE QSPI_SRAM_SIZE +#define FLASH0_SECTOR_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PAGE_SIZE 0x00001000 /* 4 kB */ +#define FLASH0_PROGRAM_UNIT 0x1 /* Minimum write size */ + +/* Driver version */ +#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 1) + +/** + * Data width values for ARM_FLASH_CAPABILITIES::data_width + * \ref ARM_FLASH_CAPABILITIES + */ +enum +{ + DATA_WIDTH_8BIT = 0u, + DATA_WIDTH_16BIT, + DATA_WIDTH_32BIT, + DATA_WIDTH_ENUM_SIZE +}; + +static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = { + sizeof(uint8_t), + sizeof(uint16_t), + sizeof(uint32_t), +}; + +/* 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 */ + 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ + 1, /* erase_chip */ + 0 /* reserved */ +}; + +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); + + if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) + { + return ARM_DRIVER_ERROR; + } + + /* 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; + + case ARM_POWER_OFF: + case ARM_POWER_LOW: + default: + return ARM_DRIVER_ERROR_UNSUPPORTED; + } +} + +#if (RTE_FLASH0) + +/* Flash Status */ +static ARM_FLASH_STATUS FlashStatus_FLASH0 = { 0, 0, 0 }; + +static ARM_FLASH_INFO ARM_FLASH0_DEV_INFO = { .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 = EMULATED_FLASH_DRV_ERASE_VALUE }; + +static struct emulated_flash_dev_t ARM_FLASH0_DEV = { +#if (defined(__DOMAIN_NS) && (__DOMAIN_NS == 1)) + .memory_base_ns = FLASH0_BASE_NS, +#else + .memory_base_ns = FLASH0_BASE_NS, + .memory_base_s = FLASH0_BASE_S, +#endif /* __DOMAIN_NS == 1 */ + .data = &(ARM_FLASH0_DEV_INFO) +}; + +struct emulated_flash_dev_t * FLASH0_DEV = &ARM_FLASH0_DEV; + +/* + * Functions + */ + +static int32_t ARM_Flash_FLASH0_ReadData(uint32_t addr, void * data, uint32_t cnt) +{ + /* Conversion between data items and bytes */ + cnt *= data_width_byte[DriverCapabilities.data_width]; + + enum emulated_flash_error_t rc = emulated_flash_read_data(FLASH0_DEV, addr, data, cnt); + if (EMULATED_FLASH_ERR_NONE == rc) + { + cnt /= data_width_byte[DriverCapabilities.data_width]; + return cnt; + } + else if (EMULATED_FLASH_ERR_INVALID_PARAM == rc) + { + return ARM_DRIVER_ERROR_PARAMETER; + } + else + { + return ARM_DRIVER_ERROR; + } +} + +static int32_t ARM_Flash_FLASH0_ProgramData(uint32_t addr, const void * data, uint32_t cnt) +{ + /* Conversion between data items and bytes */ + cnt *= data_width_byte[DriverCapabilities.data_width]; + enum emulated_flash_error_t rc = emulated_flash_program_data(FLASH0_DEV, addr, data, cnt); + + if (EMULATED_FLASH_ERR_NONE == rc) + { + cnt /= data_width_byte[DriverCapabilities.data_width]; + return (int32_t) cnt; + } + else if (EMULATED_FLASH_ERR_INVALID_PARAM == rc) + { + return ARM_DRIVER_ERROR_PARAMETER; + } + else if (EMULATED_FLASH_NOT_READY == rc) + { + return ARM_DRIVER_ERROR; + } + else + { + return ARM_DRIVER_ERROR; + } +} + +static int32_t ARM_Flash_FLASH0_EraseSector(uint32_t addr) +{ + enum emulated_flash_error_t rc = emulated_flash_erase_sector(FLASH0_DEV, addr); + + if (EMULATED_FLASH_ERR_NONE == rc) + { + return ARM_DRIVER_OK; + } + else if (EMULATED_FLASH_ERR_INVALID_PARAM == rc) + { + return ARM_DRIVER_ERROR_PARAMETER; + } + else + { + return ARM_DRIVER_ERROR; + } +} + +static int32_t ARM_Flash_FLASH0_EraseChip(void) +{ + emulated_flash_erase_chip(FLASH0_DEV); + return ARM_DRIVER_OK; +} + +static ARM_FLASH_INFO * ARM_Flash_FLASH0_GetInfo(void) +{ + return &ARM_FLASH0_DEV_INFO; +} + +static ARM_FLASH_STATUS ARM_Flash_FLASH0_GetStatus(void) +{ + return FlashStatus_FLASH0; +} + +ARM_DRIVER_FLASH Driver_FLASH0 = { ARM_Flash_GetVersion, ARM_Flash_GetCapabilities, ARM_Flash_Initialize, + ARM_Flash_Uninitialize, ARM_Flash_PowerControl, ARM_Flash_FLASH0_ReadData, + ARM_Flash_FLASH0_ProgramData, ARM_Flash_FLASH0_EraseSector, ARM_Flash_FLASH0_EraseChip, + ARM_Flash_FLASH0_GetStatus, ARM_Flash_FLASH0_GetInfo }; +#endif /* RTE_FLASH0 */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.c b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.c new file mode 100644 index 00000000000000..03bdf106ec1b95 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.c @@ -0,0 +1,1249 @@ +/* + * Copyright (c) 2019-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Driver_SSE300_PPC.h" + +#include "Driver_Common.h" +#include "RTE_Device.h" +#include "cmsis.h" +#include "cmsis_driver_config.h" +#include "ppc_sse300_drv.h" + +/* Driver version */ +#define ARM_PPC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) + +/* Driver Version */ +static const ARM_DRIVER_VERSION DriverVersion = { ARM_PPC_API_VERSION, ARM_PPC_DRV_VERSION }; + +ARM_DRIVER_VERSION PPC_SSE300_GetVersion(void) +{ + return DriverVersion; +} + +typedef struct _SSE300_PPC_Resources +{ + struct ppc_sse300_dev_t * dev; /* PPC device structure */ +} SSE300_PPC_Resources; + +#if (RTE_PPC_SSE300_MAIN0) + +static SSE300_PPC_Resources MAIN0_PPC_DEV = { + .dev = &PPC_SSE300_MAIN0_DEV, +}; + +/* MAIN0 PPC Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN0_Initialize(void) +{ + ppc_sse300_init(MAIN0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN0_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_MAIN0_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN0_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN0_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN0_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN0_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN0 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN0_Initialize, + .Uninitialize = PPC_SSE300_MAIN0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN0_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN0_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN0 */ + +#if (RTE_PPC_SSE300_MAIN_EXP0) + +static SSE300_PPC_Resources MAIN_EXP0_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP0_DEV, +}; + +/* MAIN PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP0_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP0_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_MAIN_EXP0_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP0_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP0_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP0_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP0_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP0 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP0_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP0_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP0 */ + +#if (RTE_PPC_SSE300_MAIN_EXP1) + +static SSE300_PPC_Resources MAIN_EXP1_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP1_DEV, +}; + +/* MAIN PPCEXP1 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP1_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP1_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_MAIN_EXP1_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP1_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP1_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP1_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP1_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP1 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP1_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP1_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP1_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP1 */ + +#if (RTE_PPC_SSE300_MAIN_EXP2) + +static SSE300_PPC_Resources MAIN_EXP2_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP2_DEV, +}; + +/* MAIN PPCEXP2 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP2_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP2_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP2_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP2_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP2_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP2_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP2_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_MAIN_EXP2_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP2_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP2_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP2_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP2_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP2_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP2_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP2_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP2_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP2_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP2_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP2_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP2 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP2 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP2_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP2_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP2_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP2_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP2_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP2_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP2_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP2_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP2_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP2_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP2 */ + +#if (RTE_PPC_SSE300_MAIN_EXP3) + +static SSE300_PPC_Resources MAIN_EXP3_PPC_DEV = { + .dev = &PPC_SSE300_MAIN_EXP3_DEV, +}; + +/* MAIN PPCEXP3 Driver wrapper functions */ +static int32_t PPC_SSE300_MAIN_EXP3_Initialize(void) +{ + ppc_sse300_init(MAIN_EXP3_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP3_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_MAIN_EXP3_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(MAIN_EXP3_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP3_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(MAIN_EXP3_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_MAIN_EXP3_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(MAIN_EXP3_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_MAIN_EXP3_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(MAIN_EXP3_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_MAIN_EXP3_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(MAIN_EXP3_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_MAIN_EXP3_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(MAIN_EXP3_PPC_DEV.dev); +} + +static void PPC_SSE300_MAIN_EXP3_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(MAIN_EXP3_PPC_DEV.dev); +} + +static bool PPC_SSE300_MAIN_EXP3_InterruptState(void) +{ + return ppc_sse300_irq_state(MAIN_EXP3_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 MAIN EXP3 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP3 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_MAIN_EXP3_Initialize, + .Uninitialize = PPC_SSE300_MAIN_EXP3_Uninitialize, + .ConfigPrivilege = PPC_SSE300_MAIN_EXP3_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_MAIN_EXP3_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_MAIN_EXP3_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_MAIN_EXP3_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_MAIN_EXP3_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_MAIN_EXP3_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_MAIN_EXP3_ClearInterrupt, + .InterruptState = PPC_SSE300_MAIN_EXP3_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_MAIN_EXP3 */ + +#if (RTE_PPC_SSE300_PERIPH0) + +static SSE300_PPC_Resources PERIPH0_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH0_DEV, +}; + +/* PERIPH0 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH0_Initialize(void) +{ + ppc_sse300_init(PERIPH0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH0_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH0_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH0_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH0_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH0_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH0_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH0 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH0_Initialize, + .Uninitialize = PPC_SSE300_PERIPH0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH0_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH0_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH0 */ + +#if (RTE_PPC_SSE300_PERIPH1) + +static SSE300_PPC_Resources PERIPH1_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH1_DEV, +}; + +/* PERIPH1 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH1_Initialize(void) +{ + ppc_sse300_init(PERIPH1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH1_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH1_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH1_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH1_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH1_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH1_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH1 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH1_Initialize, + .Uninitialize = PPC_SSE300_PERIPH1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH1_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH1_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH1 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP0) + +static SSE300_PPC_Resources PERIPH_EXP0_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP0_DEV, +}; + +/* PERIPH PPCEXP0 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP0_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP0_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP0_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP0_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP0_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP0_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH_EXP0_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP0_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP0_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP0_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP0_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP0_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP0_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP0_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP0_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP0_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP0_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP0_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP0 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP0 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP0_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP0_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP0_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP0_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP0_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP0_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP0_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP0_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP0_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP0_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP0 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP1) + +static SSE300_PPC_Resources PERIPH_EXP1_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP1_DEV, +}; + +/* PERIPH PPCEXP1 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP1_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP1_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP1_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP1_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP1_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP1_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH_EXP1_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP1_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP1_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP1_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP1_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP1_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP1_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP1_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP1_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP1_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP1_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP1_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP1 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP1 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP1_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP1_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP1_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP1_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP1_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP1_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP1_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP1_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP1_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP1_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP1 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP2) + +static SSE300_PPC_Resources PERIPH_EXP2_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP2_DEV, +}; + +/* PERIPH PPCEXP2 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP2_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP2_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP2_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP2_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP2_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP2_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP2_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH_EXP2_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP2_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP2_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP2_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP2_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP2_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP2_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP2_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP2_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP2_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP2_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP2_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP2 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP2 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP2_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP2_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP2_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP2_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP2_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP2_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP2_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP2_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP2_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP2_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP2 */ + +#if (RTE_PPC_SSE300_PERIPH_EXP3) + +static SSE300_PPC_Resources PERIPH_EXP3_PPC_DEV = { + .dev = &PPC_SSE300_PERIPH_EXP3_DEV, +}; + +/* PERIPH PPCEXP3 Driver wrapper functions */ +static int32_t PPC_SSE300_PERIPH_EXP3_Initialize(void) +{ + ppc_sse300_init(PERIPH_EXP3_PPC_DEV.dev); + + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP3_Uninitialize(void) +{ + /* Nothing to do */ + return ARM_DRIVER_OK; +} + +static int32_t PPC_SSE300_PERIPH_EXP3_ConfigPrivilege(uint32_t periph, PPC_SSE300_SecAttr sec_attr, PPC_SSE300_PrivAttr priv_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_privilege(PERIPH_EXP3_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr, + (enum ppc_sse300_priv_attr_t) priv_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP3_IsPeriphPrivOnly(uint32_t periph) +{ + return ppc_sse300_is_periph_priv_only(PERIPH_EXP3_PPC_DEV.dev, periph); +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +static int32_t PPC_SSE300_PERIPH_EXP3_ConfigSecurity(uint32_t periph, PPC_SSE300_SecAttr sec_attr) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_config_security(PERIPH_EXP3_PPC_DEV.dev, periph, (enum ppc_sse300_sec_attr_t) sec_attr); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static bool PPC_SSE300_PERIPH_EXP3_IsPeriphSecure(uint32_t periph) +{ + return ppc_sse300_is_periph_secure(PERIPH_EXP3_PPC_DEV.dev, periph); +} + +static int32_t PPC_SSE300_PERIPH_EXP3_EnableInterrupt(void) +{ + enum ppc_sse300_error_t ret; + + ret = ppc_sse300_irq_enable(PERIPH_EXP3_PPC_DEV.dev); + + if (ret != PPC_SSE300_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + + return ARM_DRIVER_OK; +} + +static void PPC_SSE300_PERIPH_EXP3_DisableInterrupt(void) +{ + ppc_sse300_irq_disable(PERIPH_EXP3_PPC_DEV.dev); +} + +static void PPC_SSE300_PERIPH_EXP3_ClearInterrupt(void) +{ + ppc_sse300_clear_irq(PERIPH_EXP3_PPC_DEV.dev); +} + +static bool PPC_SSE300_PERIPH_EXP3_InterruptState(void) +{ + return ppc_sse300_irq_state(PERIPH_EXP3_PPC_DEV.dev); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +/* PPC SSE-300 PERIPH EXP3 Driver CMSIS access structure */ +DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP3 = { .GetVersion = PPC_SSE300_GetVersion, + .Initialize = PPC_SSE300_PERIPH_EXP3_Initialize, + .Uninitialize = PPC_SSE300_PERIPH_EXP3_Uninitialize, + .ConfigPrivilege = PPC_SSE300_PERIPH_EXP3_ConfigPrivilege, + .IsPeriphPrivOnly = PPC_SSE300_PERIPH_EXP3_IsPeriphPrivOnly, +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + .ConfigSecurity = PPC_SSE300_PERIPH_EXP3_ConfigSecurity, + .IsPeriphSecure = PPC_SSE300_PERIPH_EXP3_IsPeriphSecure, + .EnableInterrupt = PPC_SSE300_PERIPH_EXP3_EnableInterrupt, + .DisableInterrupt = PPC_SSE300_PERIPH_EXP3_DisableInterrupt, + .ClearInterrupt = PPC_SSE300_PERIPH_EXP3_ClearInterrupt, + .InterruptState = PPC_SSE300_PERIPH_EXP3_InterruptState +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +}; +#endif /* RTE_PPC_SSE300_PERIPH_EXP3 */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.h b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.h new file mode 100644 index 00000000000000..1bff6b9ef1e437 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_SSE300_PPC.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2019-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PPC_SSE300_DRIVER_H__ +#define __PPC_SSE300_DRIVER_H__ + +#include "Driver_Common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* API version */ +#define ARM_PPC_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) + +/* Security attribute used to configure the peripheral */ +typedef enum _PPC_SSE300_SecAttr +{ + PPC_SSE300_SECURE_CONFIG = 0, /*!< Secure access */ + PPC_SSE300_NONSECURE_CONFIG, /*!< Non-secure access */ +} PPC_SSE300_SecAttr; + +/* Privilege attribute used to configure the peripheral */ +typedef enum _PPC_SSE300_PrivAttr +{ + PPC_SSE300_PRIV_AND_NONPRIV_CONFIG = 0, /*!< Privilege and non-privilege + * access */ + PPC_SSE300_PRIV_CONFIG, /*!< Privilege only access */ +} PPC_SSE300_PrivAttr; + +/* Function descriptions */ +/** + SACFG - Secure Privilege Control Block + NSACFG - Non-Secure Privilege Control Block + + \fn ARM_DRIVER_VERSION PPC_SSE300_GetVersion(void) + \brief Get driver version. + \return \ref ARM_DRIVER_VERSION + + \fn int32_t PPC_SSE300_Initialize(void) + \brief Initializes PPC Interface. + \return Returns SSE-300 PPC error code. + + \fn int32_t PPC_SSE300_Uninitialize(void) + \brief De-initializes PPC Interface. + \return Returns SSE-300 PPC error code. + + \fn int32_t PPC_SSE300_ConfigPrivilege(uint32_t periph, + PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr) + \brief Configures privilege level with privileged and unprivileged + access or privileged access only in the given security domain + for a peripheral controlled by the given PPC. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \param[in] sec_attr: Specifies Secure or Non Secure domain. + \param[in] priv_attr: Privilege attribute value to set. + \return Returns SSE-300 PPC error code. + + \fn bool PPC_SSE300_IsPeriphPrivOnly (uint32_t periph) + \brief Checks if the peripheral is configured to be privilege only + - with non-secure caller in the non-secure domain + - with secure caller in the configured security domain + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \return Returns true if the peripheral is configured as privilege access + only, false for privilege and unprivilege access mode. + + Secure only functions: + + \fn int32_t PPC_SSE300_ConfigSecurity(uint32_t periph, + PPC_SSE300_SecAttr sec_attr) + \brief Configures security level for a peripheral controlled by the + given PPC with secure or non-secure access only. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \param[in] sec_attr: Secure attribute value to set. + \return Returns SSE-300 PPC error code. + + \fn bool PPC_SSE300_IsPeriphSecure (uint32_t periph) + \brief Checks if the peripheral is configured to be secure. + \param[in] periph: Peripheral mask for SACFG and NSACFG registers. + \return Returns true if the peripheral is configured as secure, + false for non-secure. + + \fn int32_t PPC_SSE300_EnableInterrupt (void) + \brief Enables PPC interrupt. + \return Returns SSE-300 PPC error code. + + \fn void PPC_SSE300_DisableInterrupt (void) + \brief Disables PPC interrupt. + + \fn void PPC_SSE300_ClearInterrupt (void) + \brief Clears PPC interrupt. + + \fn bool PPC_SSE300_InterruptState (void) + \brief Gets PPC interrupt state. + \return Returns true if the interrupt is active, false otherwise. +*/ + +/** + * \brief Access structure of the PPC Driver. + */ +typedef struct _DRIVER_PPC_SSE300 +{ + ARM_DRIVER_VERSION (*GetVersion)(void); ///< Pointer to \ref ARM_PPC_GetVersion : Get driver version. + int32_t (*Initialize)(void); ///< Pointer to \ref ARM_PPC_Initialize : Initialize the PPC Interface. + int32_t (*Uninitialize)(void); ///< Pointer to \ref ARM_PPC_Uninitialize : De-initialize the PPC Interface. + int32_t (*ConfigPrivilege)( + uint32_t periph, PPC_SSE300_SecAttr sec_attr, + PPC_SSE300_PrivAttr priv_attr); ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC. + bool (*IsPeriphPrivOnly)( + uint32_t periph); ///< Pointer to \ref IsPeriphPrivOnly : Check if the peripheral is configured to be privilege only. +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + int32_t (*ConfigSecurity)( + uint32_t periph, + PPC_SSE300_SecAttr sec_attr); ///< Pointer to \ref ARM_PPC_ConfigPeriph : Configure a peripheral controlled by the PPC. + bool (*IsPeriphSecure)( + uint32_t periph); ///< Pointer to \ref IsPeriphSecure : Check if the peripheral is configured to be secure. + int32_t (*EnableInterrupt)(void); ///< Pointer to \ref ARM_PPC_EnableInterrupt : Enable PPC interrupt. + void (*DisableInterrupt)(void); ///< Pointer to \ref ARM_PPC_DisableInterrupt : Disable PPC interrupt. + void (*ClearInterrupt)(void); ///< Pointer to \ref ARM_PPC_ClearInterrupt : Clear PPC interrupt. + bool (*InterruptState)(void); ///< Pointer to \ref ARM_PPC_InterruptState : PPC interrupt State. +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ +} const DRIVER_PPC_SSE300; + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE300_DRIVER_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_USART.c b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_USART.c new file mode 100644 index 00000000000000..14739aab26ba0d --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/Driver_USART.c @@ -0,0 +1,694 @@ +/* + * Copyright (c) 2013-2022 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 "RTE_Device.h" +#include "cmsis_driver_config.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 transferred */ + 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++; + } + + if (uart_dev->cb_event != NULL) + { + uart_dev->cb_event(ARM_USART_EVENT_SEND_COMPLETE); + } + + /* Waits until character is transmitted */ + 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++; + } + + if (uart_dev->cb_event != NULL) + { + uart_dev->cb_event(ARM_USART_EVENT_RECEIVE_COMPLETE); + } + + 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) + { +#ifdef UART_TX_RX_CONTROL_ENABLED + case ARM_USART_CONTROL_TX: + if (arg == 0) + { + uart_cmsdk_tx_disable(uart_dev->dev); + } + else if (arg == 1) + { + if (uart_cmsdk_tx_enable(uart_dev->dev) != UART_CMSDK_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + } + else + { + return ARM_DRIVER_ERROR_PARAMETER; + } + break; + case ARM_USART_CONTROL_RX: + if (arg == 0) + { + uart_cmsdk_rx_disable(uart_dev->dev); + } + else if (arg == 1) + { + if (uart_cmsdk_rx_enable(uart_dev->dev) != UART_CMSDK_ERR_NONE) + { + return ARM_DRIVER_ERROR; + } + } + else + { + return ARM_DRIVER_ERROR_PARAMETER; + } + break; +#endif + 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/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/RTE_Device.h b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/RTE_Device.h new file mode 100644 index 00000000000000..d26bdd3910661c --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/RTE_Device.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2019-2021 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +#ifndef __RTE_DEVICE_H +#define __RTE_DEVICE_H + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] +// Configuration settings for Driver_USART0 in component ::Drivers:USART +#define RTE_USART0 1 + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] +// Configuration settings for Driver_USART1 in component ::Drivers:USART +#define RTE_USART1 0 + +// MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 + +// MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_ISRAM1_MPC 1 + +// MPC (Memory Protection Controller) [Driver_SRAM_MPC] +// Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC +#define RTE_SRAM_MPC 1 + +// MPC (Memory Protection Controller) [Driver_QSPI_MPC] +// Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC +#define RTE_QSPI_MPC 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN0] +// Configuration settings for Driver_PPC_SSE300_MAIN0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP0] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP1] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP2] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP2 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP3] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP3 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP3 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH0] +// Configuration settings for Driver_PPC_SSE300_PERIPH0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH1] +// Configuration settings for Driver_PPC_SSE300_PERIPH1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP0] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP1] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP2] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP2 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP3] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP3 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP3 1 + +// Flash device emulated by QSPI [Driver_Flash0] +// Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 + +#endif /* __RTE_DEVICE_H */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/cmsis_driver_config.h b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/cmsis_driver_config.h new file mode 100644 index 00000000000000..7197384521a3fb --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/cmsis_drivers/config/cmsis_driver_config.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2021 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 "RTE_Device.h" +#include "cmsis.h" +#include "device_definition.h" + +#define UART0_CMSDK_DEV UART0_CMSDK_DEV_NS + +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S +#define MPC_ISRAM1_DEV MPC_ISRAM1_DEV_S +#define MPC_SRAM_DEV MPC_SRAM_DEV_S +#define MPC_QSPI_DEV MPC_QSPI_DEV_S + +#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S +#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S +#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S +#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S +#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S +#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S +#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S +#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S +#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S +#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S +#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/config.cmake b/examples/platform/openiotsdk/tf-m/targets/an552/config.cmake new file mode 100755 index 00000000000000..868e43e5803aed --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/config.cmake @@ -0,0 +1,24 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021-2022, Arm Limited. All rights reserved. +# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) +# or an affiliate of Cypress Semiconductor Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +set(CONFIG_TFM_USE_TRUSTZONE ON CACHE BOOL "Enable use of TrustZone to transition between NSPE and SPE") +set(TFM_MULTI_CORE_TOPOLOGY OFF CACHE BOOL "Whether to build for a dual-cpu architecture") + +set(PLATFORM_SLIH_IRQ_TEST_SUPPORT ON CACHE BOOL "Platform supports SLIH IRQ tests") +set(PLATFORM_FLIH_IRQ_TEST_SUPPORT ON CACHE BOOL "Platform supports FLIH IRQ tests") + +# Make FLIH IRQ test as the default IRQ test on Corstone-310 +set(TEST_NS_SLIH_IRQ OFF CACHE BOOL "Whether to build NS regression Second-Level Interrupt Handling tests") + +if(BL2) + set(BL2_TRAILER_SIZE 0x800 CACHE STRING "Trailer size") +else() + #No header if no bootloader, but keep IMAGE_CODE_SIZE the same + set(BL2_TRAILER_SIZE 0xC00 CACHE STRING "Trailer size") +endif() diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/config/device_cfg.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/config/device_cfg.h new file mode 100644 index 00000000000000..cf136bb5457a6f --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/config/device_cfg.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +/** + * \file device_cfg.h + * \brief + * This is the device configuration file with only used peripherals + * defined and configured via the secure and/or non-secure base address. + */ + +/* ARM Memory Protection Controller (MPC) */ +#define MPC_ISRAM0_S +#define MPC_ISRAM1_S +#define MPC_SRAM_S +#define MPC_QSPI_S + +/* ARM Peripheral Protection Controllers (PPC) */ +#define PPC_SSE300_MAIN0_S +#define PPC_SSE300_MAIN_EXP0_S +#define PPC_SSE300_MAIN_EXP1_S +#define PPC_SSE300_MAIN_EXP2_S +#define PPC_SSE300_MAIN_EXP3_S +#define PPC_SSE300_PERIPH0_S +#define PPC_SSE300_PERIPH1_S +#define PPC_SSE300_PERIPH_EXP0_S +#define PPC_SSE300_PERIPH_EXP1_S +#define PPC_SSE300_PERIPH_EXP2_S +#define PPC_SSE300_PERIPH_EXP3_S + +/* ARM UART CMSDK */ +#define DEFAULT_UART_BAUDRATE 115200 +#define UART0_CMSDK_NS + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S +#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + +/** + * Arbitrary scaling values for test purposes + */ +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u + +/* System Timer Armv8-M */ +#define SYSTIMER0_ARMV8_M_S + +#define SYSTIMER1_ARMV8_M_NS + +#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (32000000ul) +#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (32000000ul) + +#endif /* __DEVICE_CFG_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/an552.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/an552.h new file mode 100644 index 00000000000000..524ae42ba25a30 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/an552.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 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 __AN552_H__ +#define __AN552_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ====================== 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 __CM55_REV 0x0001U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __FPU_DP 1U /* double precision FPU */ +#define __DSP_PRESENT 1U /* DSP extension present */ +#define __PMU_PRESENT 1U /* PMU present */ +#define __PMU_NUM_EVENTCNT 8U /* Number of PMU event counters */ +#define __ICACHE_PRESENT 1U /* Instruction Cache present */ +#define __DCACHE_PRESENT 1U /* Data Cache present */ + +#include "platform_irq.h" + +#include "core_cm55.h" /* Processor and core peripherals */ +#include "platform_base_address.h" +#include "platform_pins.h" +#include "platform_regs.h" +#include "system_core_init.h" + +/* ===================== 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 + +#ifdef __cplusplus +} +#endif + +#endif /* __AN552_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/cmsis.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/cmsis.h new file mode 100644 index 00000000000000..922e5058d982ca --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/cmsis.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019-2021 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__ + +#include "an552.h" + +#endif /* __CMSIS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/device_definition.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/device_definition.h new file mode 100644 index 00000000000000..fb41a71c7d300e --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/device_definition.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2019-2021 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file device_definition.h + * \brief The structure definitions in this file are exported based on the + * peripheral definitions from device_cfg.h. + * This file is meant to be used as a helper for baremetal + * applications and/or as an example of how to configure the generic + * driver structures. + */ + +#ifndef __DEVICE_DEFINITION_H__ +#define __DEVICE_DEFINITION_H__ + +#include "device_cfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ======= Defines peripheral configuration structures ======= */ +/* UART CMSDK driver structures */ +#ifdef UART0_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_S; +#endif +#ifdef UART0_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS; +#endif + +#ifdef UART1_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART1_CMSDK_DEV_S; +#endif +#ifdef UART1_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART1_CMSDK_DEV_NS; +#endif + +#ifdef UART2_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART2_CMSDK_DEV_S; +#endif +#ifdef UART2_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART2_CMSDK_DEV_NS; +#endif + +#ifdef UART3_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART3_CMSDK_DEV_S; +#endif +#ifdef UART3_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART3_CMSDK_DEV_NS; +#endif + +#ifdef UART4_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART4_CMSDK_DEV_S; +#endif +#ifdef UART4_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART4_CMSDK_DEV_NS; +#endif + +#ifdef UART5_CMSDK_S +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART5_CMSDK_DEV_S; +#endif +#ifdef UART5_CMSDK_NS +#include "uart_cmsdk_drv.h" +extern struct uart_cmsdk_dev_t UART5_CMSDK_DEV_NS; +#endif + +/* ARM PPC driver structures */ +#ifdef PPC_SSE300_MAIN0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN0_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP1_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP2_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP2_DEV_S; +#endif + +#ifdef PPC_SSE300_MAIN_EXP3_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP3_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH0_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH1_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP0_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP0_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP1_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP1_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP2_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP2_DEV_S; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP3_S +#include "ppc_sse300_drv.h" +extern struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP3_DEV_S; +#endif + +/* System counters */ +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S +#include "syscounter_armv8-m_cntrl_drv.h" +extern struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +#include "syscounter_armv8-m_read_drv.h" +extern struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS; +#endif + +/* System timers */ +#ifdef SYSTIMER0_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER0_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER1_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER1_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER2_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER2_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS; +#endif + +#ifdef SYSTIMER3_ARMV8_M_S +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S; +#endif +#ifdef SYSTIMER3_ARMV8_M_NS +#include "systimer_armv8-m_drv.h" +extern struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS; +#endif + +/* System Watchdogs */ +#ifdef SYSWDOG_ARMV8_M_S +#include "syswdog_armv8-m_drv.h" +extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S; +#endif +#ifdef SYSWDOG_ARMV8_M_NS +#include "syswdog_armv8-m_drv.h" +extern struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS; +#endif + +/* ARM MPC SIE 300 driver structures */ +#ifdef MPC_SRAM_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_SRAM_DEV_S; +#endif + +#ifdef MPC_QSPI_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_QSPI_DEV_S; +#endif + +#ifdef MPC_DDR4_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_DDR4_DEV_S; +#endif + +#ifdef MPC_ISRAM0_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_ISRAM0_DEV_S; +#endif + +#ifdef MPC_ISRAM1_S +#include "mpc_sie_drv.h" +extern struct mpc_sie_dev_t MPC_ISRAM1_DEV_S; +#endif + +#ifdef MPS3_IO_S +#include "arm_mps3_io_drv.h" +extern struct arm_mps3_io_dev_t MPS3_IO_DEV_S; +#endif + +#ifdef MPS3_IO_NS +#include "arm_mps3_io_drv.h" +extern struct arm_mps3_io_dev_t MPS3_IO_DEV_NS; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __DEVICE_DEFINITION_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_irq.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_irq.h new file mode 100644 index 00000000000000..09d51f64148172 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_irq.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019-2021 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PLATFORM_IRQ_H__ +#define __PLATFORM_IRQ_H__ + +typedef enum _IRQn_Type +{ + NonMaskableInt_IRQn = -14, /* Non Maskable Interrupt */ + HardFault_IRQn = -13, /* HardFault Interrupt */ + MemoryManagement_IRQn = -12, /* Memory Management Interrupt */ + BusFault_IRQn = -11, /* Bus Fault Interrupt */ + UsageFault_IRQn = -10, /* Usage Fault Interrupt */ + SecureFault_IRQn = -9, /* Secure Fault Interrupt */ + SVCall_IRQn = -5, /* SV Call Interrupt */ + DebugMonitor_IRQn = -4, /* Debug Monitor Interrupt */ + PendSV_IRQn = -2, /* Pend SV Interrupt */ + SysTick_IRQn = -1, /* System Tick Interrupt */ + NONSEC_WATCHDOG_RESET_REQ_IRQn = 0, /* Non-Secure Watchdog Reset + * Request Interrupt + */ + NONSEC_WATCHDOG_IRQn = 1, /* Non-Secure Watchdog Interrupt */ + SLOWCLK_TIMER_IRQn = 2, /* SLOWCLK Timer Interrupt */ + TIMER0_IRQn = 3, /* TIMER 0 Interrupt */ + TIMER1_IRQn = 4, /* TIMER 1 Interrupt */ + TIMER2_IRQn = 5, /* TIMER 2 Interrupt */ + /* Reserved = 6, Reserved */ + /* Reserved = 7, Reserved */ + /* 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 */ + MGMT_PPU_IRQn = 14, /* MGMT PPU */ + SYS_PPU_IRQn = 15, /* SYS PPU */ + CPU0_PPU_IRQn = 16, /* CPU0 PPU */ + /* Reserved = 17, Reserved */ + /* Reserved = 18, Reserved */ + /* Reserved = 19, Reserved */ + /* Reserved = 20, Reserved */ + /* Reserved = 21, Reserved */ + /* Reserved = 22, Reserved */ + /* Reserved = 23, Reserved */ + /* Reserved = 24, Reserved */ + /* Reserved = 25, Reserved */ + DEBUG_PPU_IRQn = 26, /* DEBUG PPU */ + TIMER3_AON_IRQn = 27, /* TIMER 3 AON Interrupt */ + CPU0_CTI_0_IRQn = 28, /* CPU0 CTI IRQ 0 */ + CPU0_CTI_1_IRQn = 29, /* CPU0 CTI IRQ 1 */ + /* Reserved = 30, Reserved */ + /* Reserved = 31, Reserved */ + System_Timestamp_Counter_IRQn = 32, /* System timestamp counter Interrupt */ + UARTRX0_IRQn = 33, /* UART 0 RX Interrupt */ + UARTTX0_IRQn = 34, /* UART 0 TX Interrupt */ + UARTRX1_IRQn = 35, /* UART 1 RX Interrupt */ + UARTTX1_IRQn = 36, /* UART 1 TX Interrupt */ + UARTRX2_IRQn = 37, /* UART 2 RX Interrupt */ + UARTTX2_IRQn = 38, /* UART 2 TX Interrupt */ + UARTRX3_IRQn = 39, /* UART 3 RX Interrupt */ + UARTTX3_IRQn = 40, /* UART 3 TX Interrupt */ + UARTRX4_IRQn = 41, /* UART 4 RX Interrupt */ + UARTTX4_IRQn = 42, /* UART 4 TX Interrupt */ + UART0_Combined_IRQn = 43, /* UART 0 Combined Interrupt */ + UART1_Combined_IRQn = 44, /* UART 1 Combined Interrupt */ + UART2_Combined_IRQn = 45, /* UART 2 Combined Interrupt */ + UART3_Combined_IRQn = 46, /* UART 3 Combined Interrupt */ + UART4_Combined_IRQn = 47, /* UART 4 Combined Interrupt */ + UARTOVF_IRQn = 48, /* UART 0, 1, 2, 3, 4 & 5 Overflow Interrupt */ + ETHERNET_IRQn = 49, /* Ethernet Interrupt */ + I2S_IRQn = 50, /* Audio I2S Interrupt */ + TOUCH_SCREEN_IRQn = 51, /* Touch Screen Interrupt */ + USB_IRQn = 52, /* USB Interrupt */ + SPI_ADC_IRQn = 53, /* SPI ADC Interrupt */ + SPI_SHIELD0_IRQn = 54, /* SPI (Shield 0) Interrupt */ + SPI_SHIELD1_IRQn = 55, /* SPI (Shield 1) Interrupt */ + ETHOS_U55_IRQn = 56, /* Ethos-U55 Interrupt */ + /* Reserved = 57:68 Reserved */ + GPIO0_Combined_IRQn = 69, /* GPIO 0 Combined Interrupt */ + GPIO1_Combined_IRQn = 70, /* GPIO 1 Combined Interrupt */ + GPIO2_Combined_IRQn = 71, /* GPIO 2 Combined Interrupt */ + GPIO3_Combined_IRQn = 72, /* GPIO 3 Combined Interrupt */ + GPIO0_0_IRQn = 73, /* GPIO0 has 16 pins with IRQs */ + GPIO0_1_IRQn = 74, + GPIO0_2_IRQn = 75, + GPIO0_3_IRQn = 76, + GPIO0_4_IRQn = 77, + GPIO0_5_IRQn = 78, + GPIO0_6_IRQn = 79, + GPIO0_7_IRQn = 80, + GPIO0_8_IRQn = 81, + GPIO0_9_IRQn = 82, + GPIO0_10_IRQn = 83, + GPIO0_11_IRQn = 84, + GPIO0_12_IRQn = 85, + GPIO0_13_IRQn = 86, + GPIO0_14_IRQn = 87, + GPIO0_15_IRQn = 88, + GPIO1_0_IRQn = 89, /* GPIO1 has 16 pins with IRQs */ + GPIO1_1_IRQn = 90, + GPIO1_2_IRQn = 91, + GPIO1_3_IRQn = 92, + GPIO1_4_IRQn = 93, + GPIO1_5_IRQn = 94, + GPIO1_6_IRQn = 95, + GPIO1_7_IRQn = 96, + GPIO1_8_IRQn = 97, + GPIO1_9_IRQn = 98, + GPIO1_10_IRQn = 99, + GPIO1_11_IRQn = 100, + GPIO1_12_IRQn = 101, + GPIO1_13_IRQn = 102, + GPIO1_14_IRQn = 103, + GPIO1_15_IRQn = 104, + GPIO2_0_IRQn = 105, /* GPIO2 has 16 pins with IRQs */ + GPIO2_1_IRQn = 106, + GPIO2_2_IRQn = 107, + GPIO2_3_IRQn = 108, + GPIO2_4_IRQn = 109, + GPIO2_5_IRQn = 110, + GPIO2_6_IRQn = 111, + GPIO2_7_IRQn = 112, + GPIO2_8_IRQn = 113, + GPIO2_9_IRQn = 114, + GPIO2_10_IRQn = 115, + GPIO2_11_IRQn = 116, + GPIO2_12_IRQn = 117, + GPIO2_13_IRQn = 118, + GPIO2_14_IRQn = 119, + GPIO2_15_IRQn = 120, + GPIO3_0_IRQn = 121, /* GPIO3 has 4 pins with IRQs */ + GPIO3_1_IRQn = 122, + GPIO3_2_IRQn = 123, + GPIO3_3_IRQn = 124, + UARTRX5_IRQn = 125, /* UART 5 RX Interrupt */ + UARTTX5_IRQn = 126, /* UART 5 TX Interrupt */ + UART5_IRQn = 127, /* UART 5 combined Interrupt */ + /* Reserved = 128:130 Reserved */ +} IRQn_Type; + +#endif /* __PLATFORM_IRQ_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_pins.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_pins.h new file mode 100755 index 00000000000000..843ed7133f23ee --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_pins.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2019-2022 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 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 arm_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, + AHB_GPIO3_4 = 4U, + AHB_GPIO3_5 = 5U, + AHB_GPIO3_6 = 6U, + AHB_GPIO3_7 = 7U, + AHB_GPIO3_8 = 8U, + AHB_GPIO3_9 = 9U, + AHB_GPIO3_10 = 10U, + AHB_GPIO3_11 = 11U, + AHB_GPIO3_12 = 12U, + AHB_GPIO3_13 = 13U, + AHB_GPIO3_15 = 15U, + AHB_GPIO3_14 = 14U, +}; + +/* GPIO shield 0 definition */ +#define SH0_UART_RX AHB_GPIO0_0 +#define SH0_UART_TX AHB_GPIO0_1 +#define SH0_SPI_SS AHB_GPIO0_10 +#define SH0_SPI_MOSI AHB_GPIO0_11 +#define SH0_SPI_MISO AHB_GPIO0_12 +#define SH0_SPI_SCK AHB_GPIO0_13 +#define SH0_I2C_SDA AHB_GPIO0_14 +#define SH0_I2C_SCL AHB_GPIO0_15 + +/* GPIO shield 1 definition */ +#define SH1_UART_RX AHB_GPIO1_0 +#define SH1_UART_TX AHB_GPIO1_1 + +#define SH1_SPI_SS AHB_GPIO1_10 +#define SH1_SPI_MOSI AHB_GPIO1_11 +#define SH1_SPI_MISO AHB_GPIO1_12 +#define SH1_SPI_SCK AHB_GPIO1_13 +#define SH1_I2C_SDA AHB_GPIO1_14 +#define SH1_I2C_SCL AHB_GPIO1_15 + +#endif /* __PLATFORM_PINS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_regs.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_regs.h new file mode 100644 index 00000000000000..99ebb2d6a39b04 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/platform_regs.h @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2019-2021 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 + +/* Secure Access Configuration Register Block */ +struct sse300_sacfg_t +{ + volatile uint32_t spcsecctrl; /* 0x000 (R/W) Secure Privilege Controller + Secure Configuration Control + register */ + volatile uint32_t buswait; /* 0x004 (R/W) Bus Access wait control */ + volatile uint32_t reserved0[2]; + volatile uint32_t secrespcfg; /* 0x010 (R/W) Security Violation Response + * Configuration register */ + volatile uint32_t nsccfg; /* 0x014 (R/W) Non Secure Callable + * Configuration for IDAU */ + volatile uint32_t reserved1; + volatile uint32_t secmpcintstat; /* 0x01C (R/ ) Secure MPC IRQ Status */ + volatile uint32_t secppcintstat; /* 0x020 (R/ ) Secure PPC IRQ Status */ + volatile uint32_t secppcintclr; /* 0x024 (R/W) Secure PPC IRQ Clear */ + volatile uint32_t secppcinten; /* 0x028 (R/W) Secure PPC IRQ Enable */ + volatile uint32_t reserved2; + volatile uint32_t secmscintstat; /* 0x030 (R/ ) Secure MSC IRQ Status */ + volatile uint32_t secmscintclr; /* 0x034 (R/W) Secure MSC IRQ Clear */ + volatile uint32_t secmscinten; /* 0x038 (R/W) Secure MSC IRQ Enable */ + volatile uint32_t reserved3; + volatile uint32_t brgintstat; /* 0x040 (R/ ) Bridge Buffer Error IRQ + * Status */ + volatile uint32_t brgintclr; /* 0x044 (R/W) Bridge Buffer Error IRQ + * Clear */ + volatile uint32_t brginten; /* 0x048 (R/W) Bridge Buffer Error IRQ + * Enable */ + volatile uint32_t reserved4; + volatile uint32_t mainnsppc0; /* 0x050 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Main + * Interconnect */ + volatile uint32_t reserved5[3]; + volatile uint32_t mainnsppcexp0; /* 0x060 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp1; /* 0x064 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp2; /* 0x068 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp3; /* 0x06C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t periphnsppc0; /* 0x070 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Peripheral + * Interconnect */ + volatile uint32_t periphnsppc1; /* 0x074 (R/W) Non-secure Access + * Peripheral Protection + * Control 1 on the Peripheral + * Interconnect */ + volatile uint32_t reserved6[2]; + volatile uint32_t periphnsppcexp0; /* 0x080 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp1; /* 0x084 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp2; /* 0x088 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp3; /* 0x08C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t mainspppc0; /* 0x090 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on Main + * Interconnect */ + volatile uint32_t reserved7[3]; + volatile uint32_t mainspppcexp0; /* 0x0A0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp1; /* 0x0A4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp2; /* 0x0A8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp3; /* 0x0AC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphspppc0; /* 0x0B0 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphspppc1; /* 0x0B4 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved8[2]; + volatile uint32_t periphspppcexp0; /* 0x0C0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp1; /* 0x0C4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp2; /* 0x0C8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp3; /* 0x0CC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t nsmscexp; /* 0x0D0 (R/W) Expansion MSC Non-Secure + * Configuration */ + volatile uint32_t reserved9[959]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved10[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* PPC interrupt position mask */ +#define PERIPH_PPC0_INT_POS_MASK (1UL << 0) +#define PERIPH_PPC1_INT_POS_MASK (1UL << 1) +#define PERIPH_PPCEXP0_INT_POS_MASK (1UL << 4) +#define PERIPH_PPCEXP1_INT_POS_MASK (1UL << 5) +#define PERIPH_PPCEXP2_INT_POS_MASK (1UL << 6) +#define PERIPH_PPCEXP3_INT_POS_MASK (1UL << 7) +#define MAIN_PPC0_INT_POS_MASK (1UL << 16) +#define MAIN_PPCEXP0_INT_POS_MASK (1UL << 20) +#define MAIN_PPCEXP1_INT_POS_MASK (1UL << 21) +#define MAIN_PPCEXP2_INT_POS_MASK (1UL << 22) +#define MAIN_PPCEXP3_INT_POS_MASK (1UL << 23) + +/* Non-secure Access Configuration Register Block */ +struct sse300_nsacfg_t +{ + volatile uint32_t reserved0[36]; + volatile uint32_t mainnspppc0; /* 0x090 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Main Interconnect */ + volatile uint32_t reserved1[3]; + + volatile uint32_t mainnspppcexp0; /* 0x0A0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp1; /* 0x0A4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp2; /* 0x0A8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp3; /* 0x0AC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphnspppc0; /* 0x0B0 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphnspppc1; /* 0x0B4 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved2[2]; + volatile uint32_t periphnspppcexp0; /* 0x0C0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp1; /* 0x0C4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp2; /* 0x0C8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp3; /* 0x0CC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved3[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved4[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* MAIN PPC0 peripherals definition */ +/* End MAIN PPC0 peripherals definition */ + +/* MAIN PPCEXP0 peripherals definition */ +#define GPIO0_MAIN_PPCEXP0_POS_MASK (1UL << 0) +#define GPIO1_MAIN_PPCEXP0_POS_MASK (1UL << 1) +#define GPIO2_MAIN_PPCEXP0_POS_MASK (1UL << 2) +#define GPIO3_MAIN_PPCEXP0_POS_MASK (1UL << 3) +#define FMC_GPIO0_MAIN_PPCEXP0_POS_MASK (1UL << 4) +#define FMC_GPIO1_MAIN_PPCEXP0_POS_MASK (1UL << 5) +#define FMC_GPIO2_MAIN_PPCEXP0_POS_MASK (1UL << 6) +#define FMC_AHB_USER_MAIN_PPCEXP0_POS_MASK (1UL << 7) +#define USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK (1UL << 8) +/* End MAIN PPCEXP0 peripherals definition */ + +/* MAIN PPCEXP1 peripherals definition */ +#define AHB_USER1_MAIN_PPCEXP1_POS_MASK (1UL << 1) +#define AHB_USER2_MAIN_PPCEXP1_POS_MASK (1UL << 2) +#define AHB_USER3_MAIN_PPCEXP1_POS_MASK (1UL << 3) +/* End MAIN PPCEXP1 peripherals definition */ + +/* MAIN PPCEXP2 peripherals definition */ +/* End MAIN PPCEXP2 peripherals definition */ + +/* MAIN PPCEXP3 peripherals definition */ +/* End MAIN PPCEXP3 peripherals definition */ + +/* PERIPH PPC0 peripherals definition */ +#define SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK (1UL << 0) +#define SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK (1UL << 1) +#define SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK (1UL << 2) +#define SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK (1UL << 5) +#define WATCHDOG_PERIPH_PPC0_POS_MASK (1UL << 6) +/* There are separate secure and non-secure watchdog peripherals, so this bit + * can only be used in the unprivileged access registers. */ +/* End PERIPH PPC0 peripherals definition */ + +/* PERIPH PPC1 peripherals definition */ +#define SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK (1UL << 0) +/* End PERIPH PPC1 peripherals definition */ + +/* PERIPH PPCEXP0 peripherals definition */ +#define USER_MEM_APB0_PERIPH_PPCEXP0_POS_MASK (1UL << 0) +#define USER_MEM_APB1_PERIPH_PPCEXP0_POS_MASK (1UL << 1) +#define USER_MEM_APB2_PERIPH_PPCEXP0_POS_MASK (1UL << 2) +#define USER_MEM_APB3_PERIPH_PPCEXP0_POS_MASK (1UL << 3) +#define U55_APB_PERIPH_PPCEXP0_POS_MASK (1UL << 4) +#define U55_TIMING_ADAPTER_PERIPH_PPCEXP0_POS_MASK (1UL << 5) +#define MPC_SRAM_PERIPH_PPCEXP0_POS_MASK (1UL << 13) +#define MPC_QSPI_PERIPH_PPCEXP0_POS_MASK (1UL << 14) +#define MPC_DDR4_PERIPH_PPCEXP0_POS_MASK (1UL << 15) +/* End PERIPH PPCEXP0 peripherals definition */ + +/* PERIPH PPCEXP1 peripherals definition */ +#define FPGA_I2C_TOUCH_PERIPH_PPCEXP1_POS_MASK (1UL << 0) +#define FPGA_I2C_AUDIO_PERIPH_PPCEXP1_POS_MASK (1UL << 1) +#define FPGA_SPI_ADC_PERIPH_PPCEXP1_POS_MASK (1UL << 2) +#define FPGA_SPI_SHIELD0_PERIPH_PPCEXP1_POS_MASK (1UL << 3) +#define FPGA_SPI_SHIELD1_PERIPH_PPCEXP1_POS_MASK (1UL << 4) +#define SBCon_I2C_SHIELD0_PERIPH_PPCEXP1_POS_MASK (1UL << 5) +#define SBCon_I2C_SHIELD1_PERIPH_PPCEXP1_POS_MASK (1UL << 6) +#define FPGA_SBCon_I2C_PERIPH_PPCEXP1_POS_MASK (1UL << 8) +#define FMC_APB_SPI0_PERIPH_PPCEXP1_POS_MASK (1UL << 12) +#define FMC_APB_SPI1_PERIPH_PPCEXP1_POS_MASK (1UL << 13) +#define FMC_APB_SPI2_PERIPH_PPCEXP1_POS_MASK (1UL << 14) +#define FMC_APB_USER_PERIPH_PPCEXP1_POS_MASK (1UL << 15) +/* End PERIPH PPCEXP1 peripherals definition */ + +/* PERIPH PPCEXP2 peripherals definition */ +#define FPGA_SCC_PERIPH_PPCEXP2_POS_MASK (1UL << 0) +#define FPGA_I2S_PERIPH_PPCEXP2_POS_MASK (1UL << 1) +#define FPGA_IO_PERIPH_PPCEXP2_POS_MASK (1UL << 2) +#define UART0_PERIPH_PPCEXP2_POS_MASK (1UL << 3) +#define UART1_PERIPH_PPCEXP2_POS_MASK (1UL << 4) +#define UART2_PERIPH_PPCEXP2_POS_MASK (1UL << 5) +#define UART3_PERIPH_PPCEXP2_POS_MASK (1UL << 6) +#define UART4_PERIPH_PPCEXP2_POS_MASK (1UL << 7) +#define UART5_PERIPH_PPCEXP2_POS_MASK (1UL << 8) +#define CLCD_PERIPH_PPCEXP2_POS_MASK (1UL << 10) +#define RTC_PERIPH_PPCEXP2_POS_MASK (1UL << 11) +/* End PERIPH PPCEXP2 peripherals definition */ + +/* PERIPH PPCEXP3 peripherals definition */ +/* End PERIPH PPCEXP3 peripherals definition */ + +struct cpu0_pwrctrl_t +{ + volatile uint32_t cpupwrcfg; /* 0x000 (R/W) CPU 0 Local Power + * Configuration */ + volatile uint32_t reserved0[1011]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved1[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct cpu0_secctrl_t +{ + volatile uint32_t cpuseccfg; /* 0x000 (R/W) CPU Local Security + * Configuration */ + volatile uint32_t reserved0[1011]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved1[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_sysinfo_t +{ + volatile uint32_t soc_identity; /* 0x000 (R/ ) SoC Identity Register */ + volatile uint32_t sys_config0; /* 0x004 (R/ ) System Hardware + * Configuration 0 */ + volatile uint32_t sys_config1; /* 0x008 (R/ ) System Hardware + * Configuration 1 */ + volatile uint32_t reserved0[1006]; + volatile uint32_t iidr; /* 0xFC8 (R/ ) Subsystem Implementation + * Identity */ + volatile uint32_t reserved1; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved2[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_sysctrl_t +{ + volatile uint32_t secdbgstat; /* 0x000 (R/ ) Secure Debug + * Configuration Status */ + volatile uint32_t secdbgset; /* 0x004 (R/W) Secure Debug + * Configuration Set */ + volatile uint32_t secdbgclr; /* 0x008 ( /W) Secure Debug + * Configuration Clear */ + volatile uint32_t scsecctrl; /* 0x00C (R/W) System Control Security + * Controls */ + volatile uint32_t clk_cfg0; /* 0x010 (R/W) Clock Configuration 0 */ + volatile uint32_t clk_cfg1; /* 0x014 (R/W) Clock Configuration 1 */ + volatile uint32_t clock_force; /* 0x018 (R/W) Clock Forces */ + volatile uint32_t reserved0[57]; + volatile uint32_t reset_syndrome; /* 0x100 (R/W) Reset syndrome */ + volatile uint32_t reset_mask; /* 0x104 (R/W) Reset mask */ + volatile uint32_t swreset; /* 0x108 ( /W) Software Reset */ + volatile uint32_t gretreg; /* 0x10C (R/W) General Purpose + * Retention */ + volatile uint32_t initsvtor0; /* 0x110 (R/W) CPU 0 Initial Secure + * Reset Vector Register */ + volatile uint32_t reserved1[3]; + volatile uint32_t cpuwait; /* 0x120 (R/W) CPU Boot Wait Control */ + volatile uint32_t nmi_enable; /* 0x124 (R/W) Non Maskable Interrupts + * Enable */ + volatile uint32_t reserved2[53]; + volatile uint32_t pwrctrl; /* 0x1FC (R/W) Power Configuration and + * Control */ + volatile uint32_t pdcm_pd_sys_sense; /* 0x200 (R/W) PDCM PD_SYS + * Sensitivity */ + volatile uint32_t pdcm_pd_cpu0_sense; /* 0x204 (R/ ) PDCM PD_CPU0 + * Sensitivity */ + volatile uint32_t reserved3[3]; + volatile uint32_t pdcm_pd_vmr0_sense; /* 0x214 (R/W) PDCM PD_VMR0 + * Sensitivity */ + volatile uint32_t pdcm_pd_vmr1_sense; /* 0x218 (R/W) PDCM PD_VMR1 + * Sensitivity */ + volatile uint32_t reserved4[877]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved5[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +struct sse300_ewic_t +{ + volatile uint32_t ewic_cr; /* 0x000 (R/W) EWIC Control */ + volatile uint32_t ewic_ascr; /* 0x004 (R/W) Automatic Sequence + * Control */ + volatile uint32_t ewic_clrmask; /* 0x008 ( /W) Clear All Mask */ + volatile uint32_t ewic_numid; /* 0x00C (R/ ) ID Register for the number + * of events supported */ + volatile uint32_t reserved0[124]; + volatile uint32_t ewic_maska; /* 0x200 (R/W) Set which internal events + * cause wakeup */ + volatile uint32_t ewic_mask[15]; /* 0x204 (R/W) Set which external + * interrupts cause wakeup + * Only the first (total + * system IRQ number)/32 + * registers are implemented + * in array */ + volatile uint32_t reserved1[112]; + volatile uint32_t ewic_penda; /* 0x400 (R/ ) Shows which internal + * interrupts were pended + * while the EWIC was + * enabled */ + + volatile uint32_t ewic_pend[15]; /* 0x404 (R/W) Shows which external + * interrupts were pended + * while the EWIC was + * enabled + * Only the first (total + * system IRQ number)/32 + * registers are implemented + * in array */ + volatile uint32_t reserved2[112]; + volatile uint32_t ewic_psr; /* 0x600 (R/ ) Pending Summary */ + volatile uint32_t reserved3[575]; + volatile uint32_t itctrl; /* 0xF00 (R/ ) Integration Mode Control */ + volatile uint32_t reserved4[39]; + volatile uint32_t claimset; /* 0xFA0 (R/W) Claim Tag Set */ + volatile uint32_t claimclr; /* 0xFA4 (R/W) Claim Tag Clear */ + volatile uint32_t devaff0; /* 0xFA8 (R/ ) Device Affinity 0 */ + volatile uint32_t devaff1; /* 0xFAC (R/ ) Device Affinity 1 */ + volatile uint32_t lar; /* 0xFB0 ( /W) Lock Access */ + volatile uint32_t lsr; /* 0xFB4 (R/ ) Lock Status */ + volatile uint32_t authstatus; /* 0xFB8 (R/ ) Authentication Status */ + volatile uint32_t devarch; /* 0xFBC (R/ ) Device Architecture */ + volatile uint32_t devid2; /* 0xFC0 (R/ ) Device Configuration 2 */ + volatile uint32_t devid1; /* 0xFC4 (R/ ) Device Configuration 1 */ + volatile uint32_t devid; /* 0xFC8 (R/ ) Device Configuration */ + volatile uint32_t devtype; /* 0xFCC (R/ ) Device Type */ + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved5[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; +#endif /* __PLATFORM_REGS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/include/system_core_init.h b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/system_core_init.h new file mode 100755 index 00000000000000..bca3bd04314431 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/include/system_core_init.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009-2022 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.9.0 system_ARMCM55.h + * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c + */ + +#ifndef __SYSTEM_CORE_INIT_H__ +#define __SYSTEM_CORE_INIT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency */ + +/** + \brief Exception / Interrupt Handler Function Prototype +*/ +typedef void (*VECTOR_TABLE_Type)(void); + +/** + \brief Setup the microcontroller system. + Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit(void); + +/** + \brief Update SystemCoreClock variable. + Updates the SystemCoreClock with current core Clock retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_CORE_INIT_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/source/an552_ns_init.c b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/an552_ns_init.c new file mode 100755 index 00000000000000..fa0c445d13e52c --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/an552_ns_init.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "Driver_USART.h" +#include "cmsis.h" +#include "test_interrupt.h" +#include "tfm_peripherals_def.h" +#include "uart_stdout.h" + +int32_t tfm_ns_platform_init(void) +{ + /* Register FPU non-secure test interrupt handler */ + NVIC_SetVector(TFM_FPU_NS_TEST_IRQ, (uint32_t) TFM_FPU_NS_TEST_Handler); + + /* Enable FPU non-secure test interrupt */ + NVIC_EnableIRQ(TFM_FPU_NS_TEST_IRQ); + + stdio_init(); + + return ARM_DRIVER_OK; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/source/device_definition.c b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/device_definition.c new file mode 100755 index 00000000000000..2210868fec02d1 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/device_definition.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file device_definition.c + * \brief This file defines exports the structures based on the peripheral + * definitions from device_cfg.h. + * This file is meant to be used as a helper for baremetal + * applications and/or as an example of how to configure the generic + * driver structures. + */ + +#include "device_definition.h" +#include "platform/include/tfm_plat_defs.h" +#include "platform_base_address.h" + +/* 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 UART0_CMSDK_DEV_S = { &(UART0_CMSDK_DEV_CFG_S), &(UART0_CMSDK_DEV_DATA_S) }; +#endif +#ifdef UART0_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART0_CMSDK_DEV_CFG_NS = { .base = UART0_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE }; +static struct uart_cmsdk_dev_data_t UART0_CMSDK_DEV_DATA_NS = { .state = 0, .system_clk = 0, .baudrate = 0 }; +struct uart_cmsdk_dev_t UART0_CMSDK_DEV_NS = { &(UART0_CMSDK_DEV_CFG_NS), &(UART0_CMSDK_DEV_DATA_NS) }; +#endif + +#ifdef UART1_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART1_CMSDK_DEV_CFG_S = { .base = UART1_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE }; +static struct uart_cmsdk_dev_data_t UART1_CMSDK_DEV_DATA_S = { .state = 0, .system_clk = 0, .baudrate = 0 }; +struct uart_cmsdk_dev_t UART1_CMSDK_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 UART1_CMSDK_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 UART2_CMSDK_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 UART2_CMSDK_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 UART3_CMSDK_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 UART3_CMSDK_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 UART4_CMSDK_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 UART4_CMSDK_DEV_NS = { &(UART4_CMSDK_DEV_CFG_NS), &(UART4_CMSDK_DEV_DATA_NS) }; +#endif + +#ifdef UART5_CMSDK_S +static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_S = { .base = UART5_BASE_S, + .default_baudrate = DEFAULT_UART_BAUDRATE }; +static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_S = { .state = 0, .system_clk = 0, .baudrate = 0 }; +struct uart_cmsdk_dev_t UART5_CMSDK_DEV_S = { &(UART5_CMSDK_DEV_CFG_S), &(UART5_CMSDK_DEV_DATA_S) }; +#endif +#ifdef UART5_CMSDK_NS +static const struct uart_cmsdk_dev_cfg_t UART5_CMSDK_DEV_CFG_NS = { .base = UART5_BASE_NS, + .default_baudrate = DEFAULT_UART_BAUDRATE }; +static struct uart_cmsdk_dev_data_t UART5_CMSDK_DEV_DATA_NS = { .state = 0, .system_clk = 0, .baudrate = 0 }; +struct uart_cmsdk_dev_t UART5_CMSDK_DEV_NS = { &(UART5_CMSDK_DEV_CFG_NS), &(UART5_CMSDK_DEV_DATA_NS) }; +#endif + +/* SSE-300 PPC driver structures */ +#ifdef PPC_SSE300_MAIN0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN0_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN0 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN0_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_MAIN0_DEV_S = { &PPC_SSE300_MAIN0_CFG_S, &PPC_SSE300_MAIN0_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP0_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP0 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP0_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP0_DEV_S = { &PPC_SSE300_MAIN_EXP0_CFG_S, &PPC_SSE300_MAIN_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP1_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP1 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP1_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP1_DEV_S = { &PPC_SSE300_MAIN_EXP1_CFG_S, &PPC_SSE300_MAIN_EXP1_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP2_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP2_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP2 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP2_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP2_DEV_S = { &PPC_SSE300_MAIN_EXP2_CFG_S, &PPC_SSE300_MAIN_EXP2_DATA_S }; +#endif + +#ifdef PPC_SSE300_MAIN_EXP3_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_MAIN_EXP3_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_MAIN_EXP3 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_MAIN_EXP3_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_MAIN_EXP3_DEV_S = { &PPC_SSE300_MAIN_EXP3_CFG_S, &PPC_SSE300_MAIN_EXP3_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH0_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH0 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH0_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH0_DEV_S = { &PPC_SSE300_PERIPH0_CFG_S, &PPC_SSE300_PERIPH0_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH1_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH1 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH1_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH1_DEV_S = { &PPC_SSE300_PERIPH1_CFG_S, &PPC_SSE300_PERIPH1_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP0_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP0_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP0 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP0_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP0_DEV_S = { &PPC_SSE300_PERIPH_EXP0_CFG_S, &PPC_SSE300_PERIPH_EXP0_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP1_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP1_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP1 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP1_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP1_DEV_S = { &PPC_SSE300_PERIPH_EXP1_CFG_S, &PPC_SSE300_PERIPH_EXP1_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP2_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP2_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP2 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP2_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP2_DEV_S = { &PPC_SSE300_PERIPH_EXP2_CFG_S, &PPC_SSE300_PERIPH_EXP2_DATA_S }; +#endif + +#ifdef PPC_SSE300_PERIPH_EXP3_S +static struct ppc_sse300_dev_cfg_t PPC_SSE300_PERIPH_EXP3_CFG_S = { .sacfg_base = SSE300_SACFG_BASE_S, + .nsacfg_base = SSE300_NSACFG_BASE_NS, + .ppc_name = PPC_SSE300_PERIPH_EXP3 }; +static struct ppc_sse300_dev_data_t PPC_SSE300_PERIPH_EXP3_DATA_S = { + .sacfg_ns_ppc = 0, .sacfg_sp_ppc = 0, .nsacfg_nsp_ppc = 0, .int_bit_mask = 0, .is_initialized = false +}; +struct ppc_sse300_dev_t PPC_SSE300_PERIPH_EXP3_DEV_S = { &PPC_SSE300_PERIPH_EXP3_CFG_S, &PPC_SSE300_PERIPH_EXP3_DATA_S }; +#endif + +/* System counters */ +#ifdef SYSCOUNTER_CNTRL_ARMV8_M_S + +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT > SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT > SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT > SYSCOUNTER_ARMV8_M_SCALE_VAL_INT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT is invalid. +#endif +#if SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT > SYSCOUNTER_ARMV8_M_SCALE_VAL_FRACT_MAX +#error SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT is invalid. +#endif + +static const struct syscounter_armv8_m_cntrl_dev_cfg_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_CNTRL_BASE_S, + .scale0.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT, + .scale0.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT, + .scale1.integer = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT, + .scale1.fixed_point_fraction = SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT +}; +static struct syscounter_armv8_m_cntrl_dev_data_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S = { .is_initialized = false }; +struct syscounter_armv8_m_cntrl_dev_t SYSCOUNTER_CNTRL_ARMV8_M_DEV_S = { &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_S), + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_DATA_S) }; +#endif + +#ifdef SYSCOUNTER_READ_ARMV8_M_S +static const struct syscounter_armv8_m_read_dev_cfg_t SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S = { + .base = SYSCNTR_READ_BASE_S, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_S = { + &(SYSCOUNTER_READ_ARMV8_M_DEV_CFG_S), +}; +#endif +#ifdef SYSCOUNTER_READ_ARMV8_M_NS +static const struct syscounter_armv8_m_read_dev_cfg_t SYSCOUNTER_READ_ARMV8_M_DEV_CFG_NS = { + .base = SYSCNTR_READ_BASE_NS, +}; +struct syscounter_armv8_m_read_dev_t SYSCOUNTER_READ_ARMV8_M_DEV_NS = { + &(SYSCOUNTER_CNTRL_ARMV8_M_DEV_CFG_NS), +}; +#endif + +/* System timers */ +#ifdef SYSTIMER0_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER0_ARMV8_M_DEV_CFG_S +#ifdef TEST_NS_SLIH_IRQ + TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT") +#elif defined(TEST_NS_FLIH_IRQ) + TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT") +#endif + = { .base = SYSTIMER0_ARMV8_M_BASE_S, .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER0_ARMV8_M_DEV_DATA_S +#ifdef TEST_NS_SLIH_IRQ + TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT") +#elif defined(TEST_NS_FLIH_IRQ) + TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT") +#endif + = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S +#ifdef TEST_NS_SLIH_IRQ + TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT") +#elif defined(TEST_NS_FLIH_IRQ) + TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT") +#endif + = { &(SYSTIMER0_ARMV8_M_DEV_CFG_S), &(SYSTIMER0_ARMV8_M_DEV_DATA_S) }; +#endif + +#ifdef SYSTIMER0_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER0_ARMV8_M_DEV_CFG_NS = { .base = SYSTIMER0_ARMV8_M_BASE_NS, + .default_freq_hz = + SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER0_ARMV8_M_DEV_DATA_NS = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_NS = { &(SYSTIMER0_ARMV8_M_DEV_CFG_NS), &(SYSTIMER0_ARMV8_M_DEV_DATA_NS) }; +#endif + +#ifdef SYSTIMER1_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER1_ARMV8_M_DEV_CFG_S = { .base = SYSTIMER1_ARMV8_M_BASE_S, + .default_freq_hz = + SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER1_ARMV8_M_DEV_DATA_S = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_S = { &(SYSTIMER1_ARMV8_M_DEV_CFG_S), &(SYSTIMER1_ARMV8_M_DEV_DATA_S) }; +#endif + +#ifdef SYSTIMER1_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER1_ARMV8_M_DEV_CFG_NS = { .base = SYSTIMER1_ARMV8_M_BASE_NS, + .default_freq_hz = + SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER1_ARMV8_M_DEV_DATA_NS = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS = { &(SYSTIMER1_ARMV8_M_DEV_CFG_NS), &(SYSTIMER1_ARMV8_M_DEV_DATA_NS) }; +#endif + +#ifdef SYSTIMER2_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER2_ARMV8_M_DEV_CFG_S = { .base = SYSTIMER2_ARMV8_M_BASE_S, + .default_freq_hz = + SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER2_ARMV8_M_DEV_DATA_S = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_S = { &(SYSTIMER2_ARMV8_M_DEV_CFG_S), &(SYSTIMER2_ARMV8_M_DEV_DATA_S) }; +#endif + +#ifdef SYSTIMER2_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER2_ARMV8_M_DEV_CFG_NS = { .base = SYSTIMER2_ARMV8_M_BASE_NS, + .default_freq_hz = + SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER2_ARMV8_M_DEV_DATA_NS = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER2_ARMV8_M_DEV_NS = { &(SYSTIMER2_ARMV8_M_DEV_CFG_NS), &(SYSTIMER2_ARMV8_M_DEV_DATA_NS) }; +#endif + +#ifdef SYSTIMER3_ARMV8_M_S +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER3_ARMV8_M_DEV_CFG_S = { .base = SYSTIMER3_ARMV8_M_BASE_S, + .default_freq_hz = + SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER3_ARMV8_M_DEV_DATA_S = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_S = { &(SYSTIMER3_ARMV8_M_DEV_CFG_S), &(SYSTIMER3_ARMV8_M_DEV_DATA_S) }; +#endif + +#ifdef SYSTIMER3_ARMV8_M_NS +static const struct systimer_armv8_m_dev_cfg_t SYSTIMER3_ARMV8_M_DEV_CFG_NS = { .base = SYSTIMER3_ARMV8_M_BASE_NS, + .default_freq_hz = + SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ }; +static struct systimer_armv8_m_dev_data_t SYSTIMER3_ARMV8_M_DEV_DATA_NS = { .is_initialized = false }; +struct systimer_armv8_m_dev_t SYSTIMER3_ARMV8_M_DEV_NS = { &(SYSTIMER3_ARMV8_M_DEV_CFG_NS), &(SYSTIMER3_ARMV8_M_DEV_DATA_NS) }; +#endif + +/* System Watchdogs */ +#ifdef SYSWDOG_ARMV8_M_S +static const struct syswdog_armv8_m_dev_cfg_t SYSWDOG_ARMV8_M_DEV_CFG_S = { .base = SYSWDOG_ARMV8_M_CNTRL_BASE_S }; +struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_S = { &(SYSWDOG_ARMV8_M_DEV_CFG_S) }; +#endif + +#ifdef SYSWDOG_ARMV8_M_NS +static const struct syswdog_armv8_m_dev_cfg_t SYSWDOG_ARMV8_M_DEV_CFG_NS = { .base = SYSWDOG_ARMV8_M_CNTRL_BASE_NS }; +struct syswdog_armv8_m_dev_t SYSWDOG_ARMV8_M_DEV_NS = { &(SYSWDOG_ARMV8_M_DEV_CFG_NS) }; +#endif + +/* ARM MPC SSE 300 driver structures */ +#ifdef MPC_SRAM_S +static const struct mpc_sie_dev_cfg_t MPC_SRAM_DEV_CFG_S = { .base = MPC_SRAM_BASE_S }; +static struct mpc_sie_dev_data_t MPC_SRAM_DEV_DATA_S = { .range_list = 0, .nbr_of_ranges = 0, .is_initialized = false }; +struct mpc_sie_dev_t MPC_SRAM_DEV_S = { &(MPC_SRAM_DEV_CFG_S), &(MPC_SRAM_DEV_DATA_S) }; +#endif + +#ifdef MPC_QSPI_S +static const struct mpc_sie_dev_cfg_t MPC_QSPI_DEV_CFG_S = { .base = MPC_QSPI_BASE_S }; +static struct mpc_sie_dev_data_t MPC_QSPI_DEV_DATA_S = { .range_list = 0, .nbr_of_ranges = 0, .is_initialized = false }; +struct mpc_sie_dev_t MPC_QSPI_DEV_S = { &(MPC_QSPI_DEV_CFG_S), &(MPC_QSPI_DEV_DATA_S) }; +#endif + +#ifdef MPC_DDR4_S +static const struct mpc_sie_dev_cfg_t MPC_DDR4_DEV_CFG_S = { .base = MPC_DDR4_BASE_S }; +static struct mpc_sie_dev_data_t MPC_DDR4_DEV_DATA_S = { .range_list = 0, .nbr_of_ranges = 0, .is_initialized = false }; +struct mpc_sie_dev_t MPC_DDR4_DEV_S = { &(MPC_DDR4_DEV_CFG_S), &(MPC_DDR4_DEV_DATA_S) }; +#endif + +#ifdef MPC_ISRAM0_S +static const struct mpc_sie_dev_cfg_t MPC_ISRAM0_DEV_CFG_S = { .base = MPC_ISRAM0_BASE_S }; +static struct mpc_sie_dev_data_t MPC_ISRAM0_DEV_DATA_S = { .range_list = 0, .nbr_of_ranges = 0, .is_initialized = false }; +struct mpc_sie_dev_t MPC_ISRAM0_DEV_S = { &(MPC_ISRAM0_DEV_CFG_S), &(MPC_ISRAM0_DEV_DATA_S) }; +#endif + +#ifdef MPC_ISRAM1_S +static const struct mpc_sie_dev_cfg_t MPC_ISRAM1_DEV_CFG_S = { .base = MPC_ISRAM1_BASE_S }; +static struct mpc_sie_dev_data_t MPC_ISRAM1_DEV_DATA_S = { .range_list = 0, .nbr_of_ranges = 0, .is_initialized = false }; +struct mpc_sie_dev_t MPC_ISRAM1_DEV_S = { &(MPC_ISRAM1_DEV_CFG_S), &(MPC_ISRAM1_DEV_DATA_S) }; +#endif + +#ifdef MPS3_IO_S +static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_S = { .base = FPGA_IO_BASE_S }; +struct arm_mps3_io_dev_t MPS3_IO_DEV_S = { .cfg = &(MPS3_IO_DEV_CFG_S) }; +#endif + +#ifdef MPS3_IO_NS +static struct arm_mps3_io_dev_cfg_t MPS3_IO_DEV_CFG_NS = { .base = FPGA_IO_BASE_NS }; +struct arm_mps3_io_dev_t MPS3_IO_DEV_NS = { .cfg = &(MPS3_IO_DEV_CFG_NS) }; +#endif diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/source/startup_an552.c b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/startup_an552.c new file mode 100755 index 00000000000000..8d49283e275715 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/startup_an552.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.9.0 startup_ARMCM55.c + * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +extern uint32_t __STACK_SEAL; +#endif + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ + void __WEAK handler_name(void) __NO_RETURN; \ + void handler_name(void) \ + { \ + while (1) \ + ; \ + } + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler) +DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler) +DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const VECTOR_TABLE_Type __VECTOR_TABLE[]; +const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { + (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_REQ_Handler, /* 0: Non-Secure Watchdog Reset Request Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TFM_TIMER0_IRQ_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_AON_Handler, /* 27: TIMER 3 AON Handler */ + CPU0_CTI_0_Handler, /* 28: CPU0 CTI IRQ 0 Handler */ + CPU0_CTI_1_Handler, /* 29: CPU0 CTI IRQ 1 Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + __disable_irq(); +#endif + __set_PSP((uint32_t)(&__INITIAL_SP)); + + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + __set_PSPLIM((uint32_t)(&__STACK_LIMIT)); + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + __TZ_set_STACKSEAL_S((uint32_t *) (&__STACK_SEAL)); +#endif + + SystemInit(); /* CMSIS System Initialization */ + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/device/source/system_core_init.c b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/system_core_init.c new file mode 100755 index 00000000000000..6e3aae93112895 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/device/source/system_core_init.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009-2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.9.0 system_ARMCM55.c + * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c + */ + +#include "cmsis.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define XTAL (32000000UL) +#define SYSTEM_CLOCK (XTAL) +#define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ +extern const VECTOR_TABLE_Type __VECTOR_TABLE[496]; + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit(void) +{ +#if defined(__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE[0]); +#endif + +#if (defined(__FPU_USED) && (__FPU_USED == 1U)) || (defined(__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U)) + SCB->CPACR |= ((3U << 10U * 2U) | /* enable CP10 Full Access */ + (3U << 11U * 2U)); /* enable CP11 Full Access */ + + /* Set low-power state for PDEPU */ + /* 0b00 | ON, PDEPU is not in low-power state */ + /* 0b01 | ON, but the clock is off */ + /* 0b10 | RET(ention) */ + /* 0b11 | OFF */ + + /* Clear ELPSTATE, value is 0b11 on Cold reset */ + PWRMODCTL->CPDLPSTATE &= ~(PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk); + + /* Favor best FP/MVE performance by default, avoid EPU switch-ON delays */ + /* PDEPU ON, Clock OFF */ + PWRMODCTL->CPDLPSTATE |= 0x1 << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos; +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + + /* Enable Loop and branch info cache */ + SCB->CCR |= SCB_CCR_LOB_Msk; + __DSB(); + __ISB(); + + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/faults.c b/examples/platform/openiotsdk/tf-m/targets/an552/faults.c new file mode 100755 index 00000000000000..8e8e9eab5278bd --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/faults.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "Driver_MPC.h" +#include "cmsis.h" +#include "exception_info.h" +#include "target_cfg.h" +#include "utilities.h" + +void C_MPC_Handler(void) +{ + /* Clear MPC interrupt flag and pending MPC IRQ */ + mpc_clear_irq(); + NVIC_ClearPendingIRQ(MPC_IRQn); + + /* Print fault message and block execution */ + ERROR_MSG("Platform Exception: MPC fault!!!"); + + tfm_core_panic(); +} + +__attribute__((naked)) void MPC_Handler(void) +{ + EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + + __ASM volatile("BL C_MPC_Handler \n" + "B . \n"); +} + +void C_PPC_Handler(void) +{ + /* Clear PPC interrupt flag and pending PPC IRQ */ + ppc_clear_irq(); + NVIC_ClearPendingIRQ(PPC_IRQn); + + /* Print fault message*/ + ERROR_MSG("Platform Exception: PPC fault!!!"); + + tfm_core_panic(); +} + +__attribute__((naked)) void PPC_Handler(void) +{ + EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + + __ASM volatile("BL C_PPC_Handler \n" + "B . \n"); +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/mmio_defs.h b/examples/platform/openiotsdk/tf-m/targets/an552/mmio_defs.h new file mode 100755 index 00000000000000..070764d902d313 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/mmio_defs.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __MMIO_DEFS_H__ +#define __MMIO_DEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tfm_peripherals_def.h" +#include + +/* Boundary handle binding macros. */ +#define HANDLE_ATTR_PRIV_POS 1U +#define HANDLE_ATTR_PRIV_MASK (0x1UL << HANDLE_ATTR_PRIV_POS) +#define HANDLE_ATTR_NS_POS 0U +#define HANDLE_ATTR_NS_MASK (0x1UL << HANDLE_ATTR_NS_POS) + +/* Allowed named MMIO of this platform */ +const uintptr_t partition_named_mmio_list[] = { (uintptr_t) TFM_PERIPHERAL_GPIO0, + (uintptr_t) TFM_PERIPHERAL_GPIO1, + (uintptr_t) TFM_PERIPHERAL_GPIO2, + (uintptr_t) TFM_PERIPHERAL_GPIO3, + (uintptr_t) TFM_PERIPHERAL_FMC_CMSDK_GPIO0, + (uintptr_t) TFM_PERIPHERAL_FMC_CMSDK_GPIO1, + (uintptr_t) TFM_PERIPHERAL_FMC_CMSDK_GPIO2, + (uintptr_t) TFM_PERIPHERAL_FMC_CMSDK_GPIO3, + (uintptr_t) TFM_PERIPHERAL_ETHERNET, + (uintptr_t) TFM_PERIPHERAL_USB, + (uintptr_t) TFM_PERIPHERAL_TIMER0, + (uintptr_t) TFM_PERIPHERAL_TIMER1, + (uintptr_t) TFM_PERIPHERAL_TIMER2, + (uintptr_t) TFM_PERIPHERAL_TIMER3, + (uintptr_t) TFM_PERIPHERAL_SLOWCLK, + (uintptr_t) TFM_PERIPHERAL_TOUCH_I2C, + (uintptr_t) TFM_PERIPHERAL_AUDIO_I2C, + (uintptr_t) TFM_PERIPHERAL_ADC_SPI, + (uintptr_t) TFM_PERIPHERAL_SHIELD0_SPI, + (uintptr_t) TFM_PERIPHERAL_SHIELD1_SPI, + (uintptr_t) TFM_PERIPHERAL_SHIELD0_I2C, + (uintptr_t) TFM_PERIPHERAL_SHIELD1_I2C, + (uintptr_t) TFM_PERIPHERAL_DDR4_EEPROM_I2C, + (uintptr_t) TFM_PERIPHERAL_FPGA_SCC, + (uintptr_t) TFM_PERIPHERAL_FPGA_I2S, + (uintptr_t) TFM_PERIPHERAL_FPGA_IO, + (uintptr_t) TFM_PERIPHERAL_STD_UART, + (uintptr_t) TFM_PERIPHERAL_UART1, + (uintptr_t) TFM_PERIPHERAL_UART2, + (uintptr_t) TFM_PERIPHERAL_UART3, + (uintptr_t) TFM_PERIPHERAL_UART4, + (uintptr_t) TFM_PERIPHERAL_UART5, + (uintptr_t) TFM_PERIPHERAL_CLCD, + (uintptr_t) TFM_PERIPHERAL_RTC }; + +/* + * Platform AN552 only has named MMIO. + * If the platform has numbered MMIO, define them in another list. + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MMIO_DEFS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.c new file mode 100755 index 00000000000000..c096b6333e8beb --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2021-2022 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 "emulated_flash_drv.h" +#include +#include +#include +#include + +static int32_t is_range_valid(struct emulated_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 emulated_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 emulated_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_secure_alias_needed(uint32_t addr) +{ + int32_t rc = -1; + + /* Only have to check it if the object is building for secure side */ +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + cmse_address_info_t address_info; + /* Check if address can be accessed from non-secure */ + address_info = cmse_TTA((void *) addr); + /* We only care about the security of the address here */ + if (address_info.flags.nonsecure_read_ok) + { + rc = 0; + } + else + { + rc = 1; + } +#else + rc = 0; +#endif + 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] != EMULATED_FLASH_DRV_ERASE_VALUE) + { + rc = -1; + break; + } + } + + return rc; +} + +enum emulated_flash_error_t emulated_flash_read_data(struct emulated_flash_dev_t * dev, uint32_t addr, void * data, uint32_t cnt) +{ + uint32_t start_addr = 0; + int32_t rc = 0; + + /* Check flash memory boundaries */ + rc = is_range_valid(dev, addr + cnt); + if (rc != 0) + { + return EMULATED_FLASH_ERR_INVALID_PARAM; + } + + /* Check which alias(S or NS) should be used to access the data */ + rc = is_secure_alias_needed(addr + dev->memory_base_ns); + if (rc == 1) + { + start_addr = dev->memory_base_s + addr; + } + else if (rc == 0) + { + start_addr = dev->memory_base_ns + addr; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy(data, (void *) start_addr, cnt); + return EMULATED_FLASH_ERR_NONE; +} + +enum emulated_flash_error_t emulated_flash_program_data(struct emulated_flash_dev_t * dev, uint32_t addr, const void * data, + uint32_t cnt) +{ + uint32_t start_addr = 0; + int32_t rc = 0; + + /* Check flash memory boundaries and alignment with minimal write size */ + rc = is_range_valid(dev, addr + cnt); + rc |= is_write_aligned(dev, addr); + rc |= is_write_aligned(dev, cnt); + if (rc != 0) + { + return EMULATED_FLASH_ERR_INVALID_PARAM; + } + + /* Check which alias(S or NS) should be used to access the data */ + rc = is_secure_alias_needed(addr + dev->memory_base_ns); + if (rc == 1) + { + start_addr = dev->memory_base_s + addr; + } + else if (rc == 0) + { + start_addr = dev->memory_base_ns + addr; + } + + /* 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 EMULATED_FLASH_NOT_READY; + } + + /* Flash interface just emulated over SRAM, use memcpy */ + memcpy((void *) start_addr, data, cnt); + return EMULATED_FLASH_ERR_NONE; +} + +enum emulated_flash_error_t emulated_flash_erase_sector(struct emulated_flash_dev_t * dev, uint32_t addr) +{ + uint32_t start_addr = 0; + int32_t rc = 0; + + rc = is_range_valid(dev, addr); + rc |= is_sector_aligned(dev, addr); + if (rc != 0) + { + return EMULATED_FLASH_ERR_INVALID_PARAM; + } + + /* Check which alias(S or NS) should be used to access the data */ + rc = is_secure_alias_needed(addr + dev->memory_base_ns); + if (rc == 1) + { + start_addr = dev->memory_base_s + addr; + } + else if (rc == 0) + { + start_addr = dev->memory_base_ns + addr; + } + + /* Flash interface just emulated over SRAM, use memset */ + memset((void *) start_addr, dev->data->erased_value, dev->data->sector_size); + return EMULATED_FLASH_ERR_NONE; +} + +void emulated_flash_erase_chip(struct emulated_flash_dev_t * dev) +{ + uint32_t i; + uint32_t addr = 0; + int32_t rc = 0; + + /* Only check 1 byte, as the whole memory should have the same security */ + rc = is_secure_alias_needed(dev->memory_base_ns); + if (rc == 1) + { + addr = dev->memory_base_s; + } + else if (rc == 0) + { + addr = dev->memory_base_ns; + } + + for (i = 0; i < dev->data->sector_count; i++) + { + /* Flash interface just emulated over SRAM, use memset */ + memset((void *) addr, dev->data->erased_value, dev->data->sector_size); + + addr += dev->data->sector_size; + } +} + +ARM_FLASH_INFO * emulated_flash_get_info(struct emulated_flash_dev_t * dev) +{ + return dev->data; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.h new file mode 100755 index 00000000000000..fc84f23487a6a1 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/emulated_flash_drv.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021-2022 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 __EMULATED_FLASH_DRV_H__ +#define __EMULATED_FLASH_DRV_H__ + +#include +#include + +/* This include is neceasary because of the ARM_FLASH_INFO structure. Since this driver is not used + * as a standalone driver, only with tf-m, we can include it here to prevent code duplication. + */ +#include "Driver_Flash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EMULATED_FLASH_DRV_ERASE_VALUE 0xFF + +/** +\brief Flash Sector information +*/ +typedef struct _emulated_flash_sector_t +{ + uint32_t start; ///< Sector Start address + uint32_t end; ///< Sector End address (start+size-1) +} const emulated_flash_sector_t; + +/* + * Emulated flash device structure + * + * This driver just emulates a flash interface and behaviour on top of any + * type of memory. + */ +struct emulated_flash_dev_t +{ + const uint32_t memory_base_s; /*!< FLASH memory base address, secure alias */ + const uint32_t memory_base_ns; /*!< FLASH memory base address, non-secure alias */ + ARM_FLASH_INFO * data; /*!< FLASH data */ +}; + +enum emulated_flash_error_t +{ + EMULATED_FLASH_ERR_NONE = 0, /*!< No error */ + EMULATED_FLASH_ERR_INVALID_PARAM, /*!< Invalid parameter error */ + EMULATED_FLASH_NOT_READY, /*!< Not ready error */ +}; + +/** + * \brief Reads data from emulated flash in a blocking call + * + * \param[in] dev Emulated flash device struct \ref emulated_flash_dev_t + * \param[in] addr Address to read data from the flash + * \param[out] data Pointer to store data read from the flash + * \param[in] cnt Number of data items to read + * + * \return Returns error code as specified in \ref emulated_flash_error_t + * + * \note This function doesn't check if dev is NULL. + * \note The whole region needs to be set to the same security to use this + * function. + */ +enum emulated_flash_error_t emulated_flash_read_data(struct emulated_flash_dev_t * dev, uint32_t addr, void * data, uint32_t cnt); + +/** + * \brief Writes data to the flash in a blocking call + * + * \param[in] dev Emulated flash device struct \ref emulated_flash_dev_t + * \param[in] addr Address to write data to the flash + * \param[in] data Pointer to the data to be written + * \param[in] cnt Number of bytes to write + * + * \return Returns error code as specified in \ref emulated_flash_error_t + * + * \note Flash area needs to be pre-erased before writing to it + * \note Addr is expected to be within the [0x0 - Flash size] range + * \note For better performance, this function doesn't check if dev is NULL + * \note The whole region needs to be set to the same security to use this + * function. + */ +enum emulated_flash_error_t emulated_flash_program_data(struct emulated_flash_dev_t * dev, uint32_t addr, const void * data, + uint32_t cnt); + +/** + * \brief Erases a sector of the flash + * + * \param[in] dev Emulated flash device struct \ref emulated_flash_dev_t + * \param[in] addr Address of the sector to erase + * + * \return Returns error code as specified in \ref emulated_flash_error_t + * + * \note For better performance, this function doesn't check if dev is NULL + * \note Addr is expected to be within the [0x0 - Flash size] range + * \note The whole sector needs to be set to the same security to use this + * function. + */ +enum emulated_flash_error_t emulated_flash_erase_sector(struct emulated_flash_dev_t * dev, uint32_t addr); + +/** + * \brief Erases the whole flash + * + * \param[in] dev Emulated flash device struct \ref emulated_flash_dev_t + * + * \note For better performance, this function doesn't check if dev is NULL + * \note The whole memory needs to be set to the same security to use this + * function. + */ +void emulated_flash_erase_chip(struct emulated_flash_dev_t * dev); + +/** + * \brief Returns the information of the emulated flash + * + * \param[in] dev Emulated flash device struct \ref emulated_flash_dev_t + * + * \return Returns the info \ref ARM_FLASH_INFO + * + * \note For better performance, this function doesn't check if dev is NULL + * \note The \ref ARM_FLASH_INFO is coming from the CMSIS Flash driver. This + * native driver is only used together with CMSIS, so instead of + * duplicating the structure, it is used here as well. + */ +ARM_FLASH_INFO * emulated_flash_get_info(struct emulated_flash_dev_t * dev); + +#ifdef __cplusplus +} +#endif +#endif /* __EMULATED_FLASH_DRV_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.c new file mode 100644 index 00000000000000..803591f6db6eae --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.c @@ -0,0 +1,848 @@ +/* + * Copyright (c) 2016-2020 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mpc_sie_drv.h" + +#include +#include + +#include "cmsis_compiler.h" + +/* Values for hardware version in PIDR0 reg */ +#define SIE200 0x60 +#define SIE300 0x65 + +#define MPC_SIE_BLK_CFG_OFFSET 5U + +/* Defines with numbering (eg: SIE300) are only relevant to the given SIE + * version. Defines without the numbering are applicable to all SIE versions. + */ + +/* CTRL register bit indexes */ +#define MPC_SIE200_CTRL_SEC_RESP \ + (1UL << 4UL) /* MPC fault triggers a \ + * bus error \ + */ +#define MPC_SIE300_CTRL_GATE_REQ \ + (1UL << 6UL) /* Request for gating \ + * incoming transfers \ + */ +#define MPC_SIE300_CTRL_GATE_ACK \ + (1UL << 7UL) /* Acknowledge for gating \ + * incoming transfers \ + */ +#define MPC_SIE_CTRL_AUTOINCREMENT (1UL << 8UL) /* BLK_IDX auto increment */ +#define MPC_SIE300_CTRL_SEC_RESP \ + (1UL << 16UL) /* Response type when SW \ + * asks to gate the transfer \ + */ +#define MPC_SIE300_CTRL_GATE_PRESENT (1UL << 23UL) /* Gating feature present */ +#define MPC_SIE_CTRL_SEC_LOCK_DOWN (1UL << 31UL) /* MPC Security lock down */ + +/* PIDR register bit masks */ +#define MPC_PIDR0_SIE_VERSION_MASK ((1UL << 8UL) - 1UL) + +/* ARM MPC interrupt */ +#define MPC_SIE_INT_BIT (1UL) + +/* Error code returned by the internal driver functions */ +enum mpc_sie_intern_error_t +{ + MPC_SIE_INTERN_ERR_NONE = MPC_SIE_ERR_NONE, + MPC_SIE_INTERN_ERR_NOT_IN_RANGE = MPC_SIE_ERR_NOT_IN_RANGE, + MPC_SIE_INTERN_ERR_NOT_ALIGNED = MPC_SIE_ERR_NOT_ALIGNED, + MPC_SIE_INTERN_ERR_INVALID_RANGE = MPC_SIE_ERR_INVALID_RANGE, + MPC_INTERN_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE = MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, + /* Calculated block index + * is higher than the maximum allowed by the MPC. It should never + * happen unless the controlled ranges of the MPC are misconfigured + * in the driver or if the IP has not enough LUTs to cover the + * range, due to wrong reported block size for example. + */ + MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH = -1, + +}; + +/* ARM MPC memory mapped register access structure */ +struct mpc_sie_reg_map_t +{ + volatile uint32_t ctrl; /* (R/W) MPC Control */ + volatile uint32_t reserved[3]; /* Reserved */ + volatile uint32_t blk_max; /* (R/ ) Maximum value of block based index */ + volatile uint32_t blk_cfg; /* (R/ ) Block configuration */ + volatile uint32_t blk_idx; /* (R/W) Index value for accessing block + * based look up table + */ + volatile uint32_t blk_lutn; /* (R/W) Block based gating + * Look Up Table (LUT) + */ + volatile uint32_t int_stat; /* (R/ ) Interrupt state */ + volatile uint32_t int_clear; /* ( /W) Interrupt clear */ + volatile uint32_t int_en; /* (R/W) Interrupt enable */ + volatile uint32_t int_info1; /* (R/ ) Interrupt information 1 */ + volatile uint32_t int_info2; /* (R/ ) Interrupt information 2 */ + volatile uint32_t int_set; /* ( /W) Interrupt set. Debug purpose only */ + volatile uint32_t reserved2[998]; /* Reserved */ + volatile uint32_t pidr4; /* (R/ ) Peripheral ID 4 */ + volatile uint32_t pidr5; /* (R/ ) Peripheral ID 5 */ + volatile uint32_t pidr6; /* (R/ ) Peripheral ID 6 */ + volatile uint32_t pidr7; /* (R/ ) Peripheral ID 7 */ + volatile uint32_t pidr0; /* (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* (R/ ) Component ID 3 */ +}; + +/* + * Checks if the address is controlled by the MPC and returns + * the range index in which it is contained. + * + * \param[in] dev MPC device to initialize \ref mpc_sie_dev_t + * \param[in] addr Address to check if it is controlled by MPC. + * \param[out] addr_range Range index in which it is contained. + * + * \return True if the base is controller by the range list, false otherwise. + */ +static uint32_t is_ctrl_by_range_list(struct mpc_sie_dev_t * dev, uint32_t addr, const struct mpc_sie_memory_range_t ** addr_range) +{ + uint32_t i; + const struct mpc_sie_memory_range_t * range; + + for (i = 0; i < dev->data->nbr_of_ranges; i++) + { + range = dev->data->range_list[i]; + if (addr >= range->base && addr <= range->limit) + { + *addr_range = range; + return 1; + } + } + return 0; +} + +/* + * Gets the masks selecting the bits in the LUT of the MPC corresponding + * to the base address (included) up to the limit address (included) + * + * \param[in] mpc_dev The MPC device. + * \param[in] base Address in a range controlled by this MPC + * (included), aligned on block size. + * \param[in] limit Address in a range controlled by this MPC + * (included), aligned on block size. + * \param[out] range Memory range in which the base address and + * limit are. + * \param[out] first_word_idx Index of the first touched word in the LUT. + * \param[out] nr_words Number of words used in the LUT. If 1, only + * first_word_mask is valid and limit_word_mask + * must not be used. + * \param[out] first_word_mask First word mask in the LUT will be stored here. + * \param[out] limit_word_mask Limit word mask in the LUT will be stored here. + * + * \return Returns error code as specified in \ref mpc_sie_intern_error_t + */ +static enum mpc_sie_intern_error_t get_lut_masks(struct mpc_sie_dev_t * dev, const uint32_t base, const uint32_t limit, + const struct mpc_sie_memory_range_t ** range, uint32_t * first_word_idx, + uint32_t * nr_words, uint32_t * first_word_mask, uint32_t * limit_word_mask) +{ + const struct mpc_sie_memory_range_t * base_range; + uint32_t block_size; + uint32_t base_block_idx; + uint32_t base_word_idx; + uint32_t blk_max; + const struct mpc_sie_memory_range_t * limit_range; + uint32_t limit_block_idx; + uint32_t limit_word_idx; + uint32_t mask; + uint32_t norm_base; + uint32_t norm_limit; + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + /* + * Check that the addresses are within the controlled regions + * of this MPC + */ + if (!is_ctrl_by_range_list(dev, base, &base_range) || !is_ctrl_by_range_list(dev, limit, &limit_range)) + { + return MPC_SIE_INTERN_ERR_NOT_IN_RANGE; + } + + /* Base and limit should be part of the same range */ + if (base_range != limit_range) + { + return MPC_SIE_INTERN_ERR_INVALID_RANGE; + } + *range = base_range; + + block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + /* Base and limit+1 addresses must be aligned on the MPC block size */ + if (base % block_size || (limit + 1) % block_size) + { + return MPC_SIE_INTERN_ERR_NOT_ALIGNED; + } + + /* + * Get a normalized address that is an offset from the beginning + * of the lowest range controlled by the MPC + */ + norm_base = (base - base_range->base) + base_range->range_offset; + norm_limit = (limit - base_range->base) + base_range->range_offset; + + /* + * Calculate block index and to which 32 bits word it belongs + */ + limit_block_idx = norm_limit / block_size; + limit_word_idx = limit_block_idx / 32; + + base_block_idx = norm_base / block_size; + base_word_idx = base_block_idx / 32; + + if (base_block_idx > limit_block_idx) + { + return MPC_SIE_INTERN_ERR_INVALID_RANGE; + } + + /* Transmit the information to the caller */ + *nr_words = limit_word_idx - base_word_idx + 1; + *first_word_idx = base_word_idx; + + /* Limit to the highest block that can be configured */ + blk_max = p_mpc->blk_max; + + if ((limit_word_idx > blk_max) || (base_word_idx > blk_max)) + { + return MPC_SIE_INTERN_ERR_BLK_IDX_TOO_HIGH; + } + + /* + * Create the mask for the first word to only select the limit N bits + */ + *first_word_mask = ~((1 << (base_block_idx % 32)) - 1); + + /* + * Create the mask for the limit word to select only the first M bits. + */ + *limit_word_mask = (1 << ((limit_block_idx + 1) % 32)) - 1; + /* + * If limit_word_mask is 0, it means that the limit touched block index is + * the limit in its word, so the limit word mask has all its bits selected + */ + if (*limit_word_mask == 0) + { + *limit_word_mask = 0xFFFFFFFF; + } + + /* + * If the blocks to configure are all packed in one word, only + * touch this word. + * Code using the computed masks should test if this mask + * is non-zero, and if so, only use this one instead of the limit_word_mask + * and first_word_mask. + * As the only bits that are the same in both masks are the 1 that we want + * to select, just use XOR to extract them. + */ + if (base_word_idx == limit_word_idx) + { + mask = ~(*first_word_mask ^ *limit_word_mask); + *first_word_mask = mask; + *limit_word_mask = mask; + } + + return MPC_SIE_INTERN_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t * dev, const struct mpc_sie_memory_range_t ** range_list, + uint8_t nbr_of_ranges) +{ + if ((range_list == NULL) || (nbr_of_ranges == 0)) + { + return MPC_SIE_INVALID_ARG; + } + + dev->data->sie_version = get_sie_version(dev); + + if ((dev->data->sie_version != SIE200) && (dev->data->sie_version != SIE300)) + { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + dev->data->range_list = range_list; + dev->data->nbr_of_ranges = nbr_of_ranges; + dev->data->is_initialized = true; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t * dev, uint32_t * blk_size) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (blk_size == 0) + { + return MPC_SIE_INVALID_ARG; + } + + /* Calculate the block size in byte according to the manual */ + *blk_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t * dev, const uint32_t base, const uint32_t limit, + enum mpc_sie_sec_attr_t attr) +{ + enum mpc_sie_intern_error_t error; + uint32_t first_word_idx; + uint32_t first_word_mask; + uint32_t i; + uint32_t limit_word_mask; + uint32_t limit_word_idx; + uint32_t nr_words; + const struct mpc_sie_memory_range_t * range; + uint32_t word_value; + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + /* Get the bitmasks used to select the bits in the LUT */ + error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words, &first_word_mask, &limit_word_mask); + + limit_word_idx = first_word_idx + nr_words - 1; + + if (error != MPC_SIE_INTERN_ERR_NONE) + { + /* Map internal error code lower than 0 to a generic errpr */ + if (error < 0) + { + return MPC_SIE_ERR_INVALID_RANGE; + } + return (enum mpc_sie_error_t) error; + } + + /* + * The memory range should allow accesses in with the wanted security + * attribute if it requires special attribute for successful accesses + */ + if (range->attr != attr) + { + return MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE; + } + + /* + * Starts changing actual configuration so issue DMB to ensure every + * transaction has completed by now + */ + __DMB(); + + /* Set the block index to the first word that will be updated */ + p_mpc->blk_idx = first_word_idx; + + /* If only one word needs to be touched in the LUT */ + if (nr_words == 1) + { + word_value = p_mpc->blk_lutn; + if (attr == MPC_SIE_SEC_ATTR_NONSECURE) + { + word_value |= first_word_mask; + } + else + { + word_value &= ~first_word_mask; + } + + /* + * Set the index again because full word read or write could have + * incremented it + */ + p_mpc->blk_idx = first_word_idx; + p_mpc->blk_lutn = word_value; + + /* Commit the configuration change */ + __DSB(); + __ISB(); + + return MPC_SIE_ERR_NONE; + } + + /* First word */ + word_value = p_mpc->blk_lutn; + if (attr == MPC_SIE_SEC_ATTR_NONSECURE) + { + word_value |= first_word_mask; + } + else + { + word_value &= ~first_word_mask; + } + /* + * Set the index again because full word read or write could have + * incremented it + */ + p_mpc->blk_idx = first_word_idx; + /* Partially configure the first word */ + p_mpc->blk_lutn = word_value; + + /* Fully configure the intermediate words if there are any */ + for (i = first_word_idx + 1; i < limit_word_idx; i++) + { + p_mpc->blk_idx = i; + if (attr == MPC_SIE_SEC_ATTR_NONSECURE) + { + p_mpc->blk_lutn = 0xFFFFFFFF; + } + else + { + p_mpc->blk_lutn = 0x00000000; + } + } + + /* Partially configure the limit word */ + p_mpc->blk_idx = limit_word_idx; + word_value = p_mpc->blk_lutn; + if (attr == MPC_SIE_SEC_ATTR_NONSECURE) + { + word_value |= limit_word_mask; + } + else + { + word_value &= ~limit_word_mask; + } + p_mpc->blk_idx = limit_word_idx; + p_mpc->blk_lutn = word_value; + + /* Commit the configuration change */ + __DSB(); + __ISB(); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_region_config(struct mpc_sie_dev_t * dev, uint32_t base, uint32_t limit, + enum mpc_sie_sec_attr_t * attr) +{ + enum mpc_sie_sec_attr_t attr_prev; + uint32_t block_size; + uint32_t block_size_mask; + enum mpc_sie_intern_error_t error; + uint32_t first_word_idx; + uint32_t first_word_mask; + uint32_t i; + uint32_t limit_word_idx; + uint32_t limit_word_mask; + uint32_t nr_words; + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + const struct mpc_sie_memory_range_t * range; + uint32_t word_value; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (attr == 0) + { + return MPC_SIE_INVALID_ARG; + } + + /* + * Initialize the security attribute to mixed in case of early + * termination of this function. A caller that does not check the + * returned error will act as if it does not know anything about the + * region queried, which is the safest bet + */ + *attr = MPC_SIE_SEC_ATTR_MIXED; + + /* + * If the base and limit are not aligned, align them and make sure + * that the resulting region fully includes the original region + */ + block_size = (1 << (p_mpc->blk_cfg + MPC_SIE_BLK_CFG_OFFSET)); + + block_size_mask = block_size - 1; + base &= ~(block_size_mask); + limit &= ~(block_size_mask); + limit += block_size - 1; /* Round to the upper block address, + * and then remove one to get the preceding + * address. + */ + + /* Get the bitmasks used to select the bits in the LUT */ + error = get_lut_masks(dev, base, limit, &range, &first_word_idx, &nr_words, &first_word_mask, &limit_word_mask); + + limit_word_idx = first_word_idx + nr_words - 1; + + if (error != MPC_SIE_INTERN_ERR_NONE) + { + /* Map internal error code lower than 0 to generic error */ + if (error < 0) + { + return MPC_SIE_ERR_INVALID_RANGE; + } + return (enum mpc_sie_error_t) error; + } + + /* Set the block index to the first word that will be updated */ + p_mpc->blk_idx = first_word_idx; + + /* If only one word needs to be touched in the LUT */ + if (nr_words == 1) + { + word_value = p_mpc->blk_lutn; + word_value &= first_word_mask; + if (word_value == 0) + { + *attr = MPC_SIE_SEC_ATTR_SECURE; + /* + * If there are differences between the mask and the word value, + * it means that the security attributes of blocks are mixed + */ + } + else if (word_value ^ first_word_mask) + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + } + else + { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + return MPC_SIE_ERR_NONE; + } + + /* Get the partial configuration of the first word */ + word_value = p_mpc->blk_lutn & first_word_mask; + if (word_value == 0x00000000) + { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } + else if (word_value ^ first_word_mask) + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + /* + * Bail out as the security attribute will be the same regardless + * of the configuration of other blocks + */ + return MPC_SIE_ERR_NONE; + } + else + { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + /* + * Store the current found attribute, to check that all the blocks indeed + * have the same security attribute. + */ + attr_prev = *attr; + + /* Get the configuration of the intermediate words if there are any */ + for (i = first_word_idx + 1; i < limit_word_idx; i++) + { + p_mpc->blk_idx = i; + word_value = p_mpc->blk_lutn; + if (word_value == 0x00000000) + { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } + else if (word_value == 0xFFFFFFFF) + { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + else + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + + /* If the attribute is different than the one found before, bail out */ + if (*attr != attr_prev) + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + attr_prev = *attr; + } + + /* Get the partial configuration of the limit word */ + p_mpc->blk_idx = limit_word_idx; + word_value = p_mpc->blk_lutn & limit_word_mask; + if (word_value == 0x00000000) + { + *attr = MPC_SIE_SEC_ATTR_SECURE; + } + else if (word_value ^ first_word_mask) + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + else + { + *attr = MPC_SIE_SEC_ATTR_NONSECURE; + } + + if (*attr != attr_prev) + { + *attr = MPC_SIE_SEC_ATTR_MIXED; + return MPC_SIE_ERR_NONE; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t * dev, uint32_t * ctrl_val) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (ctrl_val == 0) + { + return MPC_SIE_INVALID_ARG; + } + + *ctrl_val = p_mpc->ctrl; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t * dev, uint32_t mpc_ctrl) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + p_mpc->ctrl = mpc_ctrl; + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t * dev, enum mpc_sie_sec_resp_t * sec_rep) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + bool gating_present = false; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (sec_rep == NULL) + { + return MPC_SIE_INVALID_ARG; + } + + if (dev->data->sie_version == SIE200) + { + if (p_mpc->ctrl & MPC_SIE200_CTRL_SEC_RESP) + { + *sec_rep = MPC_SIE_RESP_BUS_ERROR; + } + else + { + *sec_rep = MPC_SIE_RESP_RAZ_WI; + } + } + else if (dev->data->sie_version == SIE300) + { + mpc_sie_is_gating_present(dev, &gating_present); + if (!gating_present) + { + return MPC_SIE_ERR_GATING_NOT_PRESENT; + } + + if (p_mpc->ctrl & MPC_SIE300_CTRL_SEC_RESP) + { + /* MPC returns a BUS ERROR response */ + *sec_rep = MPC_SIE_RESP_BUS_ERROR; + } + else + { + /* MPC sets the ready signals LOW, which stalls any transactions */ + *sec_rep = MPC_SIE_RESP_WAIT_GATING_DISABLED; + } + } + else + { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t * dev, enum mpc_sie_sec_resp_t sec_rep) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + bool gating_present = false; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (dev->data->sie_version == SIE200) + { + if (sec_rep == MPC_SIE_RESP_BUS_ERROR) + { + p_mpc->ctrl |= MPC_SIE200_CTRL_SEC_RESP; + } + else if (sec_rep == MPC_SIE_RESP_RAZ_WI) + { + p_mpc->ctrl &= ~MPC_SIE200_CTRL_SEC_RESP; + } + else + { + return MPC_SIE_INVALID_ARG; + } + } + else if (dev->data->sie_version == SIE300) + { + mpc_sie_is_gating_present(dev, &gating_present); + if (!gating_present) + { + return MPC_SIE_ERR_GATING_NOT_PRESENT; + } + + if (sec_rep == MPC_SIE_RESP_BUS_ERROR) + { + p_mpc->ctrl |= MPC_SIE300_CTRL_SEC_RESP; + } + else if (sec_rep == MPC_SIE_RESP_WAIT_GATING_DISABLED) + { + p_mpc->ctrl &= ~MPC_SIE300_CTRL_SEC_RESP; + } + else + { + return MPC_SIE_INVALID_ARG; + } + } + else + { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + p_mpc->int_en |= MPC_SIE_INT_BIT; + + return MPC_SIE_ERR_NONE; +} + +void mpc_sie_irq_disable(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + p_mpc->int_en &= ~MPC_SIE_INT_BIT; +} + +void mpc_sie_clear_irq(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + p_mpc->int_clear = MPC_SIE_INT_BIT; +} + +uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + return (p_mpc->int_stat & MPC_SIE_INT_BIT); +} + +enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + p_mpc->ctrl |= (MPC_SIE_CTRL_AUTOINCREMENT | MPC_SIE_CTRL_SEC_LOCK_DOWN); + + return MPC_SIE_ERR_NONE; +} + +enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t * dev, bool * gating_present) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + if (dev->data->is_initialized != true) + { + return MPC_SIE_NOT_INIT; + } + + if (dev->data->sie_version != SIE300) + { + return MPC_SIE_UNSUPPORTED_HARDWARE_VERSION; + } + + *gating_present = (bool) (p_mpc->ctrl & MPC_SIE300_CTRL_GATE_PRESENT); + + return MPC_SIE_ERR_NONE; +} + +uint32_t get_sie_version(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + return p_mpc->pidr0 & MPC_PIDR0_SIE_VERSION_MASK; +} + +bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + return (bool) (p_mpc->ctrl & MPC_SIE300_CTRL_GATE_ACK); +} + +void mpc_sie_request_gating(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + p_mpc->ctrl |= MPC_SIE300_CTRL_GATE_REQ; +} + +void mpc_sie_release_gating(struct mpc_sie_dev_t * dev) +{ + struct mpc_sie_reg_map_t * p_mpc = (struct mpc_sie_reg_map_t *) dev->cfg->base; + + p_mpc->ctrl &= ~MPC_SIE300_CTRL_GATE_REQ; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.h new file mode 100644 index 00000000000000..a313f8b32da1eb --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpc_sie_drv.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2016-2019 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file mpc_sie_drv.h + * \brief Generic driver for ARM SIE Memory Protection + * Controllers (MPC). + */ + +#ifndef __MPC_SIE_DRV_H__ +#define __MPC_SIE_DRV_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error code returned by the driver functions */ +enum mpc_sie_error_t +{ + MPC_SIE_ERR_NONE, /*!< No error */ + MPC_SIE_INVALID_ARG, /*!< MPC invalid input arguments */ + MPC_SIE_NOT_INIT, /*!< MPC not initialized */ + MPC_SIE_ERR_NOT_IN_RANGE, /*!< Address does not belong to a range + * controlled by the MPC */ + MPC_SIE_ERR_NOT_ALIGNED, /*!< Address is not aligned on the block size + * of this MPC + */ + MPC_SIE_ERR_INVALID_RANGE, /*!< The given address range to configure + * is invalid. This could be because: + * - The base and limit swapped + * - The base and limit addresses + * are in different ranges + */ + MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be + * accessed with the wanted + * security attributes + */ + MPC_SIE_UNSUPPORTED_HARDWARE_VERSION, /*!< MPC hardware version read from + * PIDR0 is not supported + */ + MPC_SIE_ERR_GATING_NOT_PRESENT /*!< MPC gating not present in HW */ +}; + +/* Security attribute used in various place of the API */ +enum mpc_sie_sec_attr_t +{ + MPC_SIE_SEC_ATTR_SECURE, /*!< Secure attribute */ + MPC_SIE_SEC_ATTR_NONSECURE, /*!< Non-secure attribute */ + /*!< Used when getting the configuration of a memory range and some blocks + * are secure whereas some other are non secure + */ + MPC_SIE_SEC_ATTR_MIXED, +}; + +/* What can happen when trying to do an illegal memory access */ +enum mpc_sie_sec_resp_t +{ + MPC_SIE_RESP_RAZ_WI, /*!< Read As Zero, Write Ignored */ + MPC_SIE_RESP_BUS_ERROR, /*!< Bus error */ + MPC_SIE_RESP_WAIT_GATING_DISABLED /*!< Wait until gating is disabled */ +}; + +/* Description of a memory range controlled by the MPC */ +struct mpc_sie_memory_range_t +{ + const uint32_t base; /*!< Base address (included in the range) */ + const uint32_t limit; /*!< Limit address (included in the range) */ + const uint32_t range_offset; /*!< Offset of current range area to the 0 + * point of the whole area (the sum of the + * sizes of the previous memory ranges + * covered by the same MPC) + */ + const enum mpc_sie_sec_attr_t attr; /*!< Optional security attribute + * needed to be matched when + * accessing this range. + * For example, the non-secure + * alias of a memory region can not + * be accessed using secure access, + * and configuring the MPC to + * secure using that range will not + * be permitted by the driver. + */ +}; + +/* ARM MPC SIE device configuration structure */ +struct mpc_sie_dev_cfg_t +{ + const uint32_t base; /*!< MPC base address */ +}; + +/* ARM MPC SIE device data structure */ +struct mpc_sie_dev_data_t +{ + /*!< Array of pointers to memory ranges controlled by the MPC */ + const struct mpc_sie_memory_range_t ** range_list; + uint8_t nbr_of_ranges; /*!< Number of memory ranges in the list */ + bool is_initialized; /*!< Indicates if the MPC driver + * is initialized and enabled + */ + uint32_t sie_version; /*!< SIE version */ +}; + +/* ARM MPC SIE device structure */ +struct mpc_sie_dev_t +{ + const struct mpc_sie_dev_cfg_t * const cfg; /*!< MPC configuration */ + struct mpc_sie_dev_data_t * const data; /*!< MPC data */ +}; + +/** + * \brief Initializes a MPC device. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] range_list List of memory ranges controller by the MPC + * (\ref mpc_sie_memory_range_t). This list can not + * freed after the initializations. + * \param[in] nbr_of_ranges Number of memory ranges + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_init(struct mpc_sie_dev_t * dev, const struct mpc_sie_memory_range_t ** range_list, + uint8_t nbr_of_ranges); + +/** + * \brief Gets MPC block size. All regions must be aligned on this block + * size (base address and limit+1 address). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] blk_size MPC block size + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t * dev, uint32_t * blk_size); + +/** + * \brief Configures a memory region (base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] base Base address of the region to poll. This bound is + * included. It does not need to be aligned in any way. + * + * \param[in] limit Limit address of the region to poll. This bound is + * included. (limit+1) does not need to be aligned + * in any way. + * \param[in] attr Security attribute of the region. If the region has mixed + * secure/non-secure, a special value is returned + * (\ref mpc_sie_sec_attr_t). + * + * In case base and limit+1 addresses are not aligned on + * the block size, the enclosing region with base and + * limit+1 aligned on block size will be queried. + * In case of early termination of the function (error), the + * security attribute will be set to MPC_SIE_ATTR_MIXED. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t * dev, const uint32_t base, const uint32_t limit, + enum mpc_sie_sec_attr_t attr); + +/** + * \brief Gets a memory region configuration(base and limit included). + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] base Base address of the region to get the configuration. + * \param[in] limit Limit address of the region to get the configuration. + * \param[out] attr Security attribute of the region + * \ref mpc_sie_sec_attr_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_region_config(struct mpc_sie_dev_t * dev, uint32_t base, uint32_t limit, + enum mpc_sie_sec_attr_t * attr); + +/** + * \brief Gets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] ctrl_val Current MPC control value. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t * dev, uint32_t * ctrl_val); + +/** + * \brief Sets the MPC control value. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] mpc_ctrl New MPC control value + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t * dev, uint32_t mpc_ctrl); + +/** + * \brief Gets the configured secure response. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] sec_rep Configured secure response (\ref mpc_sie_sec_resp_t). + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t * dev, enum mpc_sie_sec_resp_t * sec_rep); + +/** + * \brief Sets the response type when SW asks to gate the incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[in] sec_rep Secure response to configure (\ref mpc_sie_sec_resp_t). + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t * dev, enum mpc_sie_sec_resp_t sec_rep); + +/** + * \brief Enables MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t * dev); + +/** + * \brief Disables MPC interrupt + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_irq_disable(struct mpc_sie_dev_t * dev); + +/** + * \brief Clears MPC interrupt. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_clear_irq(struct mpc_sie_dev_t * dev); + +/** + * \brief Returns the MPC interrupt state. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns 1 if the interrupt is active, 0 otherwise. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t * dev); + +/** + * \brief Locks down the MPC configuration. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t * dev); + +/** + * \brief Returns if gating is present in hardware. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * \param[out] gating_present Returns if gating is present in hardware. + * + * \return Returns error code as specified in \ref mpc_sie_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t * dev, bool * gating_present); + +/** + * \brief Returns the value of Peripheral ID 0 register. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return Returns the value of Peripheral ID 0 register. + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t get_sie_version(struct mpc_sie_dev_t * dev); + +/** + * \brief Reads bit indicating acknowledge for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \return True if acknowledge is set. + * + * \note This function doesn't check if dev is NULL. + */ +bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t * dev); + +/** + * \brief Sets bit to request for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_request_gating(struct mpc_sie_dev_t * dev); + +/** + * \brief Clears bit to request for gating incoming transfers. + * + * \param[in] dev MPC device \ref mpc_sie_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void mpc_sie_release_gating(struct mpc_sie_dev_t * dev); + +#ifdef __cplusplus +} +#endif +#endif /* __MPC_SIE_DRV_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.c new file mode 100644 index 00000000000000..b45338b4492c8e --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2017-2021, 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_BASE_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_BASE_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; + +#ifdef TFM_PXN_ENABLE + limit_cfg |= (region_cfg->attr_pxn << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk; +#endif + + 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/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.h new file mode 100644 index 00000000000000..fcd9bf85e93cad --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/mpu_armv8m_drv.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2017-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __MPU_ARMV8M_DRV_H__ +#define __MPU_ARMV8M_DRV_H__ + +#include + +#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 +}; + +#ifdef TFM_PXN_ENABLE +enum mpu_armv8m_attr_priv_exec_t +{ + MPU_ARMV8M_PRIV_EXEC_OK, + MPU_ARMV8M_PRIV_EXEC_NEVER +}; +#endif + +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; +#ifdef TFM_PXN_ENABLE + enum mpu_armv8m_attr_priv_exec_t attr_pxn; +#endif +}; + +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 mpu_armv8m_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 mpu_armv8m_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 mpu_armv8m_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 mpu_armv8m_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/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.c new file mode 100644 index 00000000000000..317494e7b1e139 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.c @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2019-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ppc_sse300_drv.h" +#include +#include + +/* Default peripheral states */ +#define SECURE_AS_DEFAULT_PERIPHERAL_STATE true +#define PRIVILEGE_ONLY_AS_DEFAULT_PERIPHERAL_STATE true + +/* Secure Access Configuration Register Block */ +struct sse300_sacfg_block_t +{ + volatile uint32_t reserved0[8]; + volatile uint32_t secppcintstat; /* 0x020 (R/ ) Secure PPC IRQ Status */ + volatile uint32_t secppcintclr; /* 0x024 (R/W) Secure PPC IRQ Clear */ + volatile uint32_t secppcinten; /* 0x028 (R/W) Secure PPC IRQ Enable */ + volatile uint32_t reserved1[9]; + volatile uint32_t mainnsppc0; /* 0x050 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Main + * Interconnect */ + volatile uint32_t reserved2[3]; + volatile uint32_t mainnsppcexp0; /* 0x060 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp1; /* 0x064 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp2; /* 0x068 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t mainnsppcexp3; /* 0x06C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on the + * Main Interconnect */ + volatile uint32_t periphnsppc0; /* 0x070 (R/W) Non-secure Access + * Peripheral Protection + * Control 0 on the Peripheral + * Interconnect */ + volatile uint32_t periphnsppc1; /* 0x074 (R/W) Non-secure Access + * Peripheral Protection + * Control 1 on the Peripheral + * Interconnect */ + volatile uint32_t reserved3[2]; + volatile uint32_t periphnsppcexp0; /* 0x080 (R/W) Expansion 0 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp1; /* 0x084 (R/W) Expansion 1 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp2; /* 0x088 (R/W) Expansion 2 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t periphnsppcexp3; /* 0x08C (R/W) Expansion 3 Non-secure + * Access Peripheral + * Protection Control on + * Peripheral Bus */ + volatile uint32_t mainspppc0; /* 0x090 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on Main + * Interconnect */ + volatile uint32_t reserved4[3]; + volatile uint32_t mainspppcexp0; /* 0x0A0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp1; /* 0x0A4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp2; /* 0x0A8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainspppcexp3; /* 0x0AC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphspppc0; /* 0x0B0 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphspppc1; /* 0x0B4 (R/W) Secure Unprivileged Access + * Peripheral Protection + * Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved5[2]; + volatile uint32_t periphspppcexp0; /* 0x0C0 (R/W) Expansion 0 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp1; /* 0x0C4 (R/W) Expansion 1 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp2; /* 0x0C8 (R/W) Expansion 2 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphspppcexp3; /* 0x0CC (R/W) Expansion 3 Secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved6[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved7[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +/* PPC interrupt position mask */ +#define PERIPH_PPC0_INT_POS_MASK (1UL << 0) +#define PERIPH_PPC1_INT_POS_MASK (1UL << 1) +#define PERIPH_PPCEXP0_INT_POS_MASK (1UL << 4) +#define PERIPH_PPCEXP1_INT_POS_MASK (1UL << 5) +#define PERIPH_PPCEXP2_INT_POS_MASK (1UL << 6) +#define PERIPH_PPCEXP3_INT_POS_MASK (1UL << 7) +#define MAIN_PPC0_INT_POS_MASK (1UL << 16) +#define MAIN_PPCEXP0_INT_POS_MASK (1UL << 20) +#define MAIN_PPCEXP1_INT_POS_MASK (1UL << 21) +#define MAIN_PPCEXP2_INT_POS_MASK (1UL << 22) +#define MAIN_PPCEXP3_INT_POS_MASK (1UL << 23) + +/* Non-secure Access Configuration Register Block */ +struct sse300_nsacfg_block_t +{ + volatile uint32_t reserved0[36]; + volatile uint32_t mainnspppc0; /* 0x090 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Main Interconnect */ + volatile uint32_t reserved1[3]; + + volatile uint32_t mainnspppcexp0; /* 0x0A0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp1; /* 0x0A4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp2; /* 0x0A8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t mainnspppcexp3; /* 0x0AC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Main + * Interconnect */ + volatile uint32_t periphnspppc0; /* 0x0B0 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 0 on + * Peripheral Interconnect */ + volatile uint32_t periphnspppc1; /* 0x0B4 (R/W) Non-secure Unprivileged + * Access Peripheral + * Protection Control 1 on + * Peripheral Interconnect */ + volatile uint32_t reserved2[2]; + volatile uint32_t periphnspppcexp0; /* 0x0C0 (R/W) Expansion 0 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp1; /* 0x0C4 (R/W) Expansion 1 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp2; /* 0x0C8 (R/W) Expansion 2 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t periphnspppcexp3; /* 0x0CC (R/W) Expansion 3 Non-secure + * Unprivileged Access + * Peripheral Protection + * Control on Peripheral + * Interconnect */ + volatile uint32_t reserved3[960]; + volatile uint32_t pidr4; /* 0xFD0 (R/ ) Peripheral ID 4 */ + volatile uint32_t reserved4[3]; + volatile uint32_t pidr0; /* 0xFE0 (R/ ) Peripheral ID 0 */ + volatile uint32_t pidr1; /* 0xFE4 (R/ ) Peripheral ID 1 */ + volatile uint32_t pidr2; /* 0xFE8 (R/ ) Peripheral ID 2 */ + volatile uint32_t pidr3; /* 0xFEC (R/ ) Peripheral ID 3 */ + volatile uint32_t cidr0; /* 0xFF0 (R/ ) Component ID 0 */ + volatile uint32_t cidr1; /* 0xFF4 (R/ ) Component ID 1 */ + volatile uint32_t cidr2; /* 0xFF8 (R/ ) Component ID 2 */ + volatile uint32_t cidr3; /* 0xFFC (R/ ) Component ID 3 */ +}; + +enum ppc_sse300_error_t ppc_sse300_init(struct ppc_sse300_dev_t * dev) +{ + struct sse300_sacfg_block_t * p_sacfg = (struct sse300_sacfg_block_t *) dev->cfg->sacfg_base; + struct sse300_nsacfg_block_t * p_nsacfg = (struct sse300_nsacfg_block_t *) dev->cfg->nsacfg_base; + + switch (dev->cfg->ppc_name) + { + /* Case for MAIN0 */ + case PPC_SSE300_MAIN0: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppc0; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppc0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppc0; + dev->data->int_bit_mask = MAIN_PPC0_INT_POS_MASK; + break; + + /* Case for MAIN EXPX */ + case PPC_SSE300_MAIN_EXP0: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp0; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp0; + dev->data->int_bit_mask = MAIN_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP1: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp1; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp1; + dev->data->int_bit_mask = MAIN_PPCEXP1_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP2: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp2; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp2; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp2; + dev->data->int_bit_mask = MAIN_PPCEXP2_INT_POS_MASK; + break; + case PPC_SSE300_MAIN_EXP3: + dev->data->sacfg_ns_ppc = &p_sacfg->mainnsppcexp3; + dev->data->sacfg_sp_ppc = &p_sacfg->mainspppcexp3; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->mainnspppcexp3; + dev->data->int_bit_mask = MAIN_PPCEXP3_INT_POS_MASK; + break; + + /* Case for PERIPHX */ + case PPC_SSE300_PERIPH0: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppc0; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppc0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc0; + dev->data->int_bit_mask = PERIPH_PPC0_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH1: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppc1; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppc1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppc1; + dev->data->int_bit_mask = PERIPH_PPC1_INT_POS_MASK; + break; + + /* Case for PERIPH EXPX */ + case PPC_SSE300_PERIPH_EXP0: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp0; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp0; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp0; + dev->data->int_bit_mask = PERIPH_PPCEXP0_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP1: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp1; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp1; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp1; + dev->data->int_bit_mask = PERIPH_PPCEXP1_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP2: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp2; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp2; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp2; + dev->data->int_bit_mask = PERIPH_PPCEXP2_INT_POS_MASK; + break; + case PPC_SSE300_PERIPH_EXP3: + dev->data->sacfg_ns_ppc = &p_sacfg->periphnsppcexp3; + dev->data->sacfg_sp_ppc = &p_sacfg->periphspppcexp3; + dev->data->nsacfg_nsp_ppc = &p_nsacfg->periphnspppcexp3; + dev->data->int_bit_mask = PERIPH_PPCEXP3_INT_POS_MASK; + break; + default: + return PPC_SSE300_ERR_INVALID_PARAM; + } + + dev->data->is_initialized = true; + + return PPC_SSE300_ERR_NONE; +} + +enum ppc_sse300_error_t ppc_sse300_config_privilege(struct ppc_sse300_dev_t * dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr, enum ppc_sse300_priv_attr_t priv_attr) +{ + if (dev->data->is_initialized != true) + { + return PPC_SSE300_ERR_NOT_INIT; + } + + if (sec_attr == PPC_SSE300_SECURE_ACCESS) + { +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + /* Uses secure unprivileged access address (SACFG) to set privilege + * attribute + */ + if (priv_attr == PPC_SSE300_PRIV_ONLY_ACCESS) + { + *(dev->data->sacfg_sp_ppc) &= ~mask; + } + else + { + *(dev->data->sacfg_sp_ppc) |= mask; + } +#else + /* Configuring security from Non-Secure application is not permitted. */ + return PPC_SSE300_ERR_NOT_PERMITTED; +#endif + } + else + { + /* Uses non-secure unprivileged access address (NSACFG) to set + * privilege attribute */ + if (priv_attr == PPC_SSE300_PRIV_ONLY_ACCESS) + { + *(dev->data->nsacfg_nsp_ppc) &= ~mask; + } + else + { + *(dev->data->nsacfg_nsp_ppc) |= mask; + } + } + + return PPC_SSE300_ERR_NONE; +} + +bool ppc_sse300_is_periph_priv_only(struct ppc_sse300_dev_t * dev, uint32_t mask) +{ + if (dev->data->is_initialized != true) + { + /* Return true as the default configuration is privilege only */ + return true; + } + +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + /* In secure domain either secure or non-secure privilege access is returned + * based on the configuration */ + if ((*(dev->data->sacfg_ns_ppc) & mask) == 0) + { + /* Returns secure unprivileged access (SACFG) */ + return ((*(dev->data->sacfg_sp_ppc) & mask) == 0); + } + else + { + /* Returns non-secure unprivileged access (NSACFG) */ + return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0); + } +#else + /* Returns non-secure unprivileged access (NSACFG) */ + return ((*(dev->data->nsacfg_nsp_ppc) & mask) == 0); +#endif +} + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +enum ppc_sse300_error_t ppc_sse300_config_security(struct ppc_sse300_dev_t * dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr) +{ + if (dev->data->is_initialized != true) + { + return PPC_SSE300_ERR_NOT_INIT; + } + + if (sec_attr == PPC_SSE300_SECURE_ACCESS) + { + *(dev->data->sacfg_ns_ppc) &= ~mask; + } + else + { + *(dev->data->sacfg_ns_ppc) |= mask; + } + + return PPC_SSE300_ERR_NONE; +} + +bool ppc_sse300_is_periph_secure(struct ppc_sse300_dev_t * dev, uint32_t mask) +{ + if (dev->data->is_initialized != true) + { + /* Return true as the default configuration is secure */ + return true; + } + + return ((*(dev->data->sacfg_ns_ppc) & mask) == 0); +} + +enum ppc_sse300_error_t ppc_sse300_irq_enable(struct ppc_sse300_dev_t * dev) +{ + struct sse300_sacfg_block_t * p_sacfg = (struct sse300_sacfg_block_t *) dev->cfg->sacfg_base; + + if (dev->data->is_initialized != true) + { + return PPC_SSE300_ERR_NOT_INIT; + } + + p_sacfg->secppcinten |= dev->data->int_bit_mask; + + return PPC_SSE300_ERR_NONE; +} + +void ppc_sse300_irq_disable(struct ppc_sse300_dev_t * dev) +{ + struct sse300_sacfg_block_t * p_sacfg = (struct sse300_sacfg_block_t *) dev->cfg->sacfg_base; + + if (dev->data->is_initialized == true) + { + p_sacfg->secppcinten &= ~(dev->data->int_bit_mask); + } +} + +void ppc_sse300_clear_irq(struct ppc_sse300_dev_t * dev) +{ + struct sse300_sacfg_block_t * p_sacfg = (struct sse300_sacfg_block_t *) dev->cfg->sacfg_base; + + if (dev->data->is_initialized == true) + { + p_sacfg->secppcintclr = dev->data->int_bit_mask; + } +} + +bool ppc_sse300_irq_state(struct ppc_sse300_dev_t * dev) +{ + struct sse300_sacfg_block_t * p_sacfg = (struct sse300_sacfg_block_t *) dev->cfg->sacfg_base; + + if (dev->data->is_initialized != true) + { + return false; + } + + return ((p_sacfg->secppcintstat & dev->data->int_bit_mask) != 0); +} + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.h new file mode 100644 index 00000000000000..20cbc0ad5b4079 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/ppc_sse300_drv.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2019-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file ppc_sse300_drv.h + * \brief Generic driver for SSE-300 Peripheral Protection Controllers (PPC). + */ + +#ifndef __PPC_SSE_300_DRV_H__ +#define __PPC_SSE_300_DRV_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSE-300 PPC names */ +enum ppc_sse300_name_t +{ + PPC_SSE300_MAIN0 = 0, /*!< MAIN PPC 0 */ + PPC_SSE300_MAIN_EXP0, /*!< Expansion 0 MAIN PPC */ + PPC_SSE300_MAIN_EXP1, /*!< Expansion 1 MAIN PPC */ + PPC_SSE300_MAIN_EXP2, /*!< Expansion 2 MAIN PPC */ + PPC_SSE300_MAIN_EXP3, /*!< Expansion 3 MAIN PPC */ + PPC_SSE300_PERIPH0, /*!< PERIPH PPC0 */ + PPC_SSE300_PERIPH1, /*!< PERIPH PPC1 */ + PPC_SSE300_PERIPH_EXP0, /*!< Expansion 0 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP1, /*!< Expansion 1 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP2, /*!< Expansion 2 PERIPH PPC */ + PPC_SSE300_PERIPH_EXP3, /*!< Expansion 3 PERIPH PPC */ + SSE300_PPC_MAX_NUM +}; + +/* SSE-300 PPC device configuration structure */ +struct ppc_sse300_dev_cfg_t +{ + uint32_t const sacfg_base; /*!< Secure Privilege Control Block base */ + uint32_t const nsacfg_base; /*!< Non-Secure Privilege Control Block base */ + enum ppc_sse300_name_t ppc_name; +}; + +/* SSE-300 PPC device data structure */ +struct ppc_sse300_dev_data_t +{ + volatile uint32_t * sacfg_ns_ppc; /*!< Pointer to non-secure register */ + volatile uint32_t * sacfg_sp_ppc; /*!< Pointer to secure unprivileged + register */ + volatile uint32_t * nsacfg_nsp_ppc; /*!< Pointer to non-secure unprivileged + register */ + uint32_t int_bit_mask; /*!< Interrupt bit mask */ + bool is_initialized; /*!< Indicates if the PPC driver + is initialized */ +}; + +/* SSE-300 PPC device structure */ +struct ppc_sse300_dev_t +{ + const struct ppc_sse300_dev_cfg_t * const cfg; /*!< PPC configuration */ + struct ppc_sse300_dev_data_t * const data; /*!< PPC data */ +}; + +/* Security attribute used to configure the peripherals */ +enum ppc_sse300_sec_attr_t +{ + PPC_SSE300_SECURE_ACCESS = 0, /*! Secure access */ + PPC_SSE300_NONSECURE_ACCESS, /*! Non-secure access */ +}; + +/* Privilege attribute used to configure the peripherals */ +enum ppc_sse300_priv_attr_t +{ + PPC_SSE300_PRIV_AND_NONPRIV_ACCESS = 0, /*! Privilege and NonPrivilege + access */ + PPC_SSE300_PRIV_ONLY_ACCESS, /*! Privilege only access */ +}; + +/* ARM PPC error codes */ +enum ppc_sse300_error_t +{ + PPC_SSE300_ERR_NONE = 0, /*!< No error */ + PPC_SSE300_ERR_INVALID_PARAM, /*!< PPC invalid parameter error */ + PPC_SSE300_ERR_NOT_INIT, /*!< PPC not initialized */ + PPC_SSE300_ERR_NOT_PERMITTED /*!< PPC Operation not permitted */ +}; + +/** + * \brief Initialize the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_init(struct ppc_sse300_dev_t * dev); + +/** + * \brief Configures privilege attribute through the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * \param[in] sec_attr Secure attribute value. + * \param[in] priv_attr Privilege attribute value. + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_config_privilege(struct ppc_sse300_dev_t * dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr, enum ppc_sse300_priv_attr_t priv_attr); + +/** + * \brief Checks if the peripheral is configured as Privilege only or + * Privilege and non-Privilege access mode. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * + * \return Returns true for Privilege only configuration and false otherwise + * - with non-secure caller in the non-secure domain + * - with secure caller in the configured security domain + * If the driver is not initialized the return value of this function is + * true (Privilege only) as it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_is_periph_priv_only(struct ppc_sse300_dev_t * dev, uint32_t mask); + +/* Secure only functions */ +#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + +/** + * \brief Configures security attribute through the PPC device. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * \param[in] sec_attr Secure attribute value. + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_config_security(struct ppc_sse300_dev_t * dev, uint32_t mask, + enum ppc_sse300_sec_attr_t sec_attr); + +/** + * \brief Checks if the peripheral is configured as secure or non-secure. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * \param[in] mask Peripheral mask for the PPC. + * + * \return Returns true for secure and false for non-secure. + * If the driver is not initialized the return value is true (secure) as + * it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_is_periph_secure(struct ppc_sse300_dev_t * dev, uint32_t mask); + +/** + * \brief Enables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns error code as specified in \ref ppc_sse300_error_t + * + * \note This function doesn't check if dev is NULL. + */ +enum ppc_sse300_error_t ppc_sse300_irq_enable(struct ppc_sse300_dev_t * dev); + +/** + * \brief Disables PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse300_irq_disable(struct ppc_sse300_dev_t * dev); + +/** + * \brief Clears PPC interrupt. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void ppc_sse300_clear_irq(struct ppc_sse300_dev_t * dev); + +/** + * \brief Returns the PPC interrupt state. + * + * \param[in] dev PPC device \ref ppc_sse300_dev_t + * + * \return Returns true if the interrupt is active and otherwise false. + * If the driver is not initialized the return value of this function is + * false (not active) as it is the default system configuration. + * + * \note This function doesn't check if dev is NULL. + */ +bool ppc_sse300_irq_state(struct ppc_sse300_dev_t * dev); + +#endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */ + +#ifdef __cplusplus +} +#endif +#endif /* __PPC_SSE_300_DRV_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.c new file mode 100644 index 00000000000000..0155bdc0d88357 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.c @@ -0,0 +1,416 @@ +/* + * 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/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.h new file mode 100644 index 00000000000000..0977bd06c22396 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/syscounter_armv8-m_cntrl_drv.h @@ -0,0 +1,481 @@ +/* + * 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 +#include + +#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 overridden 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/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.c new file mode 100644 index 00000000000000..685de81937110c --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2019-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file systimer_armv8-m_drv.c + * + * \brief Driver for Armv8-M System Timer + * + */ + +#include "systimer_armv8-m_drv.h" + +/** Setter bit manipulation macro */ +#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1u << (BIT_INDEX))) +/** Clearing bit manipulation macro */ +#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1u << (BIT_INDEX))) +/** Getter bit manipulation macro */ +#define GET_BIT(WORD, BIT_INDEX) (bool) (((WORD) & (1u << (BIT_INDEX)))) +/** Getter bit-field manipulation macro */ +#define GET_BIT_FIELD(WORD, BIT_MASK, BIT_OFFSET) ((WORD & BIT_MASK) >> BIT_OFFSET) +/** Bit mask for given width bit-field manipulation macro */ +#define BITMASK(width) ((1u << (width)) - 1) + +/** + * \brief CNTBase Register map structure + */ +struct cnt_base_reg_map_t +{ + volatile const uint32_t cntpct_low; + /*!< Offset: 0x000 (RO) Current Physical Counter Value [31:0] */ + volatile const uint32_t cntpct_high; + /*!< Offset: 0x004 (RO) Current Physical Counter Value [63:32] */ + volatile const uint32_t reserved0[2]; + /*!< Offset: 0x008-0x0C Reserved */ + volatile uint32_t cntfrq; + /*!< Offset: 0x010 (R/W) Counter Frequency register in Hz */ + volatile const uint32_t reserved1[3]; + /*!< Offset: 0x014-0x01C Reserved */ + volatile uint32_t cntp_cval_low; + /*!< Offset: 0x020 (R/W) Timer Compare Value register [31:0] */ + volatile uint32_t cntp_cval_high; + /*!< Offset: 0x024 (R/W) Timer Compare Value register [63:32] */ + volatile uint32_t cntp_tval; + /*!< Offset: 0x028 (R/W) Timer Value register */ + volatile uint32_t cntp_ctl; + /*!< Offset: 0x02C (R/W) Timer Control register */ + volatile const uint32_t reserved2[4]; + /*!< Offset: 0x030-0x03C Reserved */ + volatile const uint32_t cntp_aival_low; + /*!< Offset: 0x040 (RO) Auto Increment Value register [31:0]*/ + volatile const uint32_t cntp_aival_high; + /*!< Offset: 0x044 (RO) Auto Increment Value register [63:32]*/ + volatile uint32_t cntp_aival_reload; + /*!< Offset: 0x048 (R/W) Auto Increment Value Reload register [63:32]*/ + volatile uint32_t cntp_aival_ctl; + /*!< Offset: 0x04C (R/W) Auto Increment Control register */ + volatile const uint32_t cntp_cfg; + /*!< Offset: 0x050 (RO) Timer Configuration register */ + volatile const uint32_t reserved3[991]; + /*!< Offset: 0x054-0xFCC Reserved */ + volatile const uint32_t cntp_pid4; + /*!< Offset: 0xFD0 (RO) Peripheral ID Register */ + volatile const uint32_t reserved4[3]; + /*!< Offset: 0xFD4-0xFDC Reserved (RAZWI) */ + volatile const uint32_t cntp_pid0; + /*!< Offset: 0xFE0 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid1; + /*!< Offset: 0xFE4 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid2; + /*!< Offset: 0xFE8 (RO) Peripheral ID Register */ + volatile const uint32_t cntp_pid3; + /*!< Offset: 0xFEC (RO) Peripheral ID Register */ + volatile const uint32_t cntp_cid0; + /*!< Offset: 0xFF0 (RO) Component ID Register */ + volatile const uint32_t cntp_cid1; + /*!< Offset: 0xFF4 (RO) Component ID Register */ + volatile const uint32_t cntp_cid2; + /*!< Offset: 0xFF8 (RO) Component ID Register */ + volatile const uint32_t cntp_cid3; + /*!< Offset: 0xFFC (RO) Component ID Register */ +}; + +/** + * \brief Timer Control Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF 0u +/*!< Timer Control Register Enable Counter bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF 1u +/*!< Timer Control Register Interrupt Mask bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF 2u +/*!< Timer Control Register Interrupt Status bit field offset */ + +/** + * \brief Timer AutoInc Control Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF 0u +/*!< Timer Control Register Enable Counter bit field offset */ +#define SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF 1u +/*!< Timer Control Register Interrupt clear bit field offset */ + +/** + * \brief Timer AutoInc Config Register bit fields + */ +#define SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF 0u +/*!< Timer Control Register AutoInc is implemented bit field offset */ + +void systimer_armv8_m_init(struct systimer_armv8_m_dev_t * dev) +{ + if (dev->data->is_initialized == false) + { + systimer_armv8_m_disable_interrupt(dev); + systimer_armv8_m_disable_autoinc(dev); + systimer_armv8_m_set_counter_freq(dev, dev->cfg->default_freq_hz); + systimer_armv8_m_enable_timer(dev); + dev->data->is_initialized = true; + } +} + +void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t * dev) +{ + if (dev->data->is_initialized == true) + { + systimer_armv8_m_disable_interrupt(dev); + systimer_armv8_m_disable_autoinc(dev); + systimer_armv8_m_disable_timer(dev); + dev->data->is_initialized = false; + } +} + +uint64_t systimer_armv8_m_get_counter_value(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + uint32_t high = 0; + uint32_t low = 0; + uint32_t high_prev = 0; + uint64_t value = 0; + + /* Make sure the 64-bit read will be atomic to avoid overflow between + * the low and high registers read + */ + high = p_cnt->cntpct_high; + do + { + high_prev = high; + low = p_cnt->cntpct_low; + high = p_cnt->cntpct_high; + } while (high != high_prev); + + value = low | (((uint64_t) high) << SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_compare_value(struct systimer_armv8_m_dev_t * dev, uint64_t value) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + p_cnt->cntp_cval_low = value & UINT32_MAX; + p_cnt->cntp_cval_high = value >> SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH; +} + +uint64_t systimer_armv8_m_get_compare_value(struct systimer_armv8_m_dev_t * dev) +{ + uint64_t value = 0; + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + value = p_cnt->cntp_cval_low | (((uint64_t) p_cnt->cntp_cval_high) << SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_counter_freq(struct systimer_armv8_m_dev_t * dev, uint32_t value) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + p_cnt->cntfrq = value; +} + +uint32_t systimer_armv8_m_get_counter_freq(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return p_cnt->cntfrq; +} + +void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t * dev, uint32_t value) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + p_cnt->cntp_tval = value; +} + +uint32_t systimer_armv8_m_get_timer_value(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return p_cnt->cntp_tval; +} + +void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +bool systimer_armv8_m_is_timer_enabled(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_EN_OFF); +} + +void systimer_armv8_m_enable_interrupt(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + CLR_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +void systimer_armv8_m_disable_interrupt(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + SET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +bool systimer_armv8_m_is_interrupt_enabled(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + /* The bit is masking interrupt, so it should be inverted. */ + return !GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_IMASK_OFF); +} + +bool systimer_armv8_m_is_interrupt_asserted(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return GET_BIT(p_cnt->cntp_ctl, SYSCTIMER_ARMV8M_CNTP_CTL_ISTATUS_OFF); +} + +uint64_t systimer_armv8_m_get_autoinc_value(struct systimer_armv8_m_dev_t * dev) +{ + uint64_t value = 0; + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + value = p_cnt->cntp_aival_low | (((uint64_t) p_cnt->cntp_aival_high) << SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH); + return value; +} + +void systimer_armv8_m_set_autoinc_reload(struct systimer_armv8_m_dev_t * dev, uint32_t value) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + p_cnt->cntp_aival_reload = value; +} + +uint32_t systimer_armv8_m_get_autoinc_reload(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return p_cnt->cntp_aival_reload; +} + +void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + SET_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +bool systimer_armv8_m_is_autoinc_enabled(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return GET_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_EN_OFF); +} + +void systimer_armv8_m_clear_autoinc_interrupt(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + CLR_BIT(p_cnt->cntp_aival_ctl, SYSCTIMER_ARMV8M_CNTP_AIVAL_CTL_IRQ_CLR_OFF); +} + +bool systimer_armv8_m_is_autoinc_implemented(struct systimer_armv8_m_dev_t * dev) +{ + struct cnt_base_reg_map_t * p_cnt = (struct cnt_base_reg_map_t *) dev->cfg->base; + return GET_BIT(p_cnt->cntp_cfg, SYSCTIMER_ARMV8M_CNTP_CFG_CTL_AUTOINC_OFF); +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.h new file mode 100644 index 00000000000000..29a8b94a4fa9a5 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/systimer_armv8-m_drv.h @@ -0,0 +1,393 @@ +/* + * 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 +#include + +#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/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.c b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.c new file mode 100644 index 00000000000000..ea7b349903cbf9 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2016-2022 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 + +/* 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 */ + } + } +} + +enum uart_cmsdk_error_t uart_cmsdk_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_EN; + + return UART_CMSDK_ERR_NONE; +} + +void uart_cmsdk_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_EN; + } +} + +enum uart_cmsdk_error_t uart_cmsdk_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_EN; + + return UART_CMSDK_ERR_NONE; +} + +void uart_cmsdk_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_EN; + } +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.h b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.h new file mode 100644 index 00000000000000..f6d1d35eda2548 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/native_drivers/uart_cmsdk_drv.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2016-2022 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 + +#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); + +/** + * \brief Enables TX + * + * \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_tx_enable(struct uart_cmsdk_dev_t * dev); + +/** + * \brief Disables TX + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void uart_cmsdk_tx_disable(struct uart_cmsdk_dev_t * dev); + +/** + * \brief Enables RX + * + * \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_rx_enable(struct uart_cmsdk_dev_t * dev); + +/** + * \brief Disables RX + * + * \param[in] dev UART device struct \ref uart_cmsdk_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void uart_cmsdk_rx_disable(struct uart_cmsdk_dev_t * dev); + +#ifdef __cplusplus +} +#endif +#endif /* __UART_CMSDK_DRV_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/partition/flash_layout.h b/examples/platform/openiotsdk/tf-m/targets/an552/partition/flash_layout.h new file mode 100644 index 00000000000000..5adc3dcf35daff --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/partition/flash_layout.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2019-2021 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FLASH_LAYOUT_H__ +#define __FLASH_LAYOUT_H__ + +#include "platform_base_address.h" + +/* WARNING: Layout below has been moved to QSPI_SRAM and addresses so different now */ +/* Flash layout on AN552 with BL2 (multiple image boot): + * + * QSPI SRAM S + * 0x0000_0000 Secure image primary slot (384 KB) + * 0x0006_0000 Non-secure image primary slot (2 MB) + * 0x0026_0000 Secure image secondary slot (384 KB) + * 0x002C_0000 Non-secure image secondary slot (2 MB) + * 0x004C_0000 Scratch area (2 MB) + * 0x006C_0000 Protected Storage Area (64 KB) + * 0x006D_0000 Internal Trusted Storage Area (64 KB) + * 0x006E_0000 OTP / NV counters area (8 KB) + * 0x006E_2000 Unused + * + * Flash layout on AN552 with BL2 (single image boot): + * + * QSPI SRAM S (part1) + * 0x0000_0000 Primary image area (2MB + 384 KB): + * 0x0000_0000 Secure image primary (384 KB) + * 0x0006_0000 Non-secure image primary (2 MB) + * QSPI SRAM S (part2) + * 0x0026_0000 Secondary image area (2MB + 384 KB): + * 0x0026_0000 Secure image secondary (384 KB) + * 0x002C_0000 Non-secure image secondary (384 KB) + * 0x004C_0000 Scratch area (2 MB) + * 0x006C_0000 Protected Storage Area (64 KB) + * 0x006D_0000 Internal Trusted Storage Area (64 KB) + * 0x006E_0000 OTP / NV counters area (8 KB) + * 0x006E_2000 Unused + */ + +/* This header file is included from linker scatter file as well, where only a + * limited C constructs are allowed. Therefore it is not possible to include + * here the platform_retarget.h to access flash related defines. To resolve this + * some of the values are redefined here with different names, these are marked + * with comment. + */ + +/* Size of a Secure and of a Non-secure image */ +#define FLASH_S_PARTITION_SIZE (0x60000) /* S partition: 384 KB */ +#define FLASH_NS_PARTITION_SIZE (0x200000) /* NS partition: 2 MB */ +#define FLASH_MAX_PARTITION_SIZE \ + ((FLASH_S_PARTITION_SIZE > FLASH_NS_PARTITION_SIZE) ? FLASH_S_PARTITION_SIZE : FLASH_NS_PARTITION_SIZE) + +/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */ +#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB */ +/* Same as FLASH0_SIZE */ +#define FLASH_TOTAL_SIZE (QSPI_SRAM_SIZE) /* 8 MB */ + +/* Flash layout info for BL2 bootloader */ +/* Same as FLASH0_BASE_S */ +#define FLASH0_BASE_ADDRESS (QSPI_SRAM_BASE_S) +#define FLASH_BASE_ADDRESS (QSPI_SRAM_BASE_S) + +/* Offset and size definitions of the flash partitions that are handled by the + * bootloader. The image swapping is done between IMAGE_PRIMARY and + * IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image + * swapping. + */ +#define FLASH_AREA_BL2_OFFSET (0x0) +#define FLASH_AREA_BL2_SIZE (ITCM_SIZE) /* 256 KB */ + +#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1) +/* In QSPI SRAM S */ +/* Secure + Non-secure image primary slot */ +#define FLASH_AREA_0_ID (1) +#define FLASH_AREA_0_OFFSET (0) +#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) + +/* In QSPI SRAM S */ +/* Secure + Non-secure secondary slot */ +#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1) +#define FLASH_AREA_2_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE) +#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) +/* Scratch area */ +#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1) +#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE) +#define FLASH_AREA_SCRATCH_SIZE (FLASH_MAX_PARTITION_SIZE / 2) +/* The maximum number of status entries supported by the bootloader. */ +#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) / FLASH_AREA_SCRATCH_SIZE) +/* Maximum number of image sectors supported by the bootloader. */ +#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) / FLASH_AREA_IMAGE_SECTOR_SIZE) + +#if (FLASH_AREA_SCRATCH_OFFSET + FLASH_AREA_SCRATCH_SIZE > QSPI_SRAM_SIZE) +#error "Out of QSPI SRAM S memory!" +#endif +#elif (MCUBOOT_IMAGE_NUMBER == 2) +/* In QSPI SRAM S */ +/* Secure image primary slot */ +#define FLASH_AREA_0_ID (1) +#define FLASH_AREA_0_OFFSET (0) +#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE) +/* Non-secure image primary slot */ +#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1) +#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE) +#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE) +/* In QSPI SRAM */ +/* 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 / 2) +/* The maximum number of status entries supported by the bootloader. */ +#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / FLASH_AREA_SCRATCH_SIZE) +/* Maximum number of image sectors supported by the bootloader. */ +#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / FLASH_AREA_IMAGE_SECTOR_SIZE) + +#if (FLASH_AREA_SCRATCH_OFFSET + FLASH_AREA_SCRATCH_SIZE > QSPI_SRAM_SIZE) +#error "Out of QSPI SRAM S memory!" +#endif + +#else /* MCUBOOT_IMAGE_NUMBER > 2 */ +#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!" +#endif /* MCUBOOT_IMAGE_NUMBER */ + +/* Protected Storage (PS) Service definitions */ +#define FLASH_PS_AREA_OFFSET (FLASH_AREA_SCRATCH_OFFSET + FLASH_AREA_SCRATCH_SIZE) +#define FLASH_PS_AREA_SIZE (0x10000) /* 64 KB */ + +/* Internal Trusted Storage (ITS) Service definitions */ +#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + FLASH_PS_AREA_SIZE) +#define FLASH_ITS_AREA_SIZE (0x10000) /* 64 KB */ + +/* OTP_definitions */ +#define FLASH_OTP_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + FLASH_ITS_AREA_SIZE) +#define FLASH_OTP_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE * 2) +#define FLASH_OTP_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE + +#if (FLASH_OTP_NV_COUNTERS_AREA_OFFSET + FLASH_OTP_NV_COUNTERS_AREA_SIZE > QSPI_SRAM_SIZE) +#error "Out of QSPI SRAM memory!" +#endif + +/* 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_0 Driver_FLASH0 +#define FLASH_DEVICE_ID_0 102 +#define FLASH_DEV_NAME_1 Driver_FLASH0 +#define FLASH_DEVICE_ID_1 102 +#define FLASH_DEV_NAME_SCRATCH Driver_FLASH0 +#define FLASH_DEVICE_ID_SCRATCH 103 + +#define FLASH_DEV_NAME FLASH_DEV_NAME_0 + +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_FLASH_PROGRAM_UNIT (0x1) + +/* Protected Storage (PS) Service definitions + * Note: Further documentation of these definitions can be found in the + * TF-M PS Integration Guide. + */ +#define TFM_HAL_PS_FLASH_DRIVER Driver_FLASH0 + +/* In this target the CMSIS driver requires only the offset from the base + * address instead of the full memory address. + */ +/* Base address of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET +/* Size of dedicated flash area for PS */ +#define TFM_HAL_PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE +#define PS_RAM_FS_SIZE TFM_HAL_PS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_PS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_PS_PROGRAM_UNIT (0x1) + +/* Internal Trusted Storage (ITS) Service definitions + * Note: Further documentation of these definitions can be found in the + * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is + * allocated in the external flash just for development platforms that don't + * have internal flash available. + */ +#define TFM_HAL_ITS_FLASH_DRIVER Driver_FLASH0 + +/* In this target the CMSIS driver requires only the offset from the base + * address instead of the full memory address. + */ +/* Base address of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET +/* Size of dedicated flash area for ITS */ +#define TFM_HAL_ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE +#define ITS_RAM_FS_SIZE TFM_HAL_ITS_FLASH_AREA_SIZE +/* Number of physical erase sectors per logical FS block */ +#define TFM_HAL_ITS_SECTORS_PER_BLOCK (1) +/* Smallest flash programmable unit in bytes */ +#define TFM_HAL_ITS_PROGRAM_UNIT (0x1) + +/* OTP / NV counter definitions */ +#define TFM_OTP_NV_COUNTERS_AREA_SIZE (FLASH_OTP_NV_COUNTERS_AREA_SIZE / 2) +#define TFM_OTP_NV_COUNTERS_AREA_ADDR FLASH_OTP_NV_COUNTERS_AREA_OFFSET +#define TFM_OTP_NV_COUNTERS_SECTOR_SIZE FLASH_OTP_NV_COUNTERS_SECTOR_SIZE +#define TFM_OTP_NV_COUNTERS_BACKUP_AREA_ADDR (TFM_OTP_NV_COUNTERS_AREA_ADDR + TFM_OTP_NV_COUNTERS_AREA_SIZE) + +#endif /* __FLASH_LAYOUT_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/partition/platform_base_address.h b/examples/platform/openiotsdk/tf-m/targets/an552/partition/platform_base_address.h new file mode 100644 index 00000000000000..236628cae7ed96 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/partition/platform_base_address.h @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2019-2022 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 AN552 MPS3 SSE-300 + + * Ethos-U55 platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H__ +#define __PLATFORM_BASE_ADDRESS_H__ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ITCM_BASE_NS 0x00000000 /* Instruction TCM Non-Secure base address */ +#define SRAM_BASE_NS 0x01000000 /* CODE SRAM Non-Secure base address */ +#define DTCM0_BASE_NS 0x20000000 /* Data TCM block 0 Non-Secure base address */ +#define DTCM1_BASE_NS 0x20020000 /* Data TCM block 1 Non-Secure base address */ +#define DTCM2_BASE_NS 0x20040000 /* Data TCM block 2 Non-Secure base address */ +#define DTCM3_BASE_NS 0x20060000 /* Data TCM block 3 Non-Secure base address */ +#define ISRAM0_BASE_NS 0x21000000 /* Internal SRAM Area Non-Secure base address */ +#define ISRAM1_BASE_NS 0x21100000 /* Internal SRAM Area Non-Secure base address */ +#define QSPI_SRAM_BASE_NS 0x28000000 /* QSPI SRAM Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */ +#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */ +#define SSE300_NSACFG_BASE_NS 0x40080000 /* SSE-300 Non-Secure Access Configuration Register Block Non-Secure base address */ +/* Non-Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_NS 0x41100000 /* GPIO 0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x41101000 /* GPIO 1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x41102000 /* GPIO 2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x41103000 /* GPIO 3 Non-Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_NS 0x41104000 /* FMC CMSDK GPIO 0 Non-Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_NS 0x41105000 /* FMC CMSDK GPIO 1 Non-Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_NS 0x41106000 /* FMC CMSDK GPIO 2 Non-Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_NS 0x41107000 /* FMC CMSDK GPIO 3 Non-Secure base address */ +#define EXTERNAL_MANAGER_0_BASE_NS 0x41200000 /* External manager 0 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_1_BASE_NS 0x41201000 /* External manager 1 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_2_BASE_NS 0x41202000 /* External manager 2 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_3_BASE_NS 0x41203000 /* External manager 3 (Unused) Non-Secure base address */ +#define ETHERNET_BASE_NS 0x41400000 /* Ethernet Non-Secure base address */ +#define USB_BASE_NS 0x41500000 /* USB Non-Secure base address */ +#define USER_APB0_BASE_NS 0x41700000 /* User APB 0 Non-Secure base address */ +#define USER_APB1_BASE_NS 0x41701000 /* User APB 1 Non-Secure base address */ +#define USER_APB2_BASE_NS 0x41702000 /* User APB 2 Non-Secure base address */ +#define USER_APB3_BASE_NS 0x41703000 /* User APB 3 Non-Secure base address */ +#define QSPI_CONFIG_BASE_NS 0x41800000 /* QSPI Config Non-Secure base address */ +#define QSPI_WRITE_BASE_NS 0x41801000 /* QSPI Write Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_NS 0x48000000 /* System Timer 0 Non-Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_NS 0x48001000 /* System Timer 1 Non-Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_NS 0x48002000 /* System Timer 2 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 3 Non-Secure base address */ +#define SSE300_SYSINFO_BASE_NS 0x48020000 /* SSE-300 System info Block Non-Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_NS 0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS 0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_NS 0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48101000 /* System Counter Read Secure base address */ +/* Non-Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_NS 0x48102000 /* Ethos-U55 APB Non-Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_NS 0x48103000 /* Ethos-U55 Timing Adapter 0 APB registers Non-Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_NS 0x48103200 /* Ethos-U55 Timing Adapter 1 APB registers Non-Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_NS 0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */ +#define FPGA_SPI_ADC_BASE_NS 0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_NS 0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_NS 0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_NS 0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_NS 0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */ +#define USER_APB_BASE_NS 0x49207000 /* USER APB Non-Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_NS 0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */ +#define FMC_USER_APB0 0x4920C000 /* FMC User APB0 */ +#define FMC_USER_APB1 0x4920D000 /* FMC User APB1 */ +#define FMC_USER_APB2 0x4920E000 /* FMC User APB2 */ +#define FMC_USER_APB3 0x4920F000 /* FMC User APB3 */ +#define FPGA_SCC_BASE_NS 0x49300000 /* FPGA - SCC registers Non-Secure base address */ +#define FPGA_I2S_BASE_NS 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */ +#define FPGA_IO_BASE_NS 0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */ +#define UART0_BASE_NS 0x49303000 /* UART 0 Non-Secure base address */ +#define UART1_BASE_NS 0x49304000 /* UART 1 Non-Secure base address */ +#define UART2_BASE_NS 0x49305000 /* UART 2 Non-Secure base address */ +#define UART3_BASE_NS 0x49306000 /* UART 3 Non-Secure base address */ +#define UART4_BASE_NS 0x49307000 /* UART 4 Non-Secure base address */ +#define UART5_BASE_NS 0x49308000 /* UART 5 Non-Secure base address */ +#define CLCD_Config_Reg_BASE_NS 0x4930A000 /* CLCD Config Reg Non-Secure base address */ +#define RTC_BASE_NS 0x4930B000 /* RTC Non-Secure base address */ +#define DDR4_BLK0_BASE_NS 0x60000000 /* DDR4 block 0 Non-Secure base address */ +#define DDR4_BLK2_BASE_NS 0x80000000 /* DDR4 block 2 Non-Secure base address */ +#define DDR4_BLK4_BASE_NS 0xA0000000 /* DDR4 block 4 Non-Secure base address */ +#define DDR4_BLK6_BASE_NS 0xC0000000 /* DDR4 block 6 Non-Secure base address */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define SRAM_BASE_S 0x11000000 /* CODE SRAM Secure base address */ +#define DTCM0_BASE_S 0x30000000 /* Data TCM block 0 Secure base address */ +#define DTCM1_BASE_S 0x30020000 /* Data TCM block 1 Secure base address */ +#define DTCM2_BASE_S 0x30040000 /* Data TCM block 2 Secure base address */ +#define DTCM3_BASE_S 0x30060000 /* Data TCM block 3 Secure base address */ +#define ISRAM0_BASE_S 0x31000000 /* Internal SRAM Area Secure base address */ +#define ISRAM1_BASE_S 0x31100000 /* Internal SRAM Area Secure base address */ +#define QSPI_SRAM_BASE_S 0x38000000 /* QSPI SRAM Secure base address */ +/* Secure Subsystem peripheral region */ +#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */ +#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */ +#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */ +#define SSE300_SACFG_BASE_S 0x50080000 /* SSE-300 Secure Access Configuration Register Secure base address */ +#define MPC_ISRAM0_BASE_S 0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */ +#define MPC_ISRAM1_BASE_S 0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */ +/* Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_S 0x51100000 /* GPIO 0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x51101000 /* GPIO 1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x51102000 /* GPIO 2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x51103000 /* GPIO 3 Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_S 0x51104000 /* FMC CMSDK GPIO 0 Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_S 0x51105000 /* FMC CMSDK GPIO 1 Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_S 0x51106000 /* FMC CMSDK GPIO 2 Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_S 0x51107000 /* FMC CMSDK GPIO 3 Secure base address */ +#define EXTERNAL_MANAGER0_BASE_S 0x51200000 /* External Manager 0 (Unused) Secure base address */ +#define EXTERNAL_MANAGER1_BASE_S 0x51201000 /* External Manager 1 (Unused) Secure base address */ +#define EXTERNAL_MANAGER2_BASE_S 0x51202000 /* External Manager 2 (Unused) Secure base address */ +#define EXTERNAL_MANAGER3_BASE_S 0x51203000 /* External Manager 3 (Unused) Secure base address */ +#define ETHERNET_BASE_S 0x51400000 /* Ethernet Secure base address */ +#define USB_BASE_S 0x51500000 /* USB Secure base address */ +#define USER_APB0_BASE_S 0x51700000 /* User APB 0 Secure base address */ +#define USER_APB1_BASE_S 0x51701000 /* User APB 1 Secure base address */ +#define USER_APB2_BASE_S 0x51702000 /* User APB 2 Secure base address */ +#define USER_APB3_BASE_S 0x51703000 /* User APB 3 Secure base address */ +#define QSPI_CONFIG_BASE_S 0x51800000 /* QSPI Config Secure base address */ +#define QSPI_WRITE_BASE_S 0x51801000 /* QSPI Write Secure base address */ +#define MPC_SRAM_BASE_S 0x57000000 /* SRAM Memory Protection Controller Secure base address */ +#define MPC_QSPI_BASE_S 0x57001000 /* QSPI Memory Protection Controller Secure base address */ +#define MPC_DDR4_BASE_S 0x57002000 /* DDR4 Memory Protection Controller Secure base address */ +/* Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_S 0x58000000 /* System Timer 0 Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_S 0x58001000 /* System Timer 1 Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_S 0x58002000 /* System Timer 0 Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_S 0x58003000 /* System Timer 1 Secure base address */ +#define SSE300_SYSINFO_BASE_S 0x58020000 /* SSE-300 System info Block Secure base address */ +#define SSE300_SYSCTRL_BASE_S 0x58021000 /* SSE-300 System control Block Secure base address */ +#define SSE300_SYSPPU_BASE_S 0x58022000 /* SSE-300 System Power Policy Unit Secure base address */ +#define SSE300_CPU0PPU_BASE_S 0x58023000 /* SSE-300 CPU 0 Power Policy Unit Secure base address */ +#define SSE300_MGMTPPU_BASE_S 0x58028000 /* SSE-300 Management Power Policy Unit Secure base address */ +#define SSE300_DBGPPU_BASE_S 0x58029000 /* SSE-300 Debug Power Policy Unit Secure base address */ +#define SLOWCLK_WDOG_CMSDK_BASE_S 0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_S 0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_S 0x58040000 /* Secure Watchdog Timer control frame Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_S 0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58100000 /* System Counter Control Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58101000 /* System Counter Read Secure base address */ +/* Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_S 0x58102000 /* Ethos-U55 APB Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_S 0x58103000 /* Ethos-U55 Timing Adapter 0 APB registers Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_S 0x58103200 /* Ethos-U55 Timing Adapter 1 APB registers Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_S 0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */ +#define FPGA_SPI_ADC_BASE_S 0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_S 0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_S 0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_S 0x59205000 /* SBCon (I2C - Shield0) Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_S 0x59206000 /* SBCon (I2C – Shield1) Secure base address */ +#define USER_APB_BASE_S 0x59207000 /* USER APB Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_S 0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */ +#define FMC_USER_APB_0_BASE_S 0x5920C000 /* FMC User APB0 registers Secure base address */ +#define FMC_USER_APB_1_BASE_S 0x5920D000 /* FMC User APB1 registers Secure base address */ +#define FMC_USER_APB_2_BASE_S 0x5920E000 /* FMC User APB2 registers Secure base address */ +#define FMC_USER_APB_3_BASE_S 0x5920F000 /* FMC User APB3 registers Secure base address */ +#define FPGA_SCC_BASE_S 0x59300000 /* FPGA - SCC registers Secure base address */ +#define FPGA_I2S_BASE_S 0x59301000 /* FPGA - I2S (Audio) Secure base address */ +#define FPGA_IO_BASE_S 0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */ +#define UART0_BASE_S 0x59303000 /* UART 0 Secure base address */ +#define UART1_BASE_S 0x59304000 /* UART 1 Secure base address */ +#define UART2_BASE_S 0x59305000 /* UART 2 Secure base address */ +#define UART3_BASE_S 0x59306000 /* UART 3 Secure base address */ +#define UART4_BASE_S 0x59307000 /* UART 4 Secure base address */ +#define UART5_BASE_S 0x59308000 /* UART 5 Secure base address */ +#define CLCD_Config_Reg_BASE_S 0x5930A000 /* CLCD Config Reg Secure base address */ +#define RTC_BASE_S 0x5930B000 /* RTC Secure base address */ +#define DDR4_BLK1_BASE_S 0x70000000 /* DDR4 block 1 Secure base address */ +#define DDR4_BLK3_BASE_S 0x90000000 /* DDR4 block 3 Secure base address */ +#define DDR4_BLK5_BASE_S 0xB0000000 /* DDR4 block 5 Secure base address */ +#define DDR4_BLK7_BASE_S 0xD0000000 /* DDR4 block 7 Secure base address */ + +/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */ +#define SSE300_EWIC_BASE \ + 0xE0047000 /* External Wakeup Interrupt Controller \ + * Access from Non-secure software is only allowed \ + * if AIRCR.BFHFNMINS is set to 1 */ + +/* Memory size definitions */ +#define ITCM_SIZE (0x00080000) /* 512 kB */ +#define DTCM_BLK_SIZE (0x00020000) /* 128 kB */ +#define DTCM_BLK_NUM (0x4) /* Number of DTCM blocks */ +#define SRAM_SIZE (0x00100000) /* 1 MB */ +#define ISRAM0_SIZE (0x00100000) /* 1 MB */ +#define ISRAM1_SIZE (0x00100000) /* 1 MB */ +#define QSPI_SRAM_SIZE (0x00800000) /* 8 MB */ +#define DDR4_BLK_SIZE (0x10000000) /* 256 MB */ +#define DDR4_BLK_NUM (0x8) /* Number of DDR4 blocks */ + +/* Defines for Driver MPC's */ +/* SRAM -- 1 MB */ +#define MPC_SRAM_RANGE_BASE_NS (SRAM_BASE_NS) +#define MPC_SRAM_RANGE_LIMIT_NS (SRAM_BASE_NS + SRAM_SIZE - 1) +#define MPC_SRAM_RANGE_OFFSET_NS (0x0) +#define MPC_SRAM_RANGE_BASE_S (SRAM_BASE_S) +#define MPC_SRAM_RANGE_LIMIT_S (SRAM_BASE_S + SRAM_SIZE - 1) +#define MPC_SRAM_RANGE_OFFSET_S (0x0) + +/* QSPI -- 8 MB*/ +#define MPC_QSPI_RANGE_BASE_NS (QSPI_SRAM_BASE_NS) +#define MPC_QSPI_RANGE_LIMIT_NS (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE - 1) +#define MPC_QSPI_RANGE_OFFSET_NS (0x0) +#define MPC_QSPI_RANGE_BASE_S (QSPI_SRAM_BASE_S) +#define MPC_QSPI_RANGE_LIMIT_S (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE - 1) +#define MPC_QSPI_RANGE_OFFSET_S (0x0) + +/* ISRAM0 -- 1 MB*/ +#define MPC_ISRAM0_RANGE_BASE_NS (ISRAM0_BASE_NS) +#define MPC_ISRAM0_RANGE_LIMIT_NS (ISRAM0_BASE_NS + ISRAM0_SIZE - 1) +#define MPC_ISRAM0_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM0_RANGE_BASE_S (ISRAM0_BASE_S) +#define MPC_ISRAM0_RANGE_LIMIT_S (ISRAM0_BASE_S + ISRAM0_SIZE - 1) +#define MPC_ISRAM0_RANGE_OFFSET_S (0x0) + +/* ISRAM1 -- 1 MB*/ +#define MPC_ISRAM1_RANGE_BASE_NS (ISRAM1_BASE_NS) +#define MPC_ISRAM1_RANGE_LIMIT_NS (ISRAM1_BASE_NS + ISRAM1_SIZE - 1) +#define MPC_ISRAM1_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM1_RANGE_BASE_S (ISRAM1_BASE_S) +#define MPC_ISRAM1_RANGE_LIMIT_S (ISRAM1_BASE_S + ISRAM1_SIZE - 1) +#define MPC_ISRAM1_RANGE_OFFSET_S (0x0) + +/* DDR4 -- 2GB (8 * 256 MB) */ +#define MPC_DDR4_BLK0_RANGE_BASE_NS (DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK0_RANGE_LIMIT_NS (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK0_RANGE_OFFSET_NS (0x0) +#define MPC_DDR4_BLK1_RANGE_BASE_S (DDR4_BLK1_BASE_S) +#define MPC_DDR4_BLK1_RANGE_LIMIT_S (DDR4_BLK1_BASE_S + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK1_RANGE_OFFSET_S (DDR4_BLK1_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_BASE_NS (DDR4_BLK2_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_LIMIT_NS (DDR4_BLK2_BASE_NS + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK2_RANGE_OFFSET_NS (DDR4_BLK2_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK3_RANGE_BASE_S (DDR4_BLK3_BASE_S) +#define MPC_DDR4_BLK3_RANGE_LIMIT_S (DDR4_BLK3_BASE_S + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK3_RANGE_OFFSET_S (DDR4_BLK3_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_BASE_NS (DDR4_BLK4_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_LIMIT_NS (DDR4_BLK4_BASE_NS + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK4_RANGE_OFFSET_NS (DDR4_BLK4_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK5_RANGE_BASE_S (DDR4_BLK5_BASE_S) +#define MPC_DDR4_BLK5_RANGE_LIMIT_S (DDR4_BLK5_BASE_S + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK5_RANGE_OFFSET_S (DDR4_BLK5_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_BASE_NS (DDR4_BLK6_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_LIMIT_NS (DDR4_BLK6_BASE_NS + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK6_RANGE_OFFSET_NS (DDR4_BLK6_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK7_RANGE_BASE_S (DDR4_BLK7_BASE_S) +#define MPC_DDR4_BLK7_RANGE_LIMIT_S (DDR4_BLK7_BASE_S + ((DDR4_BLK_SIZE) -1)) +#define MPC_DDR4_BLK7_RANGE_OFFSET_S (DDR4_BLK7_BASE_S - DDR4_BLK0_BASE_NS) + +#endif /* __PLATFORM_BASE_ADDRESS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/partition/region_defs.h b/examples/platform/openiotsdk/tf-m/targets/an552/partition/region_defs.h new file mode 100755 index 00000000000000..d124a00450785e --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/partition/region_defs.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "flash_layout.h" +#include "platform_base_address.h" + +#define BL2_HEAP_SIZE (0x0001000) +#define BL2_MSP_STACK_SIZE (0x0001800) + +#ifdef ENABLE_HEAP +#define S_HEAP_SIZE (0x0000200) +#endif + +#define S_MSP_STACK_SIZE (0x0000800) +#define S_PSP_STACK_SIZE (0x0000800) + +#define NS_HEAP_SIZE (0x0008000) +#define NS_STACK_SIZE (0x0002000) + +/* 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) + +#ifdef BL2 +#ifndef LINK_TO_SECONDARY_PARTITION +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET) +#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET) +#else +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET) +#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET) +#endif /* !LINK_TO_SECONDARY_PARTITION */ +#else +#define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0) +#endif /* BL2 */ + +#ifndef LINK_TO_SECONDARY_PARTITION +#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET + FLASH_S_PARTITION_SIZE) +#else +#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET + FLASH_S_PARTITION_SIZE) +#endif /* !LINK_TO_SECONDARY_PARTITION */ + +/* Boot partition structure if MCUBoot is used: + * 0x0_0000 Bootloader header + * 0x0_0400 Image area + * 0x5_0000 Trailer + */ +/* IMAGE_CODE_SIZE is the space available for the software binary image. + * It is less than the FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE + * because we reserve space for the image header and trailer introduced + * by the bootloader. + */ +#if (!defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)) && \ + (NS_IMAGE_PRIMARY_PARTITION_OFFSET > S_IMAGE_PRIMARY_PARTITION_OFFSET) +/* If secure image and nonsecure image are concatenated, and nonsecure image + * locates at the higher memory range, then the secure image does not need + * the trailer area. + */ +#define IMAGE_S_CODE_SIZE (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE) +#else +#define IMAGE_S_CODE_SIZE (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE) +#endif + +#define IMAGE_NS_CODE_SIZE (FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE) + +/* Secure regions */ +#define S_IMAGE_PRIMARY_AREA_OFFSET (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) +/* Secure Code stored in Code SRAM */ +#define S_CODE_START ((QSPI_SRAM_BASE_S) + (S_IMAGE_PRIMARY_AREA_OFFSET)) +#define S_CODE_SIZE (IMAGE_S_CODE_SIZE) +#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1) + +/* Secure Data stored in DTCM */ +#define S_DATA_START (DTCM0_BASE_S) +#define S_DATA_SIZE (DTCM_BLK_SIZE * DTCM_BLK_NUM) +#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1) + +/* Size of vector table: 146 interrupt handlers + 4 bytes MPS initial value */ +#define S_CODE_VECTOR_TABLE_SIZE (0x24C) + +/* Non-secure regions */ +#define NS_IMAGE_PRIMARY_AREA_OFFSET (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE) +/* Non-Secure Code stored in Code SRAM memory */ +#define NS_CODE_START (QSPI_SRAM_BASE_NS + (NS_IMAGE_PRIMARY_AREA_OFFSET)) +#define NS_CODE_SIZE (IMAGE_NS_CODE_SIZE) +#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1) + +/* Non-Secure Data stored in ISRAM0 */ +#define NS_DATA_START (ISRAM0_BASE_NS) +#define NS_DATA_SIZE (ISRAM0_SIZE) +#define NS_DATA_LIMIT (NS_DATA_START + NS_DATA_SIZE - 1) + +/* NS partition information is used for MPC and SAU configuration */ +#define NS_PARTITION_START ((QSPI_SRAM_BASE_NS) + (NS_IMAGE_PRIMARY_PARTITION_OFFSET)) +#define NS_PARTITION_SIZE (FLASH_NS_PARTITION_SIZE) + +/* Secondary partition for new images in case of firmware upgrade */ +#define SECONDARY_PARTITION_START ((QSPI_SRAM_BASE_NS) + (S_IMAGE_SECONDARY_PARTITION_OFFSET)) +#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) + +#ifdef BL2 +/* Bootloader regions */ +/* Use ITCM to store Bootloader */ +#define BL2_CODE_START (ITCM_BASE_S) +#define BL2_CODE_SIZE (ITCM_SIZE) +#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1) + +/* Bootloader uses same memory as for secure image */ +#define BL2_DATA_START (S_DATA_START) +#define BL2_DATA_SIZE (S_DATA_SIZE) +#define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1) +#endif /* BL2 */ + +/* Shared data area between bootloader and runtime firmware. + * Shared data area is allocated at the beginning of the RAM, it is overlapping + * with TF-M Secure code's MSP stack + */ +#define BOOT_TFM_SHARED_DATA_BASE S_DATA_START +#define BOOT_TFM_SHARED_DATA_SIZE (0x400) +#define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + BOOT_TFM_SHARED_DATA_SIZE - 1) + +#endif /* __REGION_DEFS_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/plat_test.c b/examples/platform/openiotsdk/tf-m/targets/an552/plat_test.c new file mode 100755 index 00000000000000..e10a3066660d20 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/plat_test.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "cmsis.h" +#include "device_definition.h" +#include "systimer_armv8-m_drv.h" +#include "tfm_plat_test.h" + +/* Interrupt interval is set to 1 ms */ +#define TIMER_RELOAD_VALUE (SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ / 1000) + +void tfm_plat_test_secure_timer_start(void) +{ + systimer_armv8_m_init(&SYSTIMER0_ARMV8_M_DEV_S); + 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_enable_interrupt(&SYSTIMER0_ARMV8_M_DEV_S); +} + +void tfm_plat_test_secure_timer_clear_intr(void) +{ + systimer_armv8_m_clear_autoinc_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); +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/preload.cmake b/examples/platform/openiotsdk/tf-m/targets/an552/preload.cmake new file mode 100755 index 00000000000000..2933c1ec1d3a51 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/preload.cmake @@ -0,0 +1,16 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021-2022, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +# preload.cmake is used to set things that related to the platform that are both +# immutable and global, which is to say they should apply to any kind of project +# that uses this platform. In practise this is normally compiler definitions and +# variables related to hardware. + +# Set architecture and CPU +set(TFM_SYSTEM_PROCESSOR cortex-m55) +set(TFM_SYSTEM_ARCHITECTURE armv8.1-m.main) +set(CONFIG_TFM_FP_ARCH "fpv5-d16") diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/services/src/tfm_platform_system.c b/examples/platform/openiotsdk/tf-m/targets/an552/services/src/tfm_platform_system.c new file mode 100644 index 00000000000000..3e9e10acd3ddd9 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/services/src/tfm_platform_system.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "tfm_platform_system.h" +#include "cmsis.h" +#include "target_cfg.h" +#include "tfm_hal_platform.h" + +void tfm_platform_hal_system_reset(void) +{ + __disable_irq(); + tfm_hal_system_reset(); +} + +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/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.c b/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.c new file mode 100755 index 00000000000000..9b0338b38c8532 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.c @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2019-2022 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_SSE300_PPC.h" +#include "cmsis.h" +#include "device_definition.h" +#include "region.h" +#include "region_defs.h" +#include "syscounter_armv8-m_cntrl_drv.h" +#include "tfm_plat_defs.h" +#include "uart_stdout.h" +#include "utilities.h" + +/* Throw out bus error when an access causes security violation */ +#define CMSDK_SECRESPCFG_BUS_ERR_MASK (1UL << 0) + +/* The section names come from the scatter file */ +REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base); +REGION_DECLARE(Image$$, ER_VENEER, $$Base); +REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit); + +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(Image$$, ER_VENEER, $$Base), + .veneer_limit = (uint32_t) ®ION_NAME(Image$$, VENEER_ALIGN, $$Limit), +}; + +/* Configures the RAM region to NS callable in sacfg block's nsccfg register */ +#define RAMNSC 0x2 +/* Configures the CODE region to NS callable in sacfg block's nsccfg register */ +#define CODENSC 0x1 + +/* Import MPC drivers */ +extern ARM_DRIVER_MPC Driver_ISRAM0_MPC; +extern ARM_DRIVER_MPC Driver_ISRAM1_MPC; +extern ARM_DRIVER_MPC Driver_SRAM_MPC; +extern ARM_DRIVER_MPC Driver_QSPI_MPC; + +/* Import PPC drivers */ +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP2; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_MAIN_EXP3; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP0; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP1; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP2; +extern DRIVER_PPC_SSE300 Driver_PPC_SSE300_PERIPH_EXP3; + +/* Define Peripherals NS address range for the platform */ +#define PERIPHERALS_BASE_NS_START (0x40000000) +#define PERIPHERALS_BASE_NS_END (0x4FFFFFFF) + +/* Enable system reset request for CPU 0 */ +#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 8U) + +/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field, + * otherwise the processor ignores the write. + */ +#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)) + +/* Debug configuration flags */ +#define SPNIDEN_SEL_STATUS (0x01u << 7) +#define SPNIDEN_STATUS (0x01u << 6) +#define SPIDEN_SEL_STATUS (0x01u << 5) +#define SPIDEN_STATUS (0x01u << 4) +#define NIDEN_SEL_STATUS (0x01u << 3) +#define NIDEN_STATUS (0x01u << 2) +#define DBGEN_SEL_STATUS (0x01u << 1) +#define DBGEN_STATUS (0x01u << 0) + +#define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | NIDEN_SEL_STATUS | DBGEN_SEL_STATUS) + +static DRIVER_PPC_SSE300 * const ppc_bank_drivers[] = { + &Driver_PPC_SSE300_MAIN0, &Driver_PPC_SSE300_MAIN_EXP0, &Driver_PPC_SSE300_MAIN_EXP1, &Driver_PPC_SSE300_MAIN_EXP2, + &Driver_PPC_SSE300_MAIN_EXP3, &Driver_PPC_SSE300_PERIPH0, &Driver_PPC_SSE300_PERIPH1, &Driver_PPC_SSE300_PERIPH_EXP0, + &Driver_PPC_SSE300_PERIPH_EXP1, &Driver_PPC_SSE300_PERIPH_EXP2, &Driver_PPC_SSE300_PERIPH_EXP3, +}; + +#define PPC_BANK_COUNT (sizeof(ppc_bank_drivers) / sizeof(ppc_bank_drivers[0])) + +enum tfm_plat_err_t enable_fault_handlers(void) +{ + /* Explicitly set secure fault priority to the highest */ + NVIC_SetPriority(SecureFault_IRQn, 0); + + /* Enables BUS, MEM, USG and Secure faults */ + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_SECUREFAULTENA_Msk; + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t system_reset_cfg(void) +{ + struct sse300_sysctrl_t * sysctrl = (struct sse300_sysctrl_t *) SSE300_SYSCTRL_BASE_S; + uint32_t reg_value = SCB->AIRCR; + + /* Enable system reset request for CPU 0, to be triggered via + * NVIC_SystemReset function. + */ + sysctrl->reset_mask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST; + + /* Clear SCB_AIRCR_VECTKEY value */ + reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk); + + /* Enable system reset request only to the secure world */ + reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk); + + SCB->AIRCR = reg_value; + + return TFM_PLAT_ERR_SUCCESS; +} + +/*--------------------- NVIC interrupt NS/S configuration --------------------*/ +enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) +{ + uint8_t i; + + /* Target every interrupt to NS; unimplemented interrupts will be WI */ + for (i = 0; i < (sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0])); i++) + { + NVIC->ITNS[i] = 0xFFFFFFFF; + } + + /* Make sure that MPC and PPC are targeted to S state */ + NVIC_ClearTargetState(MPC_IRQn); + NVIC_ClearTargetState(PPC_IRQn); + +#ifdef SECURE_UART1 + /* UART1 is a secure peripheral, so its IRQs have to target S state */ + NVIC_ClearTargetState(UARTRX1_IRQn); + NVIC_ClearTargetState(UARTTX1_IRQn); +#endif + + return TFM_PLAT_ERR_SUCCESS; +} + +/*----------------- NVIC interrupt enabling for S peripherals ----------------*/ +enum tfm_plat_err_t nvic_interrupt_enable(void) +{ + int32_t ret = ARM_DRIVER_OK; + int32_t i = 0; + + /* MPC interrupt enabling */ + mpc_clear_irq(); + ret = Driver_ISRAM0_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Enable MPC interrupt for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_SRAM_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Enable MPC interrupt for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + ret = Driver_QSPI_MPC.EnableInterrupt(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Enable MPC interrupt for QSPI!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + NVIC_ClearPendingIRQ(MPC_IRQn); + NVIC_EnableIRQ(MPC_IRQn); + + /* PPC interrupt enabling */ + ppc_clear_irq(); + + for (i = 0; i < PPC_BANK_COUNT; i++) + { + ret = ppc_bank_drivers[i]->EnableInterrupt(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Enable interrupt on PPC"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + } + + NVIC_ClearPendingIRQ(PPC_IRQn); + NVIC_EnableIRQ(PPC_IRQn); + +#ifdef PSA_FF_TEST_SECURE_UART2 + NVIC_EnableIRQ(FF_TEST_UART_IRQ); +#endif + return TFM_PLAT_ERR_SUCCESS; +} + +enum tfm_plat_err_t init_debug(void) +{ + struct sse300_sysctrl_t * sysctrl = (struct sse300_sysctrl_t *) SSE300_SYSCTRL_BASE_S; + +#if defined(DAUTH_NONE) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 0 */ + sysctrl->secdbgclr = DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_NS_ONLY) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set the debug enable bits to 1 for NS, and 0 for S mode */ + sysctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS; + sysctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS; +#elif defined(DAUTH_FULL) + /* Set all the debug enable selector bits to 1 */ + sysctrl->secdbgset = All_SEL_STATUS; + /* Set all the debug enable bits to 1 */ + sysctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS; +#else + +#if !defined(DAUTH_CHIP_DEFAULT) +#error "No debug authentication setting is provided." +#endif + + /* Set all the debug enable selector bits to 0 */ + sysctrl->secdbgclr = All_SEL_STATUS; + + /* No need to set any enable bits because the value depends on + * input signals. + */ +#endif + return TFM_PLAT_ERR_SUCCESS; +} + +/*------------------- SAU/IDAU configuration functions -----------------------*/ +void sau_and_idau_cfg(void) +{ + struct sse300_sacfg_t * sacfg = (struct sse300_sacfg_t *) SSE300_SACFG_BASE_S; + + /* Enables SAU */ + TZ_SAU_Enable(); + + /* Configures SAU regions to be non-secure */ + SAU->RNR = 0; + SAU->RBAR = (memory_regions.non_secure_partition_base & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.non_secure_partition_limit & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + SAU->RNR = 1; + SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (NS_DATA_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Configures veneers region to be non-secure callable */ + SAU->RNR = 2; + SAU->RBAR = (memory_regions.veneer_base & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk; + + /* Configure the peripherals space */ + SAU->RNR = 3; + SAU->RBAR = (PERIPHERALS_BASE_NS_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Configure the peripherals space */ + SAU->RNR = 4; + SAU->RBAR = (MPC_SRAM_RANGE_BASE_NS & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (MPC_SRAM_RANGE_LIMIT_NS & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Allows SAU to define the CODE region as a NSC */ + sacfg->nsccfg |= RAMNSC; +} + +/*------------------- Memory configuration functions -------------------------*/ +enum tfm_plat_err_t mpc_init_cfg(void) +{ + int32_t ret = ARM_DRIVER_OK; + + /* ISRAM0 is allocated for NS data, so whole range is set to non-secure + * accesible. */ + ret = Driver_ISRAM0_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Initialize MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_ISRAM0_MPC.ConfigRegion(MPC_ISRAM0_RANGE_BASE_NS, MPC_ISRAM0_RANGE_LIMIT_NS, ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Configure MPC for ISRAM0!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Configuring additional flash partition. */ + ret = Driver_SRAM_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Initialize MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_SRAM_MPC.ConfigRegion(MPC_SRAM_RANGE_BASE_NS, MPC_SRAM_RANGE_LIMIT_NS, ARM_MPC_ATTR_NONSECURE); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Configure MPC for SRAM!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Configuring primary non-secure partition. */ + ret = Driver_QSPI_MPC.Initialize(); + if (ret != ARM_DRIVER_OK) + { + ERROR_MSG("Failed to Initialize MPC for QSPI!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + ret = Driver_QSPI_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 QSPI!"); + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + /* Lock down not used MPC's */ + Driver_ISRAM1_MPC.LockDown(); + + /* SRAM and ISRAM0 MPCs left unlocked as they are not reset if NVIC system + * reset asserted. + */ + + /* Add barriers to assure the MPC configuration is done before continue + * the execution. + */ + __DSB(); + __ISB(); + + return TFM_PLAT_ERR_SUCCESS; +} + +void mpc_revert_non_secure_to_secure_cfg(void) +{ + Driver_ISRAM0_MPC.ConfigRegion(MPC_ISRAM0_RANGE_BASE_S, MPC_ISRAM0_RANGE_LIMIT_S, ARM_MPC_ATTR_SECURE); + + Driver_SRAM_MPC.ConfigRegion(MPC_SRAM_RANGE_BASE_S, MPC_SRAM_RANGE_LIMIT_S, ARM_MPC_ATTR_SECURE); + + Driver_QSPI_MPC.ConfigRegion(MPC_QSPI_RANGE_BASE_S, MPC_QSPI_RANGE_LIMIT_S, ARM_MPC_ATTR_SECURE); + + /* Add barriers to assure the MPC configuration is done before continue + * the execution. + */ + __DSB(); + __ISB(); +} + +void mpc_clear_irq(void) +{ + Driver_ISRAM0_MPC.ClearInterrupt(); + Driver_SRAM_MPC.ClearInterrupt(); + Driver_QSPI_MPC.ClearInterrupt(); +} + +/*------------------- PPC configuration functions -------------------------*/ +enum tfm_plat_err_t ppc_init_cfg(void) +{ + struct sse300_sacfg_t * sacfg = (struct sse300_sacfg_t *) SSE300_SACFG_BASE_S; + int32_t err = ARM_DRIVER_OK; + + /* Grant non-secure access to peripherals on MAIN EXP0 */ + err |= Driver_PPC_SSE300_MAIN_EXP0.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity(GPIO0_MAIN_PPCEXP0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity(GPIO1_MAIN_PPCEXP0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity(GPIO2_MAIN_PPCEXP0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity(GPIO3_MAIN_PPCEXP0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP0.ConfigSecurity(USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on MAIN EXP1 */ + err |= Driver_PPC_SSE300_MAIN_EXP1.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity(AHB_USER1_MAIN_PPCEXP1_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity(AHB_USER2_MAIN_PPCEXP1_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_MAIN_EXP1.ConfigSecurity(AHB_USER3_MAIN_PPCEXP1_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH0 */ + err |= Driver_PPC_SSE300_PERIPH0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(WATCHDOG_PERIPH_PPC0_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH1 */ + err |= Driver_PPC_SSE300_PERIPH1.Initialize(); + err |= Driver_PPC_SSE300_PERIPH1.ConfigSecurity(SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + + /* Grant non-secure access to peripherals on PERIPH EXP2 */ + err |= Driver_PPC_SSE300_PERIPH_EXP2.Initialize(); + + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(FPGA_I2S_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(FPGA_IO_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART0_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART1_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART2_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART3_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART4_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(UART5_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigSecurity(CLCD_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG); + + /* Grant un-privileged access for UART0 in NS domain */ + err |= Driver_PPC_SSE300_PERIPH_EXP2.ConfigPrivilege(UART0_PERIPH_PPCEXP2_POS_MASK, PPC_SSE300_NONSECURE_CONFIG, + PPC_SSE300_PRIV_AND_NONPRIV_CONFIG); + + /* Initialize not used PPC drivers */ + err |= Driver_PPC_SSE300_MAIN0.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP2.Initialize(); + err |= Driver_PPC_SSE300_MAIN_EXP3.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP0.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP1.Initialize(); + err |= Driver_PPC_SSE300_PERIPH_EXP3.Initialize(); + + /* + * Configure the response to a security violation as a + * bus error instead of RAZ/WI + */ + sacfg->secrespcfg |= CMSDK_SECRESPCFG_BUS_ERR_MASK; + + if (err != ARM_DRIVER_OK) + { + return TFM_PLAT_ERR_SYSTEM_ERR; + } + + return TFM_PLAT_ERR_SUCCESS; +} + +void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 * ppc_driver; + + if (bank >= PPC_BANK_COUNT) + { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) + { + ppc_driver->ConfigSecurity(pos, PPC_SSE300_SECURE_CONFIG); + } +} + +void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 * ppc_driver; + + if (bank >= PPC_BANK_COUNT) + { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) + { + ppc_driver->ConfigSecurity(pos, PPC_SSE300_NONSECURE_CONFIG); + } +} + +void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 * ppc_driver; + + if (bank >= PPC_BANK_COUNT) + { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) + { + ppc_driver->ConfigPrivilege(pos, PPC_SSE300_SECURE_CONFIG, PPC_SSE300_PRIV_AND_NONPRIV_CONFIG); + } +} + +void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos) +{ + DRIVER_PPC_SSE300 * ppc_driver; + + if (bank >= PPC_BANK_COUNT) + { + return; + } + + ppc_driver = ppc_bank_drivers[bank]; + if (ppc_driver) + { + ppc_driver->ConfigPrivilege(pos, PPC_SSE300_SECURE_CONFIG, PPC_SSE300_PRIV_CONFIG); + } +} + +void ppc_clear_irq(void) +{ + int32_t i = 0; + + for (i = 0; i < PPC_BANK_COUNT; i++) + { + ppc_bank_drivers[i]->ClearInterrupt(); + } +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.h b/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.h new file mode 100644 index 00000000000000..8fc19a4589c910 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/target_cfg.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2019-2021 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 "tfm_peripherals_def.h" +#include "tfm_plat_defs.h" +#include + +#define TFM_DRIVER_STDIO Driver_USART0 +#define NS_DRIVER_STDIO Driver_USART0 + +/** + * \brief Defines the word offsets of Slave Peripheral Protection Controller + * Registers + */ +enum ppc_bank_e +{ + PPC_SP_DO_NOT_CONFIGURE = -1, + PPC_SP_MAIN0 = 0, + PPC_SP_MAIN_EXP0 = 1, + PPC_SP_MAIN_EXP1 = 2, + PPC_SP_MAIN_EXP2 = 3, + PPC_SP_MAIN_EXP3 = 4, + PPC_SP_PERIPH0 = 5, + PPC_SP_PERIPH1 = 6, + PPC_SP_PERIPH_EXP0 = 7, + PPC_SP_PERIPH_EXP1 = 8, + PPC_SP_PERIPH_EXP2 = 9, + PPC_SP_PERIPH_EXP3 = 10, +}; + +/** + * \brief Store the addresses of memory regions + */ +struct memory_region_limits +{ + uint32_t non_secure_code_start; + uint32_t non_secure_partition_base; + uint32_t non_secure_partition_limit; + uint32_t veneer_base; + uint32_t veneer_limit; +}; + +/** + * \brief Holds the data necessary to do isolation for a specific peripheral. + */ +struct platform_data_t +{ + uint32_t periph_start; + uint32_t periph_limit; + enum ppc_bank_e periph_ppc_bank; + int16_t periph_ppc_mask; +}; + +/** + * \brief Enables the fault handlers BusFault, UsageFault, + * MemManageFault and SecureFault. + */ +enum tfm_plat_err_t enable_fault_handlers(void); + +/** + * \brief Configures the system reset request properties + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t system_reset_cfg(void); + +/** + * \brief Configures all external interrupts to target the + * NS state, apart for the ones associated to secure + * peripherals (plus MPC and PPC) + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void); + +/** + * \brief This function enable the interrupts associated + * to the secure peripherals (plus MPC and PPC) + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t nvic_interrupt_enable(void); + +/** + * \brief Configures the system debug properties. + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t init_debug(void); + +/** + * \brief Configures the Memory Protection Controller. + * + * \return Returns error code. + */ +enum tfm_plat_err_t mpc_init_cfg(void); + +/** + * \brief Clear MPC interrupt. + */ +void mpc_clear_irq(void); + +/** + * \brief Configures the Peripheral Protection Controller. + */ +enum tfm_plat_err_t ppc_init_cfg(void); + +/** + * \brief Restict peripheral access to secure access only + * + * \note The function does not configure privilege + */ +void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Allow non-secure access to peripheral + * + * \note The function does not configure privilege + */ +void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Enable secure unprivileged access to peripheral + */ +void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Clear secure unprivileged access to peripheral + */ +void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint32_t pos); + +/** + * \brief Clears PPC interrupt. + */ +void ppc_clear_irq(void); + +/** + * \brief Configures SAU and IDAU. + */ +void sau_and_idau_cfg(void); + +/** + * \brief Sets to secure the initialized non-secure regions of + * the Memory Protection Controller. + */ +void mpc_revert_non_secure_to_secure_cfg(void); + +#endif /* __TARGET_CFG_H__ */ diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_isolation.c b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_isolation.c new file mode 100755 index 00000000000000..2083f80a1369ae --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_isolation.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2020-2022, Arm Limited. All rights reserved. + * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon + * company) or an affiliate of Cypress Semiconductor Corporation. All rights + * reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "tfm_hal_isolation.h" +#include "Driver_Common.h" +#include "array.h" +#include "cmsis.h" +#include "load/asset_defs.h" +#include "load/partition_defs.h" +#include "load/spm_load_api.h" +#include "mmio_defs.h" +#include "mpu_armv8m_drv.h" +#include "region.h" +#include "target_cfg.h" +#include "tfm_hal_defs.h" +#include "tfm_peripherals_def.h" +#include +#include +#include +#include + +/* It can be retrieved from the MPU_TYPE register. */ +#define MPU_REGION_NUM 16 +#define PROT_BOUNDARY_VAL ((1U << HANDLE_ATTR_PRIV_POS) & HANDLE_ATTR_PRIV_MASK) + +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT +static uint32_t n_configured_regions = 0; +struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE }; + +REGION_DECLARE(Image$$, ER_VENEER, $$Base); +REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit); +REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base); +REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$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); +#ifdef CONFIG_TFM_PARTITION_META +REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Base); +REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Limit); +#endif /* CONFIG_TFM_PARTITION_META */ + +const struct mpu_armv8m_region_cfg_t region_cfg[] = { + /* Veneer region */ + { 0, /* will be updated before using */ + (uint32_t) ®ION_NAME(Image$$, ER_VENEER, $$Base), (uint32_t) ®ION_NAME(Image$$, VENEER_ALIGN, $$Limit), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_XN_EXEC_OK, MPU_ARMV8M_AP_RO_PRIV_UNPRIV, MPU_ARMV8M_SH_NONE, +#ifdef TFM_PXN_ENABLE + MPU_ARMV8M_PRIV_EXEC_OK +#endif + }, + /* TFM Core unprivileged code region */ + { 0, /* will be updated before using */ + (uint32_t) ®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base), (uint32_t) ®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_XN_EXEC_OK, MPU_ARMV8M_AP_RO_PRIV_UNPRIV, MPU_ARMV8M_SH_NONE, +#ifdef TFM_PXN_ENABLE + MPU_ARMV8M_PRIV_EXEC_OK +#endif + }, + /* RO region */ + { 0, /* will be updated before using */ + (uint32_t) ®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base), (uint32_t) ®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base), + MPU_ARMV8M_MAIR_ATTR_CODE_IDX, MPU_ARMV8M_XN_EXEC_OK, MPU_ARMV8M_AP_RO_PRIV_UNPRIV, MPU_ARMV8M_SH_NONE, +#ifdef TFM_PXN_ENABLE +#if TFM_LVL == 1 + MPU_ARMV8M_PRIV_EXEC_OK +#else + MPU_ARMV8M_PRIV_EXEC_NEVER +#endif +#endif + }, + /* RW, ZI and stack as one region */ + { 0, /* will be updated before using */ + (uint32_t) ®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base), + (uint32_t) ®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base), MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_XN_EXEC_NEVER, + MPU_ARMV8M_AP_RW_PRIV_UNPRIV, MPU_ARMV8M_SH_NONE, +#ifdef TFM_PXN_ENABLE + MPU_ARMV8M_PRIV_EXEC_NEVER +#endif + }, +#ifdef CONFIG_TFM_PARTITION_META + /* TFM partition metadata pointer region */ + { 0, /* will be updated before using */ + (uint32_t) ®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Base), (uint32_t) ®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Limit), + MPU_ARMV8M_MAIR_ATTR_DATA_IDX, MPU_ARMV8M_XN_EXEC_NEVER, MPU_ARMV8M_AP_RW_PRIV_UNPRIV, MPU_ARMV8M_SH_NONE, +#ifdef TFM_PXN_ENABLE + MPU_ARMV8M_PRIV_EXEC_NEVER +#endif + } +#endif +}; +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + +enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(uintptr_t * p_spm_boundary) +{ +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT + struct mpu_armv8m_region_cfg_t localcfg; +#endif + /* Set up isolation boundaries between SPE and NSPE */ + sau_and_idau_cfg(); + if (mpc_init_cfg() != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + ppc_init_cfg(); + + /* Set up static isolation boundaries inside SPE */ +#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT + int32_t i; + + mpu_armv8m_clean(&dev_mpu_s); + + if (ARRAY_SIZE(region_cfg) > MPU_REGION_NUM) + { + return TFM_HAL_ERROR_GENERIC; + } + for (i = 0; i < ARRAY_SIZE(region_cfg); i++) + { + memcpy(&localcfg, ®ion_cfg[i], sizeof(localcfg)); + localcfg.region_nr = i; + if (mpu_armv8m_region_enable(&dev_mpu_s, (struct mpu_armv8m_region_cfg_t *) &localcfg) != MPU_ARMV8M_OK) + { + return TFM_HAL_ERROR_GENERIC; + } + } + n_configured_regions = i; + + mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE, HARDFAULT_NMI_ENABLE); +#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ + + *p_spm_boundary = (uintptr_t) PROT_BOUNDARY_VAL; + + return TFM_HAL_SUCCESS; +} + +/* + * Implementation of tfm_hal_bind_boundary() on AN552: + * + * The API encodes some attributes into a handle and returns it to SPM. + * The attributes include isolation boundaries, privilege, and MMIO information. + * When scheduler switches running partitions, SPM compares the handle between + * partitions to know if boundary update is necessary. If update is required, + * SPM passes the handle to platform to do platform settings and update + * isolation boundaries. + */ +enum tfm_hal_status_t tfm_hal_bind_boundary(const struct partition_load_info_t * p_ldinf, uintptr_t * p_boundary) +{ + uint32_t i, j; + bool privileged; + bool ns_agent; + uint32_t partition_attrs = 0; + const struct asset_desc_t * p_asset; + struct platform_data_t * plat_data_ptr; +#if TFM_LVL == 2 + struct mpu_armv8m_region_cfg_t localcfg; +#endif + if (!p_ldinf || !p_boundary) + { + return TFM_HAL_ERROR_GENERIC; + } + +#if TFM_LVL == 1 + privileged = true; +#else + privileged = IS_PARTITION_PSA_ROT(p_ldinf); +#endif + + ns_agent = IS_PARTITION_NS_AGENT(p_ldinf); + p_asset = LOAD_INFO_ASSET(p_ldinf); + + /* + * Validate if the named MMIO of partition is allowed by the platform. + * Otherwise, skip validation. + * + * NOTE: Need to add validation of numbered MMIO if platform requires. + */ + for (i = 0; i < p_ldinf->nassets; i++) + { + if (!(p_asset[i].attr & ASSET_ATTR_NAMED_MMIO)) + { + continue; + } + for (j = 0; j < ARRAY_SIZE(partition_named_mmio_list); j++) + { + if (p_asset[i].dev.dev_ref == partition_named_mmio_list[j]) + { + break; + } + } + + if (j == ARRAY_SIZE(partition_named_mmio_list)) + { + /* The MMIO asset is not in the allowed list of platform. */ + return TFM_HAL_ERROR_GENERIC; + } + /* Assume PPC & MPC settings are required even under level 1 */ + plat_data_ptr = REFERENCE_TO_PTR(p_asset[i].dev.dev_ref, struct platform_data_t *); + + if (plat_data_ptr->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) + { + ppc_configure_to_secure(plat_data_ptr->periph_ppc_bank, plat_data_ptr->periph_ppc_mask); + if (privileged) + { + ppc_clr_secure_unpriv(plat_data_ptr->periph_ppc_bank, plat_data_ptr->periph_ppc_mask); + } + else + { + ppc_en_secure_unpriv(plat_data_ptr->periph_ppc_bank, plat_data_ptr->periph_ppc_mask); + } + } +#if TFM_LVL == 2 + /* + * Static boundaries are set. Set up MPU region for MMIO. + * Setup regions for unprivileged assets only. + */ + if (!privileged) + { + localcfg.region_base = plat_data_ptr->periph_start; + localcfg.region_limit = plat_data_ptr->periph_limit; + localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX; + localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER; + localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV; + localcfg.attr_sh = MPU_ARMV8M_SH_NONE; +#ifdef TFM_PXN_ENABLE + localcfg.attr_pxn = MPU_ARMV8M_PRIV_EXEC_NEVER; +#endif + localcfg.region_nr = n_configured_regions++; + + if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) + { + return TFM_HAL_ERROR_GENERIC; + } + } +#endif + } + + partition_attrs = ((uint32_t) privileged << HANDLE_ATTR_PRIV_POS) & HANDLE_ATTR_PRIV_MASK; + partition_attrs |= ((uint32_t) ns_agent << HANDLE_ATTR_NS_POS) & HANDLE_ATTR_NS_MASK; + *p_boundary = (uintptr_t) partition_attrs; + + return TFM_HAL_SUCCESS; +} + +enum tfm_hal_status_t tfm_hal_activate_boundary(const struct partition_load_info_t * p_ldinf, uintptr_t boundary) +{ + CONTROL_Type ctrl; + bool privileged = !!((uint32_t) boundary & HANDLE_ATTR_PRIV_MASK); + + /* Privileged level is required to be set always */ + ctrl.w = __get_CONTROL(); + ctrl.b.nPRIV = privileged ? 0 : 1; + __set_CONTROL(ctrl.w); + + return TFM_HAL_SUCCESS; +} + +enum tfm_hal_status_t tfm_hal_memory_check(uintptr_t boundary, uintptr_t base, size_t size, uint32_t access_type) +{ + int flags = 0; + + /* If size is zero, this indicates an empty buffer and base is ignored */ + if (size == 0) + { + return TFM_HAL_SUCCESS; + } + + if (!base) + { + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if ((access_type & TFM_HAL_ACCESS_READWRITE) == TFM_HAL_ACCESS_READWRITE) + { + flags |= CMSE_MPU_READWRITE; + } + else if (access_type & TFM_HAL_ACCESS_READABLE) + { + flags |= CMSE_MPU_READ; + } + else + { + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if (!((uint32_t) boundary & HANDLE_ATTR_PRIV_MASK)) + { + flags |= CMSE_MPU_UNPRIV; + } + + if ((uint32_t) boundary & HANDLE_ATTR_NS_MASK) + { + CONTROL_Type ctrl; + ctrl.w = __TZ_get_CONTROL_NS(); + if (ctrl.b.nPRIV == 1) + { + flags |= CMSE_MPU_UNPRIV; + } + else + { + flags &= ~CMSE_MPU_UNPRIV; + } + flags |= CMSE_NONSECURE; + } + + if (cmse_check_address_range((void *) base, size, flags) != NULL) + { + return TFM_HAL_SUCCESS; + } + else + { + return TFM_HAL_ERROR_MEM_FAULT; + } +} + +bool tfm_hal_boundary_need_switch(uintptr_t boundary_from, uintptr_t boundary_to) +{ + if (boundary_from == boundary_to) + { + return false; + } + + if (((uint32_t) boundary_from & HANDLE_ATTR_PRIV_MASK) && ((uint32_t) boundary_to & HANDLE_ATTR_PRIV_MASK)) + { + return false; + } + return true; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_platform.c b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_platform.c new file mode 100755 index 00000000000000..e793615fddfe5d --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_hal_platform.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "tfm_hal_platform.h" +#include "cmsis.h" +#include "device_definition.h" +#include "target_cfg.h" +#include "tfm_peripherals_def.h" +#include "uart_stdout.h" +#if defined(TEST_NS_FPU) || defined(TEST_S_FPU) +#include "test_interrupt.h" +#endif + +/* Get address of memory regions to configure MPU */ +extern const struct memory_region_limits memory_regions; + +enum tfm_hal_status_t tfm_hal_platform_init(void) +{ + enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR; + enum syscounter_armv8_m_cntrl_error_t counter_err = SYSCOUNTER_ARMV8_M_ERR_NONE; + + plat_err = enable_fault_handlers(); + if (plat_err != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + + plat_err = system_reset_cfg(); + if (plat_err != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + + plat_err = init_debug(); + if (plat_err != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + + /* Syscounter enabled by default. This way App-RoT partitions can use + * systimers without the need to add the syscounter as an mmio divide. + */ + counter_err = syscounter_armv8_m_cntrl_init(&SYSCOUNTER_CNTRL_ARMV8_M_DEV_S); + if (counter_err != SYSCOUNTER_ARMV8_M_ERR_NONE) + { + return TFM_HAL_ERROR_GENERIC; + } + + __enable_irq(); + stdio_init(); + + plat_err = nvic_interrupt_target_state_cfg(); + if (plat_err != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + + plat_err = nvic_interrupt_enable(); + if (plat_err != TFM_PLAT_ERR_SUCCESS) + { + return TFM_HAL_ERROR_GENERIC; + } + +#if defined(TEST_S_FPU) || defined(TEST_NS_FPU) + /* Set IRQn in secure mode */ + NVIC_ClearTargetState(TFM_FPU_S_TEST_IRQ); + + /* Register FPU secure test interrupt handler */ + NVIC_SetVector(TFM_FPU_S_TEST_IRQ, (uint32_t) TFM_FPU_S_TEST_Handler); + + /* Enable FPU secure test interrupt */ + NVIC_EnableIRQ(TFM_FPU_S_TEST_IRQ); +#endif + +#if defined(TEST_NS_FPU) + /* Set IRQn in non-secure mode */ + NVIC_SetTargetState(TFM_FPU_NS_TEST_IRQ); +#endif + + return TFM_HAL_SUCCESS; +} + +uint32_t tfm_hal_get_ns_VTOR(void) +{ + return memory_regions.non_secure_code_start; +} + +uint32_t tfm_hal_get_ns_MSP(void) +{ + return *((uint32_t *) memory_regions.non_secure_code_start); +} + +uint32_t tfm_hal_get_ns_entry_point(void) +{ + return *((uint32_t *) (memory_regions.non_secure_code_start + 4)); +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/tfm_interrupts.c b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_interrupts.c new file mode 100755 index 00000000000000..cbd41dc221d4a6 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_interrupts.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon + * company) or an affiliate of Cypress Semiconductor Corporation. All rights + * reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include + +#include "cmsis.h" +#include "device_definition.h" +#include "ffm/interrupt.h" +#include "load/interrupt_defs.h" +#include "spm_ipc.h" +#include "tfm_hal_interrupt.h" +#include "tfm_peripherals_def.h" +#include "tfm_plat_test.h" + +static struct irq_t timer0_irq = { 0 }; + +void TFM_TIMER0_IRQ_Handler(void) +{ + spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer0_irq_init(void * p_pt, const struct irq_load_info_t * p_ildi) +{ + timer0_irq.p_ildi = p_ildi; + timer0_irq.p_pt = p_pt; + + NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY); + NVIC_ClearTargetState(TFM_TIMER0_IRQ); + NVIC_DisableIRQ(TFM_TIMER0_IRQ); + + return TFM_HAL_SUCCESS; +} diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.c b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.c new file mode 100755 index 00000000000000..511be4482ae156 --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "cmsis.h" +#include "target_cfg.h" + +struct platform_data_t tfm_peripheral_gpio0 = { GPIO0_CMSDK_BASE_S, GPIO0_CMSDK_BASE_S + 0xFFF, PPC_SP_MAIN_EXP0, + GPIO0_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_gpio1 = { GPIO1_CMSDK_BASE_S, GPIO1_CMSDK_BASE_S + 0xFFF, PPC_SP_MAIN_EXP0, + GPIO1_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_gpio2 = { GPIO2_CMSDK_BASE_S, GPIO2_CMSDK_BASE_S + 0xFFF, PPC_SP_MAIN_EXP0, + GPIO2_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_gpio3 = { GPIO3_CMSDK_BASE_S, GPIO3_CMSDK_BASE_S + 0xFFF, PPC_SP_MAIN_EXP0, + GPIO3_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio0 = { FMC_CMSDK_GPIO_0_BASE_S, FMC_CMSDK_GPIO_0_BASE_S + 0xFFF, + PPC_SP_MAIN_EXP1, FMC_GPIO0_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio1 = { FMC_CMSDK_GPIO_1_BASE_S, FMC_CMSDK_GPIO_1_BASE_S + 0xFFF, + PPC_SP_MAIN_EXP1, FMC_GPIO1_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio2 = { FMC_CMSDK_GPIO_2_BASE_S, FMC_CMSDK_GPIO_2_BASE_S + 0xFFF, + PPC_SP_MAIN_EXP1, FMC_GPIO2_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio3 = { FMC_CMSDK_GPIO_3_BASE_S, FMC_CMSDK_GPIO_3_BASE_S + 0xFFF, + PPC_SP_MAIN_EXP1, FMC_AHB_USER_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_ethernet = { ETHERNET_BASE_S, ETHERNET_BASE_S + 0xFFFFF, PPC_SP_MAIN_EXP0, + USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_usb = { USB_BASE_S, USB_BASE_S + 0xFFFFF, PPC_SP_MAIN_EXP0, + USB_AND_ETHERNET_MAIN_PPCEXP0_POS_MASK }; + +struct platform_data_t tfm_peripheral_timer0 = { SYSTIMER0_ARMV8_M_BASE_S, SYSTIMER0_ARMV8_M_BASE_S + 0xFFF, PPC_SP_PERIPH0, + SYSTEM_TIMER0_PERIPH_PPC0_POS_MASK }; + +struct platform_data_t tfm_peripheral_timer1 = { SYSTIMER1_ARMV8_M_BASE_S, SYSTIMER1_ARMV8_M_BASE_S + 0xFFF, PPC_SP_PERIPH0, + SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK }; + +struct platform_data_t tfm_peripheral_timer2 = { SYSTIMER2_ARMV8_M_BASE_S, SYSTIMER2_ARMV8_M_BASE_S + 0xFFF, PPC_SP_PERIPH0, + SYSTEM_TIMER2_PERIPH_PPC0_POS_MASK }; + +struct platform_data_t tfm_peripheral_timer3 = { SYSTIMER3_ARMV8_M_BASE_S, SYSTIMER3_ARMV8_M_BASE_S + 0xFFF, PPC_SP_PERIPH0, + SYSTEM_TIMER3_PERIPH_PPC0_POS_MASK }; + +struct platform_data_t tfm_peripheral_slowclk = { SLOWCLK_TIMER_CMSDK_BASE_S, SLOWCLK_TIMER_CMSDK_BASE_S + 0xFFF, PPC_SP_PERIPH1, + SLOWCLK_TIMER_PERIPH_PPC1_POS_MASK }; + +struct platform_data_t tfm_peripheral_touch_i2c = { FPGA_SBCon_I2C_TOUCH_BASE_S, FPGA_SBCon_I2C_TOUCH_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, FPGA_I2C_TOUCH_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_audio_i2c = { FPGA_SBCon_I2C_AUDIO_BASE_S, FPGA_SBCon_I2C_AUDIO_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, FPGA_I2C_AUDIO_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_adc_spi = { FPGA_SPI_ADC_BASE_S, FPGA_SPI_ADC_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP1, + FPGA_SPI_ADC_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_shield0_spi = { FPGA_SPI_SHIELD0_BASE_S, FPGA_SPI_SHIELD0_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP1, + FPGA_SPI_SHIELD0_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_shield1_spi = { FPGA_SPI_SHIELD1_BASE_S, FPGA_SPI_SHIELD1_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP1, + FPGA_SPI_SHIELD1_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_shield0_i2c = { SBCon_I2C_SHIELD0_BASE_S, SBCon_I2C_SHIELD0_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, SBCon_I2C_SHIELD0_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_shield1_i2c = { SBCon_I2C_SHIELD1_BASE_S, SBCon_I2C_SHIELD1_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, SBCon_I2C_SHIELD1_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_ddr4_eeprom_i2c = { FPGA_DDR4_EEPROM_BASE_S, FPGA_DDR4_EEPROM_BASE_S + 0xFFF, + PPC_SP_PERIPH_EXP1, FPGA_SBCon_I2C_PERIPH_PPCEXP1_POS_MASK }; + +struct platform_data_t tfm_peripheral_fpga_scc = { FPGA_SCC_BASE_S, FPGA_SCC_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + FPGA_SCC_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_fpga_i2s = { FPGA_I2S_BASE_S, FPGA_I2S_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + FPGA_I2S_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_fpga_io = { FPGA_IO_BASE_S, FPGA_IO_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + FPGA_IO_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_std_uart = { UART0_BASE_NS, UART0_BASE_NS + 0xFFF, PPC_SP_DO_NOT_CONFIGURE, -1 }; + +struct platform_data_t tfm_peripheral_uart1 = { UART1_BASE_S, UART1_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + UART1_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_uart2 = { UART2_BASE_S, UART2_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + UART2_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_uart3 = { UART3_BASE_S, UART3_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + UART3_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_uart4 = { UART4_BASE_S, UART4_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + UART4_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_uart5 = { UART5_BASE_S, UART5_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + UART5_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_clcd = { CLCD_Config_Reg_BASE_S, CLCD_Config_Reg_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, + CLCD_PERIPH_PPCEXP2_POS_MASK }; + +struct platform_data_t tfm_peripheral_rtc = { RTC_BASE_S, RTC_BASE_S + 0xFFF, PPC_SP_PERIPH_EXP2, RTC_PERIPH_PPCEXP2_POS_MASK }; diff --git a/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.h b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.h new file mode 100755 index 00000000000000..092056a832296b --- /dev/null +++ b/examples/platform/openiotsdk/tf-m/targets/an552/tfm_peripherals_def.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019-2022, Arm Limited. All rights reserved. + * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PERIPHERALS_DEF_H__ +#define __TFM_PERIPHERALS_DEF_H__ + +#include "platform_irq.h" +#include "target_cfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Quantized default IRQ priority, the value is: + * (Number of configurable priority) / 4: (1UL << __NVIC_PRIO_BITS) / 4 + */ +#define DEFAULT_IRQ_PRIORITY (1UL << (__NVIC_PRIO_BITS - 2)) + +#define TFM_TIMER0_IRQ (TIMER0_IRQn) +#define TFM_TIMER1_IRQ (TIMER1_IRQn) + +#define TFM_FPU_S_TEST_IRQ (GPIO0_0_IRQn) +#define TFM_FPU_NS_TEST_IRQ (GPIO0_1_IRQn) + +extern struct platform_data_t tfm_peripheral_gpio0; +extern struct platform_data_t tfm_peripheral_gpio1; +extern struct platform_data_t tfm_peripheral_gpio2; +extern struct platform_data_t tfm_peripheral_gpio3; +extern struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio0; +extern struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio1; +extern struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio2; +extern struct platform_data_t tfm_peripheral_fmc_cmsdk_gpio3; +extern struct platform_data_t tfm_peripheral_ethernet; +extern struct platform_data_t tfm_peripheral_usb; +extern struct platform_data_t tfm_peripheral_timer0; +extern struct platform_data_t tfm_peripheral_timer1; +extern struct platform_data_t tfm_peripheral_timer2; +extern struct platform_data_t tfm_peripheral_timer3; +extern struct platform_data_t tfm_peripheral_slowclk; +extern struct platform_data_t tfm_peripheral_touch_i2c; +extern struct platform_data_t tfm_peripheral_audio_i2c; +extern struct platform_data_t tfm_peripheral_adc_spi; +extern struct platform_data_t tfm_peripheral_shield0_spi; +extern struct platform_data_t tfm_peripheral_shield1_spi; +extern struct platform_data_t tfm_peripheral_shield0_i2c; +extern struct platform_data_t tfm_peripheral_shield1_i2c; +extern struct platform_data_t tfm_peripheral_ddr4_eeprom_i2c; +extern struct platform_data_t tfm_peripheral_fpga_scc; +extern struct platform_data_t tfm_peripheral_fpga_i2s; +extern struct platform_data_t tfm_peripheral_fpga_io; +extern struct platform_data_t tfm_peripheral_std_uart; +extern struct platform_data_t tfm_peripheral_uart1; +extern struct platform_data_t tfm_peripheral_uart2; +extern struct platform_data_t tfm_peripheral_uart3; +extern struct platform_data_t tfm_peripheral_uart4; +extern struct platform_data_t tfm_peripheral_uart5; +extern struct platform_data_t tfm_peripheral_clcd; +extern struct platform_data_t tfm_peripheral_rtc; + +#define TFM_PERIPHERAL_GPIO0 (&tfm_peripheral_gpio0) +#define TFM_PERIPHERAL_GPIO1 (&tfm_peripheral_gpio1) +#define TFM_PERIPHERAL_GPIO2 (&tfm_peripheral_gpio2) +#define TFM_PERIPHERAL_GPIO3 (&tfm_peripheral_gpio3) +#define TFM_PERIPHERAL_FMC_CMSDK_GPIO0 (&tfm_peripheral_fmc_cmsdk_gpio0) +#define TFM_PERIPHERAL_FMC_CMSDK_GPIO1 (&tfm_peripheral_fmc_cmsdk_gpio1) +#define TFM_PERIPHERAL_FMC_CMSDK_GPIO2 (&tfm_peripheral_fmc_cmsdk_gpio2) +#define TFM_PERIPHERAL_FMC_CMSDK_GPIO3 (&tfm_peripheral_fmc_cmsdk_gpio3) +#define TFM_PERIPHERAL_ETHERNET (&tfm_peripheral_ethernet) +#define TFM_PERIPHERAL_USB (&tfm_peripheral_usb) +#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0) +#define TFM_PERIPHERAL_TIMER1 (&tfm_peripheral_timer1) +#define TFM_PERIPHERAL_TIMER2 (&tfm_peripheral_timer2) +#define TFM_PERIPHERAL_TIMER3 (&tfm_peripheral_timer3) +#define TFM_PERIPHERAL_SLOWCLK (&tfm_peripheral_slowclk) +#define TFM_PERIPHERAL_TOUCH_I2C (&tfm_peripheral_touch_i2c) +#define TFM_PERIPHERAL_AUDIO_I2C (&tfm_peripheral_audio_i2c) +#define TFM_PERIPHERAL_ADC_SPI (&tfm_peripheral_adc_spi) +#define TFM_PERIPHERAL_SHIELD0_SPI (&tfm_peripheral_shield0_spi) +#define TFM_PERIPHERAL_SHIELD1_SPI (&tfm_peripheral_shield1_spi) +#define TFM_PERIPHERAL_SHIELD0_I2C (&tfm_peripheral_shield0_i2c) +#define TFM_PERIPHERAL_SHIELD1_I2C (&tfm_peripheral_shield1_i2c) +#define TFM_PERIPHERAL_DDR4_EEPROM_I2C (&tfm_peripheral_ddr4_eeprom_i2c) +#define TFM_PERIPHERAL_FPGA_SCC (&tfm_peripheral_fpga_scc) +#define TFM_PERIPHERAL_FPGA_I2S (&tfm_peripheral_fpga_i2s) +#define TFM_PERIPHERAL_FPGA_IO (&tfm_peripheral_fpga_io) +#define TFM_PERIPHERAL_STD_UART (&tfm_peripheral_std_uart) +#define TFM_PERIPHERAL_UART1 (&tfm_peripheral_uart1) +#define TFM_PERIPHERAL_UART2 (&tfm_peripheral_uart2) +#define TFM_PERIPHERAL_UART3 (&tfm_peripheral_uart3) +#define TFM_PERIPHERAL_UART4 (&tfm_peripheral_uart4) +#define TFM_PERIPHERAL_UART5 (&tfm_peripheral_uart5) +#define TFM_PERIPHERAL_CLCD (&tfm_peripheral_clcd) +#define TFM_PERIPHERAL_RTC (&tfm_peripheral_rtc) + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PERIPHERALS_DEF_H__ */ diff --git a/examples/shell/openiotsdk/CMakeLists.txt b/examples/shell/openiotsdk/CMakeLists.txt index 2d9cf86d9a95bb..d17908bf6021e7 100644 --- a/examples/shell/openiotsdk/CMakeLists.txt +++ b/examples/shell/openiotsdk/CMakeLists.txt @@ -23,7 +23,10 @@ get_filename_component(SHELL_COMMON ${CHIP_ROOT}/examples/shell/shell_common REA list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) -set(APP_TARGET chip-openiotsdk-shell-example) +set(APP_TARGET chip-openiotsdk-shell-example_ns) + +set(TFM_SUPPORT YES) +set(TFM_NS_APP_VERSION "0.0.1") # Toolchain files need to exist before first call to project include(toolchain) @@ -64,7 +67,7 @@ target_include_directories(${APP_TARGET} target_sources(${APP_TARGET} PRIVATE - main/main.cpp + main/main_ns.cpp ${SHELL_COMMON}/cmd_misc.cpp ${SHELL_COMMON}/globals.cpp ) @@ -75,3 +78,5 @@ target_link_libraries(${APP_TARGET} include(linker) set_target_link(${APP_TARGET}) + +sdk_post_build(${APP_TARGET}) diff --git a/examples/shell/openiotsdk/freertos-config/FreeRTOSConfig.h b/examples/shell/openiotsdk/freertos-config/FreeRTOSConfig.h index 6011c1e9d6bf79..38b2a2678a34dc 100644 --- a/examples/shell/openiotsdk/freertos-config/FreeRTOSConfig.h +++ b/examples/shell/openiotsdk/freertos-config/FreeRTOSConfig.h @@ -190,7 +190,7 @@ extern uint32_t SystemCoreClock; // Use TrustZone Secure Side Only // This settings prevents FreeRTOS contex switch to Non-Secure side. // Enable this setting when FreeRTOS runs on the Secure side only. -#define configRUN_FREERTOS_SECURE_ONLY 1 +#define configRUN_FREERTOS_SECURE_ONLY CONFIG_RUN_FREERTOS_SECURE_ONLY // Use TrustZone Security Extension // Using TrustZone affects context handling. diff --git a/examples/shell/openiotsdk/main/main.cpp b/examples/shell/openiotsdk/main/main_ns.cpp similarity index 100% rename from examples/shell/openiotsdk/main/main.cpp rename to examples/shell/openiotsdk/main/main_ns.cpp diff --git a/scripts/build/builders/openiotsdk.py b/scripts/build/builders/openiotsdk.py index dd24618e11e00e..7de737e3ea60a4 100644 --- a/scripts/build/builders/openiotsdk.py +++ b/scripts/build/builders/openiotsdk.py @@ -67,11 +67,6 @@ def generate(self): ], title='Generating ' + self.identifier) def _build(self): - # Remove old artifacts to force linking - cmd = 'rm -rf {}/chip-*'.format(self.output_dir) - self._Execute(['bash', '-c', cmd], - title='Remove old artifacts ' + self.identifier) - self._Execute(['cmake', '--build', shlex.quote(self.output_dir)], title='Building ' + self.identifier) diff --git a/scripts/build/testdata/dry_run_openiotsdk-lock.txt b/scripts/build/testdata/dry_run_openiotsdk-lock.txt index d00bdae66c6358..bbe17977600ec6 100644 --- a/scripts/build/testdata/dry_run_openiotsdk-lock.txt +++ b/scripts/build/testdata/dry_run_openiotsdk-lock.txt @@ -4,8 +4,5 @@ cd "{root}" # Generating openiotsdk-lock cmake -GNinja -S {root}/examples/lock-app/openiotsdk -B {out}/openiotsdk-lock --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -# Remove old artifacts openiotsdk-lock -bash -c 'rm -rf {out}/openiotsdk-lock/chip-*' - # Building openiotsdk-lock cmake --build {out}/openiotsdk-lock diff --git a/scripts/build/testdata/dry_run_openiotsdk-shell.txt b/scripts/build/testdata/dry_run_openiotsdk-shell.txt index f93c6a3201b591..ef1a848a14ac88 100644 --- a/scripts/build/testdata/dry_run_openiotsdk-shell.txt +++ b/scripts/build/testdata/dry_run_openiotsdk-shell.txt @@ -4,8 +4,5 @@ cd "{root}" # Generating openiotsdk-shell cmake -GNinja -S {root}/examples/shell/openiotsdk -B {out}/openiotsdk-shell --toolchain=toolchains/toolchain-arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -# Remove old artifacts openiotsdk-shell -bash -c 'rm -rf {out}/openiotsdk-shell/chip-*' - # Building openiotsdk-shell cmake --build {out}/openiotsdk-shell diff --git a/scripts/constraints.txt b/scripts/constraints.txt index a10433ad738a6c..19326bf8ace249 100644 --- a/scripts/constraints.txt +++ b/scripts/constraints.txt @@ -28,7 +28,9 @@ brotli==1.0.9 cbor==1.0.0 # via -r requirements.txt cbor2==5.4.3 - # via -r requirements.txt + # via + # -r requirements.txt + # imgtool certifi==2021.5.30 # via requests cffi==1.15.1 @@ -41,6 +43,7 @@ click==8.1.3 # -r requirements.txt # flask # idf-component-manager + # imgtool # mbed-tools # pip-tools colorama==0.4.4 @@ -61,7 +64,8 @@ cryptography==3.4.7 # via # -c constraints.esp32.txt # -r requirements.txt -cxxfilt==0.2.2 ; sys_platform == "linux" + # imgtool +cxxfilt==0.2.2 # via -r requirements.txt decorator==5.0.9 # via ipython @@ -112,11 +116,14 @@ idf-component-manager==1.1.4 # via -r requirements.esp32.txt idna==2.10 # via requests +imgtool==1.9.0 + # via -r requirements.openiotsdk.txt iniconfig==1.1.1 # via pytest intelhex==2.3.0 # via # -r requirements.txt + # imgtool # mbed-os-tools ipython==7.24.1 # via -r requirements.txt diff --git a/scripts/examples/openiotsdk_example.sh b/scripts/examples/openiotsdk_example.sh index d700a227d0b767..fbba7a343f0c7c 100755 --- a/scripts/examples/openiotsdk_example.sh +++ b/scripts/examples/openiotsdk_example.sh @@ -104,13 +104,8 @@ function build_with_cmake() { BUILD_OPTIONS+=(-DCMAKE_BUILD_TYPE=Debug) fi - # Remove old artifacts to force linking - rm -rf "$BUILD_PATH/chip-"* - # Activate Matter environment source "$CHIP_ROOT"/scripts/activate.sh - # Remove access to ARM GCC toolchain from Matter environment, use higher version from OIS environment - PATH=$(echo "$PATH" | sed 's/:/\n/g' | grep -v "$PW_ARM_CIPD_INSTALL_DIR" | xargs | tr ' ' ':') cmake -G Ninja -S "$EXAMPLE_PATH" -B "$BUILD_PATH" --toolchain="$TOOLCHAIN_PATH" "${BUILD_OPTIONS[@]}" cmake --build "$BUILD_PATH" @@ -230,8 +225,8 @@ function run_test() { fi } -SHORT=C:,p:,d:.n:,c,s,h -LONG=command:,path:,debug:.network:,clean,scratch,help +SHORT=C:,p:,d:,n:,c,s,h +LONG=command:,path:,debug:,network:,clean,scratch,help OPTS=$(getopt -n build --options "$SHORT" --longoptions "$LONG" -- "$@") eval set -- "$OPTS" diff --git a/scripts/requirements.openiotsdk.txt b/scripts/requirements.openiotsdk.txt index 319312169ae92e..99f1a3010edb8f 100644 --- a/scripts/requirements.openiotsdk.txt +++ b/scripts/requirements.openiotsdk.txt @@ -1 +1,2 @@ -pytest-json-report>=1.5.0 \ No newline at end of file +pytest-json-report>=1.5.0 +imgtool>=1.6.0 \ No newline at end of file diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index e66d60a4525025..f3766f08717c31 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -57,6 +57,8 @@ endfunction() # # Configure ${APP_TARGET} based on the selected data model configuration. # Available options are: +# SCOPE Cmake scope keyword that defines the scope of included sources +# The default is PRIVATE scope. # INCLUDE_SERVER Include source files from src/app/server directory # ZAP_FILE Path to the ZAP file, used to determine the list of clusters # supported by the application. @@ -64,10 +66,15 @@ endfunction() # if not provided # function(chip_configure_data_model APP_TARGET) - cmake_parse_arguments(ARG "INCLUDE_SERVER" "ZAP_FILE;IDL" "" ${ARGN}) + set(SCOPE PRIVATE) + cmake_parse_arguments(ARG "INCLUDE_SERVER" "SCOPE" "ZAP_FILE;IDL" "" ${ARGN}) + + if (ARG_SCOPE) + set(SCOPE ${ARG_SCOPE}) + endif() if (ARG_INCLUDE_SERVER) - target_sources(${APP_TARGET} PRIVATE + target_sources(${APP_TARGET} ${SCOPE} ${CHIP_APP_BASE_DIR}/server/EchoHandler.cpp ${CHIP_APP_BASE_DIR}/server/Dnssd.cpp ${CHIP_APP_BASE_DIR}/server/OnboardingCodesUtil.cpp @@ -75,7 +82,7 @@ function(chip_configure_data_model APP_TARGET) ${CHIP_APP_BASE_DIR}/server/CommissioningWindowManager.cpp ) - target_compile_options(${APP_TARGET} PUBLIC + target_compile_options(${APP_TARGET} ${SCOPE} "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" ) endif() @@ -98,7 +105,7 @@ function(chip_configure_data_model APP_TARGET) OUTPUT_FILES APP_GEN_FILES ) - target_include_directories(${APP_TARGET} PRIVATE "${APP_GEN_DIR}") + target_include_directories(${APP_TARGET} ${SCOPE} "${APP_GEN_DIR}") add_dependencies(${APP_TARGET} ${APP_TARGET}-codegen) else() set(APP_GEN_FILES) @@ -117,10 +124,10 @@ function(chip_configure_data_model APP_TARGET) OUTPUT_PATH APP_TEMPLATES_GEN_DIR OUTPUT_FILES APP_TEMPLATES_GEN_FILES ) - target_include_directories(${APP_TARGET} PRIVATE "${APP_TEMPLATES_GEN_DIR}") + target_include_directories(${APP_TARGET} ${SCOPE} "${APP_TEMPLATES_GEN_DIR}") add_dependencies(${APP_TARGET} ${APP_TARGET}-zapgen) - target_sources(${APP_TARGET} PRIVATE + target_sources(${APP_TARGET} ${SCOPE} ${CHIP_APP_BASE_DIR}/../../zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp ${CHIP_APP_BASE_DIR}/../../zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp ${CHIP_APP_BASE_DIR}/util/af-event.cpp diff --git a/src/platform/openiotsdk/BUILD.gn b/src/platform/openiotsdk/BUILD.gn index 2b80b49a8aeb6b..a8cd947ae411bc 100644 --- a/src/platform/openiotsdk/BUILD.gn +++ b/src/platform/openiotsdk/BUILD.gn @@ -14,10 +14,43 @@ import("//build_overrides/chip.gni") +import("${chip_root}/build/chip/buildconfig_header.gni") import("${chip_root}/src/platform/device.gni") assert(chip_device_platform == "openiotsdk") +declare_args() { + # Add Trusted Firmware-M (TF-M) support + chip_openiotsdk_use_tfm = false + + # By default use flash block device storage + chip_openiotsdk_use_psa_ps = false +} + +buildconfig_header("openiotsdk_buildconfig") { + header = "OpenIoTSDKConfig.h" + header_dir = "ois" + + if (chip_openiotsdk_use_psa_ps) { + _chip_openiotsdk_kv_store_config_include = + "" + _chip_openiotsdk_persisted_storage_key_type = "uint64_t" + } else { + _chip_openiotsdk_kv_store_config_include = + "" + _chip_openiotsdk_persisted_storage_key_type = "const char *" + } + + defines = [ + "CHIP_OPEN_IOT_SDK_KV_STORE_CONFIG_INCLUDE=${_chip_openiotsdk_kv_store_config_include}", + "CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE=${_chip_openiotsdk_persisted_storage_key_type}", + ] + + if (chip_openiotsdk_use_tfm) { + defines += [ "CHIP_OPEN_IOT_SDK_USE_TFM=1" ] + } +} + static_library("openiotsdk") { sources = [ "../SingletonConfigurationManager.cpp", @@ -39,13 +72,27 @@ static_library("openiotsdk") { "NetworkCommissioningEthernetDriver.cpp", "OpenIoTSDKArchUtils.c", "OpenIoTSDKArchUtils.h", - "OpenIoTSDKConfig.cpp", - "OpenIoTSDKConfig.h", + "OpenIoTSDKPort.h", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "SystemPlatformConfig.h", "SystemTimeSupport.cpp", ] - public_deps = [ "${chip_root}/src/platform:platform_base" ] + public_deps = [ + ":openiotsdk_buildconfig", + "${chip_root}/src/platform:platform_base", + ] + + if (chip_openiotsdk_use_psa_ps) { + sources += [ + "KVPsaPsStore.cpp", + "KVPsaPsStore.h", + ] + } else { + sources += [ + "KVBlockDeviceStore.cpp", + "KVBlockDeviceStore.h", + ] + } } diff --git a/src/platform/openiotsdk/CHIPPlatformConfig.h b/src/platform/openiotsdk/CHIPPlatformConfig.h index 58da36298c27ef..efc4afd358fdf6 100644 --- a/src/platform/openiotsdk/CHIPPlatformConfig.h +++ b/src/platform/openiotsdk/CHIPPlatformConfig.h @@ -26,6 +26,8 @@ #include +#include + // ==================== General Platform Adaptations ==================== #define CHIP_CONFIG_EXPECTED_LOW_PROCESSING_TIME 10 diff --git a/src/platform/openiotsdk/ConfigurationManagerImpl.cpp b/src/platform/openiotsdk/ConfigurationManagerImpl.cpp index 58e6e70c995509..84da3ef5c767c1 100644 --- a/src/platform/openiotsdk/ConfigurationManagerImpl.cpp +++ b/src/platform/openiotsdk/ConfigurationManagerImpl.cpp @@ -28,7 +28,11 @@ #include +#ifdef CHIP_OPEN_IOT_SDK_USE_TFM +#include "tfm_platform_api.h" +#else #include "cmsis.h" +#endif namespace chip { namespace DeviceLayer { @@ -45,8 +49,10 @@ CHIP_ERROR ConfigurationManagerImpl::Init() { CHIP_ERROR err; + KVStoreConfig::Init(); + // Initialize the generic implementation base class. - err = Internal::GenericConfigurationManagerImpl::Init(); + err = Internal::GenericConfigurationManagerImpl::Init(); SuccessOrExit(err); exit: @@ -65,7 +71,7 @@ void ConfigurationManagerImpl::InitiateFactoryReset(void) CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) { - CHIP_ERROR err = ReadConfigValue(key, value); + CHIP_ERROR err = KVStoreConfig::ReadConfigValueCounter(key, value); if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; @@ -75,73 +81,73 @@ CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform: CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) { - return OpenIoTSDKConfig::WriteCounter(key, value); + return KVStoreConfig::WriteConfigValueCounter(key, value); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) { - return OpenIoTSDKConfig::ReadConfigValue(key, val); + return KVStoreConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) { - return OpenIoTSDKConfig::ReadConfigValue(key, val); + return KVStoreConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) { - return OpenIoTSDKConfig::ReadConfigValue(key, val); + return KVStoreConfig::ReadConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { - return OpenIoTSDKConfig::ReadConfigValueStr(key, buf, bufSize, outLen); + return KVStoreConfig::ReadConfigValueStr(key, buf, bufSize, outLen); } CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - return OpenIoTSDKConfig::ReadConfigValueBin(key, buf, bufSize, outLen); + return KVStoreConfig::ReadConfigValueBin(key, buf, bufSize, outLen); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) { - return OpenIoTSDKConfig::WriteConfigValue(key, val); + return KVStoreConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) { - return OpenIoTSDKConfig::WriteConfigValue(key, val); + return KVStoreConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) { - return OpenIoTSDKConfig::WriteConfigValue(key, val); + return KVStoreConfig::WriteConfigValue(key, val); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) { - return OpenIoTSDKConfig::WriteConfigValueStr(key, str); + return KVStoreConfig::WriteConfigValueStr(key, str); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) { - return OpenIoTSDKConfig::WriteConfigValueStr(key, str, strLen); + return KVStoreConfig::WriteConfigValueStr(key, str, strLen); } CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { - return OpenIoTSDKConfig::WriteConfigValueBin(key, data, dataLen); + return KVStoreConfig::WriteConfigValueBin(key, data, dataLen); } void ConfigurationManagerImpl::RunConfigUnitTest(void) { - OpenIoTSDKConfig::RunConfigUnitTest(); + KVStoreConfig::RunConfigUnitTest(); } void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { ChipLogProgress(DeviceLayer, "Performing factory reset"); - const CHIP_ERROR err = OpenIoTSDKConfig::FactoryResetConfig(); + const CHIP_ERROR err = KVStoreConfig::FactoryResetConfig(); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err)); @@ -149,7 +155,12 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) // Restart the system. ChipLogProgress(DeviceLayer, "System restarting"); +#ifdef CHIP_OPEN_IOT_SDK_USE_TFM + tfm_platform_system_reset(); +#else + __disable_irq(); NVIC_SystemReset(); +#endif } ConfigurationManager & ConfigurationMgrImpl() diff --git a/src/platform/openiotsdk/ConfigurationManagerImpl.h b/src/platform/openiotsdk/ConfigurationManagerImpl.h index ad4effe0645978..044c3d55d6f377 100644 --- a/src/platform/openiotsdk/ConfigurationManagerImpl.h +++ b/src/platform/openiotsdk/ConfigurationManagerImpl.h @@ -25,7 +25,8 @@ #pragma once #include -#include + +#include CHIP_OPEN_IOT_SDK_KV_STORE_CONFIG_INCLUDE namespace chip { namespace DeviceLayer { @@ -33,7 +34,7 @@ namespace DeviceLayer { /** * Concrete implementation of the ConfigurationManager singleton object for the Zephyr platform. */ -class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl +class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl { public: diff --git a/src/platform/openiotsdk/OpenIoTSDKConfig.cpp b/src/platform/openiotsdk/KVBlockDeviceStore.cpp similarity index 55% rename from src/platform/openiotsdk/OpenIoTSDKConfig.cpp rename to src/platform/openiotsdk/KVBlockDeviceStore.cpp index d156e417ff324d..fc6f364976b0d7 100644 --- a/src/platform/openiotsdk/OpenIoTSDKConfig.cpp +++ b/src/platform/openiotsdk/KVBlockDeviceStore.cpp @@ -17,7 +17,7 @@ /** * @file - * Utilities for interacting with the the Open IoT SDK key-value storage. + * Open IoT SDK key-value storage base on flash TDBStore. */ #include @@ -28,59 +28,93 @@ #include #include +#include +#include + namespace chip { namespace DeviceLayer { namespace Internal { // *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices. -#define STR_EXPAND(tok) #tok - -// Note: An external mbed parameter could be useful so an application can put -// chip NVS values in a single place -#define CHIP_CONFIG_KV_STORE_PARTITION STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV) - // NVS namespaces used to store device configuration information. #define CHIP_CONFIG_FACTORY_PREFIX "chip-factory-" #define CHIP_CONFIG_CONFIG_PREFIX "chip-config-" #define CHIP_CONFIG_COUNTER_PREFIX "chip-counters-" -#define FACTORY_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX key -#define CONFIG_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX key - -const char OpenIoTSDKConfig::kConfigNamespace_ChipFactory[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX; -const char OpenIoTSDKConfig::kConfigNamespace_ChipConfig[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX; -const char OpenIoTSDKConfig::kConfigNamespace_ChipCounters[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX; +#define FACTORY_KEY(key) CHIP_CONFIG_FACTORY_PREFIX key +#define CONFIG_KEY(key) CHIP_CONFIG_CONFIG_PREFIX key +#define COUNTER_KEY(key) CHIP_CONFIG_COUNTER_PREFIX key // Keys stored in the chip-factory namespace -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SerialNum = { FACTORY_KEY("serial-num") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceId = { FACTORY_KEY("device-id") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceCert = { FACTORY_KEY("device-cert") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDeviceICACerts = { FACTORY_KEY("device-ca-certs") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_MfrDevicePrivateKey = { FACTORY_KEY("device-key") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_HardwareVersion = { FACTORY_KEY("hardware-ver") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ManufacturingDate = { FACTORY_KEY("mfg-date") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SetupPinCode = { FACTORY_KEY("pin-code") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_SetupDiscriminator = { FACTORY_KEY("discriminator") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pIterationCount = { FACTORY_KEY("iteration-count") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pSalt = { FACTORY_KEY("salt") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_Spake2pVerifier = { FACTORY_KEY("verifier") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_SerialNum = { FACTORY_KEY("serial-num") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_MfrDeviceId = { FACTORY_KEY("device-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_MfrDeviceCert = { FACTORY_KEY("device-cert") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_MfrDeviceICACerts = { FACTORY_KEY("device-ca-certs") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_MfrDevicePrivateKey = { FACTORY_KEY("device-key") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_HardwareVersion = { FACTORY_KEY("hardware-ver") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_ManufacturingDate = { FACTORY_KEY("mfg-date") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_SetupPinCode = { FACTORY_KEY("pin-code") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_SetupDiscriminator = { FACTORY_KEY("discriminator") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_Spake2pIterationCount = { FACTORY_KEY("iteration-count") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_Spake2pSalt = { FACTORY_KEY("salt") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_Spake2pVerifier = { FACTORY_KEY("verifier") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_VendorId = { FACTORY_KEY("vendor-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_ProductId = { FACTORY_KEY("product-id") }; // Keys stored in the chip-config namespace -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ServiceConfig = { CONFIG_KEY("service-config") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_PairedAccountId = { CONFIG_KEY("account-id") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_ServiceId = { CONFIG_KEY("service-id") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_LastUsedEpochKeyId = { CONFIG_KEY("last-ek-id") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_FailSafeArmed = { CONFIG_KEY("fail-safe-armed") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_WiFiStationSecType = { CONFIG_KEY("sta-sec-type") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_RegulatoryLocation = { CONFIG_KEY("regulatory-location") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_CountryCode = { CONFIG_KEY("country-code") }; -const OpenIoTSDKConfig::Key OpenIoTSDKConfig::kConfigKey_UniqueId = { CONFIG_KEY("unique-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_ServiceConfig = { CONFIG_KEY("service-config") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_PairedAccountId = { CONFIG_KEY("account-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_ServiceId = { CONFIG_KEY("service-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_LastUsedEpochKeyId = { CONFIG_KEY("last-ek-id") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_FailSafeArmed = { CONFIG_KEY("fail-safe-armed") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_WiFiStationSecType = { CONFIG_KEY("sta-sec-type") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_RegulatoryLocation = { CONFIG_KEY("regulatory-location") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_CountryCode = { CONFIG_KEY("country-code") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_LocationCapability = { CONFIG_KEY("location-capability") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kConfigKey_UniqueId = { CONFIG_KEY("unique-id") }; + +// Keys stored in the Chip-counters namespace +const KVBlockDeviceStore::Key KVBlockDeviceStore::kCounterKey_RebootCount = { COUNTER_KEY("reboot-count") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kCounterKey_UpTime = { COUNTER_KEY("up-time") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kCounterKey_TotalOperationalHours = { COUNTER_KEY("total-operational-hours") }; +const KVBlockDeviceStore::Key KVBlockDeviceStore::kCounterKey_BootReason = { COUNTER_KEY("boot-reason") }; using iotsdk::storage::kv_status; using iotsdk::storage::KVStore; -CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, bool & val) +iotsdk::storage::TDBStore * KVBlockDeviceStore::tdb = nullptr; + +CHIP_ERROR KVBlockDeviceStore::Init(void) +{ + if (tdb) + { + return CHIP_NO_ERROR; + } + + // Create a TDBStore using the underlying storage + tdb = new iotsdk::storage::TDBStore(GetBlockDevice()); + + if (!tdb) + { + return CHIP_ERROR_INTERNAL; + } + + // KVStore uses dual stage initialization so we can handle any errors + // Call the `init` method to setup the TDBStore + kv_status err = tdb->init(); + if (err != kv_status::OK) + { + delete tdb; + // zero tdb as we use it keep track of init + tdb = nullptr; + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVBlockDeviceStore::ReadConfigValue(Key key, bool & val) { if (Init() != CHIP_NO_ERROR) { @@ -108,7 +142,7 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, bool & val) return CHIP_NO_ERROR; } -CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint32_t & val) +CHIP_ERROR KVBlockDeviceStore::ReadConfigValue(Key key, uint32_t & val) { if (Init() != CHIP_NO_ERROR) { @@ -136,7 +170,7 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint32_t & val) return CHIP_NO_ERROR; } -CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint64_t & val) +CHIP_ERROR KVBlockDeviceStore::ReadConfigValue(Key key, uint64_t & val) { if (Init() != CHIP_NO_ERROR) { @@ -164,7 +198,7 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValue(Key key, uint64_t & val) return CHIP_NO_ERROR; } -CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR KVBlockDeviceStore::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { CHIP_ERROR err = ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); // Note: The system expect the trailing null to be added. @@ -180,7 +214,12 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueStr(Key key, char * buf, size_t bufS return CHIP_NO_ERROR; } -CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR KVBlockDeviceStore::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return ReadConfigValueBin(key, buf, bufSize, outLen, 0); +} + +CHIP_ERROR KVBlockDeviceStore::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset) { if (Init() != CHIP_NO_ERROR) { @@ -200,13 +239,13 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t b return CHIP_ERROR_INTERNAL; } - err = tdb->get(key, reinterpret_cast(buf), bufSize, &outLen); + err = tdb->get(key, reinterpret_cast(buf), bufSize, &outLen, offset); if (err != kv_status::OK) { return CHIP_ERROR_INTERNAL; } - if (bufSize < info.size) + if (bufSize < info.size - offset) { return CHIP_ERROR_BUFFER_TOO_SMALL; } @@ -214,7 +253,19 @@ CHIP_ERROR OpenIoTSDKConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t b return CHIP_NO_ERROR; } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, bool val) +CHIP_ERROR KVBlockDeviceStore::ReadConfigValueCounter(Key counterId, uint32_t & value) +{ + char key[50] = { 0 }; + auto err = ConstructCounterKey(counterId, key, sizeof(key)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return ReadConfigValue(key, value); +} + +CHIP_ERROR KVBlockDeviceStore::WriteConfigValue(Key key, bool val) { if (Init() != CHIP_NO_ERROR) { @@ -225,7 +276,7 @@ CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, bool val) return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint32_t val) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValue(Key key, uint32_t val) { if (Init() != CHIP_NO_ERROR) { @@ -236,7 +287,7 @@ CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint32_t val) return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint64_t val) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValue(Key key, uint64_t val) { if (Init() != CHIP_NO_ERROR) { @@ -247,17 +298,17 @@ CHIP_ERROR OpenIoTSDKConfig::WriteConfigValue(Key key, uint64_t val) return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueStr(Key key, const char * str) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValueStr(Key key, const char * str) { return WriteConfigValueBin(key, reinterpret_cast(str), strlen(str)); } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValueStr(Key key, const char * str, size_t strLen) { return WriteConfigValueBin(key, reinterpret_cast(str), strLen); } -CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { if (Init() != CHIP_NO_ERROR) { @@ -282,7 +333,19 @@ CHIP_ERROR OpenIoTSDKConfig::WriteConfigValueBin(Key key, const uint8_t * data, } } -CHIP_ERROR OpenIoTSDKConfig::ClearConfigValue(Key key) +CHIP_ERROR KVBlockDeviceStore::WriteConfigValueCounter(Key counterId, uint32_t value) +{ + char key[50] = { 0 }; + auto err = ConstructCounterKey(counterId, key, sizeof(key)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return WriteConfigValue(key, value); +} + +CHIP_ERROR KVBlockDeviceStore::ClearConfigValue(Key key) { if (Init() != CHIP_NO_ERROR) { @@ -292,38 +355,44 @@ CHIP_ERROR OpenIoTSDKConfig::ClearConfigValue(Key key) kv_status err = tdb->remove(key); if (err == kv_status::ITEM_NOT_FOUND) { - return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; } return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } -bool OpenIoTSDKConfig::ConfigValueExists(Key key) +CHIP_ERROR KVBlockDeviceStore::FactoryResetConfig() { - if (Init() != CHIP_NO_ERROR) + // tdb->reset is not used, we want to preserve other setting and factory + // configuration + auto err = ClearNamespace(CHIP_CONFIG_CONFIG_PREFIX); + if (err != CHIP_NO_ERROR) { - return false; + return err; } + return ClearNamespace(CHIP_CONFIG_COUNTER_PREFIX); +} - KVStore::info_t info; - kv_status err = tdb->get_info(key, &info); - return err == kv_status::OK ? true : false; +void KVBlockDeviceStore::RunConfigUnitTest() +{ + // Run common unit test. + ::chip::DeviceLayer::Internal::RunConfigUnitTest(); } -CHIP_ERROR OpenIoTSDKConfig::FactoryResetConfig() +bool KVBlockDeviceStore::ConfigValueExists(Key key) { - // tdb->reset is not used, we want to preserve other setting and factory - // configuration - auto err = ClearNamespace(kConfigNamespace_ChipConfig); - if (err != CHIP_NO_ERROR) + if (Init() != CHIP_NO_ERROR) { - return err; + return false; } - return ClearNamespace(kConfigNamespace_ChipCounters); + + KVStore::info_t info; + kv_status err = tdb->get_info(key, &info); + return err == kv_status::OK ? true : false; } -CHIP_ERROR OpenIoTSDKConfig::ConstructCounterKey(Key id, char * buf, size_t bufSize) +CHIP_ERROR KVBlockDeviceStore::ConstructCounterKey(Key id, char * buf, size_t bufSize) { - auto length = snprintf(buf, bufSize - 1, CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX "%s", id); + auto length = snprintf(buf, bufSize - 1, CHIP_CONFIG_COUNTER_PREFIX "%s", id); if (length < 0) { return CHIP_ERROR_INTERNAL; @@ -338,31 +407,7 @@ CHIP_ERROR OpenIoTSDKConfig::ConstructCounterKey(Key id, char * buf, size_t bufS } } -CHIP_ERROR OpenIoTSDKConfig::ReadCounter(Key counterId, uint32_t & value) -{ - char key[50] = { 0 }; - auto err = ConstructCounterKey(counterId, key, sizeof(key)); - if (err != CHIP_NO_ERROR) - { - return err; - } - - return ReadConfigValue(key, value); -} - -CHIP_ERROR OpenIoTSDKConfig::WriteCounter(Key counterId, uint32_t value) -{ - char key[50] = { 0 }; - auto err = ConstructCounterKey(counterId, key, sizeof(key)); - if (err != CHIP_NO_ERROR) - { - return err; - } - - return WriteConfigValue(key, value); -} - -CHIP_ERROR OpenIoTSDKConfig::ClearNamespace(const char * ns) +CHIP_ERROR KVBlockDeviceStore::ClearNamespace(const char * ns) { if (Init() != CHIP_NO_ERROR) { @@ -400,53 +445,29 @@ CHIP_ERROR OpenIoTSDKConfig::ClearNamespace(const char * ns) return err == kv_status::OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } -void OpenIoTSDKConfig::RunConfigUnitTest() -{ - // Run common unit test. - ::chip::DeviceLayer::Internal::RunConfigUnitTest(); -} - -CHIP_ERROR OpenIoTSDKConfig::Init(void) +KVBlockDeviceStoreKeyBuilder::KVBlockDeviceStoreKeyBuilder(const char * key) { - if (tdb) - { - return CHIP_NO_ERROR; - } - - flash_bd = new iotsdk::storage::FlashIAPBlockDevice(get_ram_drive_instance(), 0, 0); - - if (!flash_bd) - { - return CHIP_ERROR_INTERNAL; - } - - // Create a TDBStore using the underlying storage - tdb = new iotsdk::storage::TDBStore(flash_bd); - - if (!tdb) - { - delete flash_bd; - return CHIP_ERROR_INTERNAL; - } - - // KVStore uses dual stage initialization so we can handle any errors - // Call the `init` method to setup the TDBStore - kv_status err = tdb->init(); - if (err != kv_status::OK) - { - delete flash_bd; - delete tdb; - // zero tdb as we use it keep track of init - tdb = nullptr; - return CHIP_ERROR_INTERNAL; + // Check sign by sign if key contains illegal characters + // Each illegal character will be replaced by '!' + capital encoded letter value + char * out = buffer + strlen(buffer); + char * illegal_ptr; + while ((out < buffer + sizeof(buffer) - 3) && *key) // 2 chars for potential illegal char + 1 for \0 + { + illegal_ptr = strchr(illegalCharacters, *key); + if (illegal_ptr) + { + *out++ = '!'; + *out++ = 'A' + (int) (illegal_ptr - illegalCharacters); + } + else + { + *out++ = *key; + } + key++; } - - return CHIP_NO_ERROR; + valid = true; } -iotsdk::storage::TDBStore * OpenIoTSDKConfig::tdb = nullptr; -iotsdk::storage::FlashIAPBlockDevice * OpenIoTSDKConfig::flash_bd = nullptr; - } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/openiotsdk/OpenIoTSDKConfig.h b/src/platform/openiotsdk/KVBlockDeviceStore.h similarity index 62% rename from src/platform/openiotsdk/OpenIoTSDKConfig.h rename to src/platform/openiotsdk/KVBlockDeviceStore.h index ed056f1fd8f1c0..5935d599ba17a8 100644 --- a/src/platform/openiotsdk/OpenIoTSDKConfig.h +++ b/src/platform/openiotsdk/KVBlockDeviceStore.h @@ -17,47 +17,36 @@ /** * @file - * Utilities for interacting with the the Open IoT SDK key-value storage. + * Open IoT SDK key-value storage base on flash TDBStore. */ #pragma once +#include + +#include +#include #include #include -#include "iotsdk/BufferedBlockDevice.h" -#include "iotsdk/FlashIAPBlockDevice.h" - -extern "C" { -#include "flash_cs300.h" -#include "hal/flash_api.h" -#include "iotsdk/TDBStore.h" -} -#include +#include namespace chip { namespace DeviceLayer { namespace Internal { /** - * Provides functions and definitions for accessing device configuration information on the ESP32. - * - * This class is designed to be mixed-in to concrete implementation classes as a means to - * provide access to configuration information to generic base classes. + * This class provides access to configuration information for Open IoT SDK platform + * stored in Lightweight Key Value storage over a flash block device. */ -class OpenIoTSDKConfig +class KVBlockDeviceStore { public: - using Key = const char *; - - // NVS prefix used to store device configuration information. - static const char kConfigNamespace_ChipFactory[]; - static const char kConfigNamespace_ChipConfig[]; - static const char kConfigNamespace_ChipCounters[]; + using Key = chip::Platform::PersistedStorage::Key; // Key definitions for well-known keys. + // Factory keys static const Key kConfigKey_SerialNum; - static const Key kConfigKey_UniqueId; static const Key kConfigKey_MfrDeviceId; static const Key kConfigKey_MfrDeviceCert; static const Key kConfigKey_MfrDeviceICACerts; @@ -65,49 +54,91 @@ class OpenIoTSDKConfig static const Key kConfigKey_HardwareVersion; static const Key kConfigKey_ManufacturingDate; static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_Spake2pIterationCount; + static const Key kConfigKey_Spake2pSalt; + static const Key kConfigKey_Spake2pVerifier; + static const Key kConfigKey_VendorId; + static const Key kConfigKey_ProductId; + + // Config Keys static const Key kConfigKey_ServiceConfig; static const Key kConfigKey_PairedAccountId; static const Key kConfigKey_ServiceId; static const Key kConfigKey_LastUsedEpochKeyId; static const Key kConfigKey_FailSafeArmed; static const Key kConfigKey_WiFiStationSecType; - static const Key kConfigKey_SetupDiscriminator; static const Key kConfigKey_RegulatoryLocation; static const Key kConfigKey_CountryCode; - static const Key kConfigKey_Spake2pIterationCount; - static const Key kConfigKey_Spake2pSalt; - static const Key kConfigKey_Spake2pVerifier; + static const Key kConfigKey_LocationCapability; + static const Key kConfigKey_UniqueId; + + // Counter Keys + static const Key kCounterKey_RebootCount; + static const Key kCounterKey_UpTime; + static const Key kCounterKey_TotalOperationalHours; + static const Key kCounterKey_BootReason; + + // Initialization + static CHIP_ERROR Init(void); - // Config value accessors. + // Config value accessors static CHIP_ERROR ReadConfigValue(Key key, bool & val); static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset); + static CHIP_ERROR ReadConfigValueCounter(Key counterId, uint32_t & val); + static CHIP_ERROR WriteConfigValue(Key key, bool val); static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR WriteConfigValueCounter(Key counterId, uint32_t val); + static CHIP_ERROR ClearConfigValue(Key key); + + // Additional functions + static CHIP_ERROR FactoryResetConfig(void); + static void RunConfigUnitTest(void); static bool ConfigValueExists(Key key); - static CHIP_ERROR FactoryResetConfig(); - static CHIP_ERROR Init(void); - // NVS Namespace helper functions. +private: + static iotsdk::storage::TDBStore * tdb; + + // NVS Namespace helper functions static CHIP_ERROR ConstructCounterKey(Key id, char * buf, size_t bufSize); - static CHIP_ERROR ReadCounter(Key counterId, uint32_t & value); - static CHIP_ERROR WriteCounter(Key counterId, uint32_t value); static CHIP_ERROR ClearNamespace(const char * ns); +}; - static void RunConfigUnitTest(void); +class KVBlockDeviceStoreKeyBuilder +{ +public: + KVBlockDeviceStoreKeyBuilder(const char * key); + + void AddKey(void) {} + void RemoveKey(void) {} + + KVBlockDeviceStore::Key GetKey() const; private: - static iotsdk::storage::TDBStore * tdb; - static iotsdk::storage::FlashIAPBlockDevice * flash_bd; + char buffer[PersistentStorageDelegate::kKeyLengthMax + 1] = "chip-kvs-"; + bool valid; + // Mbed KV storage does not accept these characters in the key definition + const char * illegalCharacters = " */?:;\"|<>\\"; }; +inline KVBlockDeviceStore::Key KVBlockDeviceStoreKeyBuilder::GetKey() const +{ + return valid ? buffer : nullptr; +} + } // namespace Internal } // namespace DeviceLayer } // namespace chip + +using KVStoreConfig = chip::DeviceLayer::Internal::KVBlockDeviceStore; +using KVStoreKeyBuilder = chip::DeviceLayer::Internal::KVBlockDeviceStoreKeyBuilder; diff --git a/src/platform/openiotsdk/KVPsaPsStore.cpp b/src/platform/openiotsdk/KVPsaPsStore.cpp new file mode 100644 index 00000000000000..74023134ec0e97 --- /dev/null +++ b/src/platform/openiotsdk/KVPsaPsStore.cpp @@ -0,0 +1,624 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 + * Open IoT SDK key-value storage base on flash TDBStore. + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +// *** CAUTION ***: Changing the values of these keys can *break* existing devices. +const KVPsaPsStore::Key KVPsaPsStore::kMatterFactory_KeyOffset = 0x0; +const KVPsaPsStore::Key KVPsaPsStore::kMatterConfig_KeyOffset = 0x1; +const KVPsaPsStore::Key KVPsaPsStore::kMatterCounter_KeyOffset = 0x2; +const KVPsaPsStore::Key KVPsaPsStore::kMatterKvs_KeyOffset = 0x3; + +// Keys stored in the Matter factory group +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_SerialNum = GetPsaPaKey(kMatterFactory_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_MfrDeviceId = GetPsaPaKey(kMatterFactory_KeyOffset, 0x01); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_MfrDeviceCert = GetPsaPaKey(kMatterFactory_KeyOffset, 0x02); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_MfrDeviceICACerts = GetPsaPaKey(kMatterFactory_KeyOffset, 0x03); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_MfrDevicePrivateKey = GetPsaPaKey(kMatterFactory_KeyOffset, 0x04); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_HardwareVersion = GetPsaPaKey(kMatterFactory_KeyOffset, 0x05); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_ManufacturingDate = GetPsaPaKey(kMatterFactory_KeyOffset, 0x06); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_SetupPinCode = GetPsaPaKey(kMatterFactory_KeyOffset, 0x07); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_SetupDiscriminator = GetPsaPaKey(kMatterFactory_KeyOffset, 0x08); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_Spake2pIterationCount = GetPsaPaKey(kMatterFactory_KeyOffset, 0x09); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_Spake2pSalt = GetPsaPaKey(kMatterFactory_KeyOffset, 0x0A); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_Spake2pVerifier = GetPsaPaKey(kMatterFactory_KeyOffset, 0x0B); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_VendorId = GetPsaPaKey(kMatterFactory_KeyOffset, 0x0C); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_ProductId = GetPsaPaKey(kMatterFactory_KeyOffset, 0x0D); + +// Keys stored in the Matter config group +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_ServiceConfig = GetPsaPaKey(kMatterConfig_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_PairedAccountId = GetPsaPaKey(kMatterConfig_KeyOffset, 0x01); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_ServiceId = GetPsaPaKey(kMatterConfig_KeyOffset, 0x02); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_LastUsedEpochKeyId = GetPsaPaKey(kMatterConfig_KeyOffset, 0x03); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_FailSafeArmed = GetPsaPaKey(kMatterConfig_KeyOffset, 0x04); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_WiFiStationSecType = GetPsaPaKey(kMatterConfig_KeyOffset, 0x05); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_RegulatoryLocation = GetPsaPaKey(kMatterConfig_KeyOffset, 0x06); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_CountryCode = GetPsaPaKey(kMatterConfig_KeyOffset, 0x07); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_LocationCapability = GetPsaPaKey(kMatterConfig_KeyOffset, 0x08); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_UniqueId = GetPsaPaKey(kMatterConfig_KeyOffset, 0x09); + +// Keys stored in the Matter counters group +const KVPsaPsStore::Key KVPsaPsStore::kCounterKey_RebootCount = GetPsaPaKey(kMatterCounter_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kCounterKey_UpTime = GetPsaPaKey(kMatterCounter_KeyOffset, 0x01); +const KVPsaPsStore::Key KVPsaPsStore::kCounterKey_TotalOperationalHours = GetPsaPaKey(kMatterCounter_KeyOffset, 0x02); +const KVPsaPsStore::Key KVPsaPsStore::kCounterKey_BootReason = GetPsaPaKey(kMatterCounter_KeyOffset, 0x03); + +// Keys stored in the Matter key-value group +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_KvsStringKeyMap = GetPsaPaKey(kMatterKvs_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_KvsFirstKeySlot = GetPsaPaKey(kMatterKvs_KeyOffset, 0x01); +const KVPsaPsStore::Key KVPsaPsStore::kConfigKey_KvsLastKeySlot = GetPsaPaKey(kMatterKvs_KeyOffset, KVS_MAX_ENTRIES); + +// NVS helper variables +const KVPsaPsStore::Key KVPsaPsStore::kMinConfigKey_MatterConfig = GetPsaPaKey(kMatterConfig_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kMaxConfigKey_MatterConfig = GetPsaPaKey(kMatterConfig_KeyOffset, 0xFF); +const KVPsaPsStore::Key KVPsaPsStore::kMinConfigKey_MatterCounter = GetPsaPaKey(kMatterCounter_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kMaxConfigKey_MatterCounter = GetPsaPaKey(kMatterCounter_KeyOffset, 0xFF); + +const KVPsaPsStore::Key KVPsaPsStore::kMinMatterPsaPaKeyRegion = GetPsaPaKey(kMatterFactory_KeyOffset, 0x00); +const KVPsaPsStore::Key KVPsaPsStore::kMaxMatterPsaPaKeyRegion = GetPsaPaKey(kMatterKvs_KeyOffset, 0xFF); + +char mKvsStoredKeyString[KVS_MAX_ENTRIES][PersistentStorageDelegate::kKeyLengthMax + 1]; +chip::System::Mutex mKvsStoredKeyMutex; + +bool KVPsaPsStore::initialized = false; + +CHIP_ERROR KVPsaPsStore::Init(void) +{ + if (initialized) + { + return CHIP_NO_ERROR; + } + + memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString)); + size_t outLen; + CHIP_ERROR err = ReadConfigValueBin(kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), + sizeof(mKvsStoredKeyString), outLen); + + if ((err != CHIP_NO_ERROR) && (err != CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)) // Initial boot + { + return err; + } + + chip::System::Mutex::Init(mKvsStoredKeyMutex); + initialized = true; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValue(Key key, bool & val) +{ + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_get(key, 0, sizeof(val), reinterpret_cast(&val), &actual_size)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValue(Key key, uint32_t & val) +{ + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_get(key, 0, sizeof(val), reinterpret_cast(&val), &actual_size)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValue(Key key, uint64_t & val) +{ + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_get(key, 0, sizeof(val), reinterpret_cast(&val), &actual_size)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + // Note: The system expect adding the terminator char. + CHIP_ERROR err = ReadConfigValueBin(key, reinterpret_cast(buf), (bufSize - 1), outLen); + if (err != CHIP_NO_ERROR) + { + return err; + } + + buf[outLen] = 0; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return ReadConfigValueBin(key, buf, bufSize, outLen, 0); +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset) +{ + size_t keySize; + if (!ConfigValueExists(key, keySize)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + if (buf != NULL) + { + size_t actual_size = 0; + size_t readLength = bufSize >= (keySize - offset) ? keySize - offset : bufSize; + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_get(key, offset, readLength, reinterpret_cast(buf), &actual_size)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + outLen = actual_size; + if (bufSize < keySize - offset) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ReadConfigValueCounter(Key counterId, uint32_t & val) +{ + Key key = kMinConfigKey_MatterCounter + counterId; + + if (!ConfigValueExists(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + size_t actual_size = 0; + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_get(key, 0, sizeof(val), reinterpret_cast(&val), &actual_size)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + if (actual_size != sizeof(val)) + { + return CHIP_ERROR_BAD_REQUEST; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValue(Key key, bool val) +{ + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_set(key, sizeof(val), reinterpret_cast(&val), PSA_STORAGE_FLAG_NONE)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValue(Key key, uint32_t val) +{ + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_set(key, sizeof(val), reinterpret_cast(&val), PSA_STORAGE_FLAG_NONE)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValue(Key key, uint64_t val) +{ + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_set(key, sizeof(val), reinterpret_cast(&val), PSA_STORAGE_FLAG_NONE)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueBin(key, reinterpret_cast(str), (str != NULL) ? strlen(str) : 0); +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return WriteConfigValueBin(key, reinterpret_cast(str), (strLen > 0) ? strLen : 1); +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + // Two different behavior: If the pointer is not null, the value is updated + // or create. If the pointer is null, the key is removed if it exist. + if (data != nullptr) + { + CHIP_ERROR err = PsaStatus2ChipError( + psa_ps_set(key, dataLen, const_cast(reinterpret_cast(data)), PSA_STORAGE_FLAG_NONE)); + if (err != CHIP_NO_ERROR) + { + return err; + } + } + else if (ConfigValueExists(key)) + { + return ClearConfigValue(key); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::WriteConfigValueCounter(Key counterId, uint32_t val) +{ + Key key = kMinConfigKey_MatterCounter + counterId; + + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_set(key, sizeof(val), reinterpret_cast(&val), PSA_STORAGE_FLAG_NONE)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::ClearConfigValue(Key key) +{ + if (!ValidConfigKey(key)) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + CHIP_ERROR err = PsaStatus2ChipError(psa_ps_remove(key)); + if (err != CHIP_NO_ERROR) + { + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::FactoryResetConfig() +{ + // Deletes all Config and KVS group objects. + // Factory and Counter type objects are NOT deleted. + + if (Init() != CHIP_NO_ERROR) + { + return CHIP_ERROR_INTERNAL; + } + + // Iterate over all the Matter Config objects and delete each one. + CHIP_ERROR err = ForEachObject(kMinConfigKey_MatterConfig, kMaxConfigKey_MatterConfig, false, + [](const Key & key, const size_t & size) -> CHIP_ERROR { return ClearConfigValue(key); }); + if (err != CHIP_NO_ERROR) + { + return err; + } + + // Iterate over all the Matter KVS objects and delete each one (including KVS key map). + err = ForEachObject(kConfigKey_KvsStringKeyMap, kConfigKey_KvsLastKeySlot, false, + [](const Key & key, const size_t & size) -> CHIP_ERROR { return ClearConfigValue(key); }); + if (err != CHIP_NO_ERROR) + { + return err; + } + + mKvsStoredKeyMutex.Lock(); + memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString)); + mKvsStoredKeyMutex.Unlock(); + + return err; +} + +void KVPsaPsStore::RunConfigUnitTest() +{ + // Run common unit test. + ::chip::DeviceLayer::Internal::RunConfigUnitTest(); +} + +bool KVPsaPsStore::ValidConfigKey(Key key) +{ + // Returns true if the key is in the Matter reserved key range. + return ((key >= kMinMatterPsaPaKeyRegion) && (key <= kMaxMatterPsaPaKeyRegion)); +} + +bool KVPsaPsStore::ValidKvsKey(Key key) +{ + // Returns true if the key is in the KVS group range. + return ((key >= kConfigKey_KvsFirstKeySlot) && (key <= kConfigKey_KvsLastKeySlot)); +} + +void KVPsaPsStore::KVSKeyMapUpdate() +{ + OnScheduleKVSKeyMapUpdate(nullptr, nullptr); +} + +void KVPsaPsStore::ScheduleKVSKeyMapUpdate() +{ + CHIP_ERROR err = SystemLayer().StartTimer( + std::chrono::duration_cast(System::Clock::Seconds32(KVS_KEY_MAP_UPDATE_DELAY_SEC)), + OnScheduleKVSKeyMapUpdate, NULL); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Start KVS key map update timer failed: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void KVPsaPsStore::OnScheduleKVSKeyMapUpdate(System::Layer * systemLayer, void * appState) +{ + mKvsStoredKeyMutex.Lock(); + CHIP_ERROR err = WriteConfigValueBin(kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), + sizeof(mKvsStoredKeyString)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "KVS key map update failed: %" CHIP_ERROR_FORMAT, err.Format()); + } + mKvsStoredKeyMutex.Unlock(); +} + +bool KVPsaPsStore::ConfigValueExists(Key key, size_t & size) +{ + if (!ValidConfigKey(key)) + { + return false; + } + + psa_storage_info_t info; + psa_status_t status = psa_ps_get_info(key, &info); + if (status == PSA_SUCCESS) + { + size = info.size; + } + + return (status == PSA_SUCCESS); +} + +bool KVPsaPsStore::ConfigValueExists(Key key) +{ + size_t size; + return ConfigValueExists(key, size); +} + +CHIP_ERROR KVPsaPsStore::ForEachObject(Key firstKey, Key lastKey, bool addNewRecord, ForEachObjectFunct funct) +{ + CHIP_ERROR err; + // Iterates through the specified range of object key ids. + // Invokes the callers CB function when appropriate. + + for (Key key = firstKey; key <= lastKey; ++key) + { + // Check if object with current key exists. + psa_storage_info_t info; + psa_status_t status = psa_ps_get_info(key, &info); + switch (status) + { + case PSA_SUCCESS: + if (!addNewRecord) + { + // Invoke the caller's function + // (for retrieve,store,delete,enumerate GroupKey operations). + err = funct(key, info.size); + } + break; + case PSA_ERROR_DOES_NOT_EXIST: + if (addNewRecord) + { + // Invoke caller's function + // (for add GroupKey operation). + err = funct(key, info.size); + } + break; + default: + err = PsaStatus2ChipError(status); + break; + } + + if (err != CHIP_NO_ERROR) + { + return err; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KVPsaPsStore::PsaStatus2ChipError(psa_status_t status) +{ + CHIP_ERROR err; + + switch (status) + { + case PSA_SUCCESS: + err = CHIP_NO_ERROR; + break; + case PSA_ERROR_DOES_NOT_EXIST: + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; + default: + err = CHIP_ERROR(ChipError::Range::kPlatform, (status * (-1))); + break; + } + + return err; +} + +#define CONVERT_INDEX_TO_KEY(index) (KVPsaPsStore::kConfigKey_KvsFirstKeySlot + index) +#define CONVERT_KEY_TO_INDEX(key) (key - KVPsaPsStore::kConfigKey_KvsFirstKeySlot) + +KVPsaPsStoreKeyBuilder::KVPsaPsStoreKeyBuilder(const char * key) +{ + uint8_t firstEmptyKeySlot = KVS_MAX_ENTRIES; + + if (KVPsaPsStore::Init() != CHIP_NO_ERROR) + { + return; + } + + valid = false; + existing = false; + mKvsStoredKeyMutex.Lock(); + + // Check if key already exists, find the first empty slot in the same time + for (uint8_t keyIndex = 0; keyIndex < KVS_MAX_ENTRIES; keyIndex++) + { + if (strcmp(key, mKvsStoredKeyString[keyIndex]) == 0) + { + keyValue = CONVERT_INDEX_TO_KEY(keyIndex); + if (KVPsaPsStore::ValidKvsKey(keyValue)) + { + valid = true; + existing = true; + } + return; + } + + if ((keyIndex < firstEmptyKeySlot) && (mKvsStoredKeyString[keyIndex][0] == 0)) + { + firstEmptyKeySlot = keyIndex; + } + } + + // Key does not exist, reserve a slot for it + keyValue = CONVERT_INDEX_TO_KEY(firstEmptyKeySlot); + if (KVPsaPsStore::ValidKvsKey(keyValue)) + { + memset(buffer, 0, sizeof(buffer)); + size_t keyLength = strlen(key) <= (sizeof(buffer) - 1) ? strlen(key) : (sizeof(buffer) - 1); + if (keyLength < strlen(key)) + { + ChipLogError(DeviceLayer, "String key length is too long. Truncated to %d bytes", (sizeof(buffer) - 1)); + } + memcpy(buffer, key, keyLength); + buffer[keyLength] = 0; + + valid = true; + } +} + +KVPsaPsStoreKeyBuilder::~KVPsaPsStoreKeyBuilder() +{ + mKvsStoredKeyMutex.Unlock(); +} + +void KVPsaPsStoreKeyBuilder::AddKey() +{ + if (!valid || existing) + { + return; + } + + uint32_t keyIndex = CONVERT_KEY_TO_INDEX(keyValue); + memset(mKvsStoredKeyString[keyIndex], 0, sizeof(mKvsStoredKeyString[keyIndex])); + Platform::CopyString(mKvsStoredKeyString[keyIndex], buffer); + KVPsaPsStore::ScheduleKVSKeyMapUpdate(); +} + +void KVPsaPsStoreKeyBuilder::RemoveKey() +{ + if (!valid) + { + return; + } + + uint32_t keyIndex = CONVERT_KEY_TO_INDEX(keyValue); + memset(mKvsStoredKeyString[keyIndex], 0, sizeof(mKvsStoredKeyString[keyIndex])); + KVPsaPsStore::ScheduleKVSKeyMapUpdate(); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/openiotsdk/KVPsaPsStore.h b/src/platform/openiotsdk/KVPsaPsStore.h new file mode 100644 index 00000000000000..b66c9cf669df63 --- /dev/null +++ b/src/platform/openiotsdk/KVPsaPsStore.h @@ -0,0 +1,196 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 + * Open IoT SDK key-value storage base on flash TDBStore. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Platform::PersistedStorage; + +// PSA Protected Storage interface provides 64-bit ID number, +// For Matter we reserved region ranges from 0x00010000 to 0x0001FFFF +// e.g. key = 0x010214 +// '01' = Matter region +// '02' = the sub region group base offset (Factory, Config, Counter or KVS) +// '14' = the id offset inside the group. +constexpr Key kMatterPsaPaKeyRegion = 0x010000U; +constexpr inline Key GetPsaPaKey(Key group, uint8_t id) +{ + return kMatterPsaPaKeyRegion | (group) << 8 | id; +} + +#define KVS_MAX_ENTRIES 30 + +#define KVS_KEY_MAP_UPDATE_DELAY_SEC 5 + +/** + * This class provides access to configuration information for Open IoT SDK platform + * stored in PSA Protected Storage. + */ +class KVPsaPsStore +{ +public: + using Key = chip::Platform::PersistedStorage::Key; + + // Persistent config values set at manufacturing time. Retained during factory reset. + static const Key kMatterFactory_KeyOffset; + // Persistent config values set at runtime. Cleared during factory reset. + static const Key kMatterConfig_KeyOffset; + // Persistent counter values set at runtime. Retained during factory reset. + static const Key kMatterCounter_KeyOffset; + // Persistent config values set at runtime. Cleared during factory reset. + static const Key kMatterKvs_KeyOffset; + + // Key definitions for well-known keys. + // Factory keys + static const Key kConfigKey_SerialNum; + static const Key kConfigKey_MfrDeviceId; + static const Key kConfigKey_MfrDeviceCert; + static const Key kConfigKey_MfrDeviceICACerts; + static const Key kConfigKey_MfrDevicePrivateKey; + static const Key kConfigKey_HardwareVersion; + static const Key kConfigKey_ManufacturingDate; + static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_Spake2pIterationCount; + static const Key kConfigKey_Spake2pSalt; + static const Key kConfigKey_Spake2pVerifier; + static const Key kConfigKey_VendorId; + static const Key kConfigKey_ProductId; + + // Config Keys + static const Key kConfigKey_ServiceConfig; + static const Key kConfigKey_PairedAccountId; + static const Key kConfigKey_ServiceId; + static const Key kConfigKey_LastUsedEpochKeyId; + static const Key kConfigKey_FailSafeArmed; + static const Key kConfigKey_WiFiStationSecType; + static const Key kConfigKey_RegulatoryLocation; + static const Key kConfigKey_CountryCode; + static const Key kConfigKey_LocationCapability; + static const Key kConfigKey_UniqueId; + + // Counter Keys + static const Key kCounterKey_RebootCount; + static const Key kCounterKey_UpTime; + static const Key kCounterKey_TotalOperationalHours; + static const Key kCounterKey_BootReason; + + // KVS storage Keys + static const Key kConfigKey_KvsStringKeyMap; + static const Key kConfigKey_KvsFirstKeySlot; + static const Key kConfigKey_KvsLastKeySlot; + + // NVS helper variables + static const Key kMinConfigKey_MatterConfig; + static const Key kMaxConfigKey_MatterConfig; + static const Key kMinConfigKey_MatterCounter; + static const Key kMaxConfigKey_MatterCounter; + + static const Key kMinMatterPsaPaKeyRegion; + static const Key kMaxMatterPsaPaKeyRegion; + + static CHIP_ERROR Init(void); + + // Config value accessors. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset); + static CHIP_ERROR ReadConfigValueCounter(Key counterId, uint32_t & val); + + static CHIP_ERROR WriteConfigValue(Key key, bool val); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR WriteConfigValueCounter(Key counterId, uint32_t val); + + static CHIP_ERROR ClearConfigValue(Key key); + + // Additional functions + static CHIP_ERROR FactoryResetConfig(void); + static void RunConfigUnitTest(void); + static bool ConfigValueExists(Key key); + static bool ValidKvsKey(Key key); + static void KVSKeyMapUpdate(void); + static void ScheduleKVSKeyMapUpdate(void); + +protected: + using ForEachObjectFunct = std::function; + static CHIP_ERROR ForEachObject(Key firstKey, Key lastKey, bool addNewRecord, ForEachObjectFunct funct); + +private: + // NVS helper functions. + static bool ValidConfigKey(Key key); + static bool ConfigValueExists(Key key, size_t & size); + static CHIP_ERROR PsaStatus2ChipError(psa_status_t status); + static void OnScheduleKVSKeyMapUpdate(System::Layer * systemLayer, void * appState); + + static bool initialized; +}; + +class KVPsaPsStoreKeyBuilder +{ +public: + KVPsaPsStoreKeyBuilder(const char * key); + + ~KVPsaPsStoreKeyBuilder(); + + void AddKey(void); + void RemoveKey(void); + + KVPsaPsStore::Key GetKey() const; + +private: + KVPsaPsStore::Key keyValue; + char buffer[PersistentStorageDelegate::kKeyLengthMax + 1]; + bool valid; + bool existing; +}; + +inline KVPsaPsStore::Key KVPsaPsStoreKeyBuilder::GetKey() const +{ + return valid ? keyValue : 0; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +using KVStoreConfig = chip::DeviceLayer::Internal::KVPsaPsStore; +using KVStoreKeyBuilder = chip::DeviceLayer::Internal::KVPsaPsStoreKeyBuilder; diff --git a/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp b/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp index e88772995c41c0..fb5268d494139f 100644 --- a/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp +++ b/src/platform/openiotsdk/KeyValueStoreManagerImpl.cpp @@ -27,101 +27,77 @@ #include #include -#include -using chip::DeviceLayer::Internal::OpenIoTSDKConfig; +#include CHIP_OPEN_IOT_SDK_KV_STORE_CONFIG_INCLUDE + +using namespace ::chip::DeviceLayer::Internal; namespace chip { namespace DeviceLayer { namespace PersistedStorage { -class KeyBuilder +CHIP_ERROR KeyValueStoreManagerImpl::ToKeyValueStoreManagerError(CHIP_ERROR err) { -public: - KeyBuilder(const char * key) - { - // Check sign by sign if key contains illegal characters - // Each illegal character will be replaced by '!' + capital encoded letter value - char * out = buffer + strlen(buffer); - char * illegal_ptr; - while ((out < buffer + sizeof(buffer) - 3) && *key) // 2 chars for potential illegal char + 1 for \0 - { - illegal_ptr = strchr(illegalCharacters, *key); - if (illegal_ptr) - { - *out++ = '!'; - *out++ = 'A' + (int) (illegal_ptr - illegalCharacters); - } - else - { - *out++ = *key; - } - key++; - } - valid = true; - } - - const char * str() const { return valid ? buffer : nullptr; } + return err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND ? CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND : err; +} -private: - char buffer[100] = "chip-kvs-"; - bool valid; - // Mbed KV storage does not accept these characters in the key definition - const char * illegalCharacters = " */?:;\"|<>\\"; -}; +CHIP_ERROR KeyValueStoreManagerImpl::Init(void) +{ + return KVStoreConfig::Init(); +} -// NOTE: Currently this platform does not support partial and offset reads -// these will return CHIP_ERROR_NOT_IMPLEMENTED. CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset) { - if (offset > 0) - { - // Offset and partial reads are not supported. - // Support can be added in the future if this is needed. - return CHIP_ERROR_NOT_IMPLEMENTED; - } - - KeyBuilder key_builder(key); - if (!key_builder.str()) + KVStoreKeyBuilder key_builder(key); + if (!key_builder.GetKey()) { return CHIP_ERROR_PERSISTED_STORAGE_FAILED; } - auto err = - OpenIoTSDKConfig::ReadConfigValueBin(key_builder.str(), reinterpret_cast(value), value_size, *read_bytes_size); - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + size_t outLen; + CHIP_ERROR err = ToKeyValueStoreManagerError( + KVStoreConfig::ReadConfigValueBin(key_builder.GetKey(), reinterpret_cast(value), value_size, outLen, offset)); + if (read_bytes_size) { - err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + *read_bytes_size = outLen; } return err; } CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { - KeyBuilder key_builder(key); - if (!key_builder.str()) + KVStoreKeyBuilder key_builder(key); + if (!key_builder.GetKey()) { return CHIP_ERROR_PERSISTED_STORAGE_FAILED; } - auto err = OpenIoTSDKConfig::ClearConfigValue(key_builder.str()); - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + CHIP_ERROR err = ToKeyValueStoreManagerError(KVStoreConfig::ClearConfigValue(key_builder.GetKey())); + if (err == CHIP_NO_ERROR) { - err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + key_builder.RemoveKey(); } + return err; } CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) { - KeyBuilder key_builder(key); - if (!key_builder.str()) + KVStoreKeyBuilder key_builder(key); + if (!key_builder.GetKey()) { return CHIP_ERROR_PERSISTED_STORAGE_FAILED; } - return OpenIoTSDKConfig::WriteConfigValueBin(key_builder.str(), reinterpret_cast(value), value_size); + CHIP_ERROR err = ToKeyValueStoreManagerError( + KVStoreConfig::WriteConfigValueBin(key_builder.GetKey(), reinterpret_cast(value), value_size)); + if (err == CHIP_NO_ERROR) + { + key_builder.AddKey(); + } + + return err; } KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; diff --git a/src/platform/openiotsdk/KeyValueStoreManagerImpl.h b/src/platform/openiotsdk/KeyValueStoreManagerImpl.h index 9257c33c6f25d7..3b13ef410444f6 100644 --- a/src/platform/openiotsdk/KeyValueStoreManagerImpl.h +++ b/src/platform/openiotsdk/KeyValueStoreManagerImpl.h @@ -37,12 +37,9 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager friend class KeyValueStoreManager; public: - // NOTE: Currently this platform does not support partial and offset reads - // these will return CHIP_ERROR_NOT_IMPLEMENTED. + CHIP_ERROR Init(void); CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0); - CHIP_ERROR _Delete(const char * key); - CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); private: @@ -50,6 +47,8 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager friend KeyValueStoreManager & KeyValueStoreMgr(); friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + CHIP_ERROR ToKeyValueStoreManagerError(CHIP_ERROR err); + static KeyValueStoreManagerImpl sInstance; }; diff --git a/src/platform/openiotsdk/OpenIoTSDKPort.h b/src/platform/openiotsdk/OpenIoTSDKPort.h new file mode 100644 index 00000000000000..15db673d2f3775 --- /dev/null +++ b/src/platform/openiotsdk/OpenIoTSDKPort.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 + * Utilities for interacting with the the Open IoT SDK platform port + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +iotsdk::storage::BlockDevice * GetBlockDevice(void); + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/third_party/open-iot-sdk/sdk b/third_party/open-iot-sdk/sdk index e71066cfbe4e1d..f2ffb845311828 160000 --- a/third_party/open-iot-sdk/sdk +++ b/third_party/open-iot-sdk/sdk @@ -1 +1 @@ -Subproject commit e71066cfbe4e1dc21bcf0a88840ea8e88625de24 +Subproject commit f2ffb845311828af0c5a8ecdbacdc104cb03c703