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