From 6e9fdc0565ff07fce1fb5efc18bb7d5dbe3da489 Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Fri, 14 Jan 2022 16:38:17 +0100 Subject: Adding Corstone-Polaris target Corstone-Polaris is the upcoming Corstone-3xx platform featuring the Cortex-Olympus CPU. Change-Id: I17b56b6e94f040e7f9a39dddad2e98309c82b294 --- .../model.h | 4 +- scripts/run_ctest.py | 62 ++- targets/corstone-polaris/CMakeLists.txt | 135 +++++++ targets/corstone-polaris/platform.ld | 337 ++++++++++++++++ targets/corstone-polaris/platform.scatter | 175 +++++++++ targets/corstone-polaris/retarget.c | 276 +++++++++++++ targets/corstone-polaris/target.cpp | 430 +++++++++++++++++++++ 7 files changed, 1405 insertions(+), 14 deletions(-) create mode 100644 targets/corstone-polaris/CMakeLists.txt create mode 100644 targets/corstone-polaris/platform.ld create mode 100644 targets/corstone-polaris/platform.scatter create mode 100644 targets/corstone-polaris/retarget.c create mode 100644 targets/corstone-polaris/target.cpp diff --git a/applications/baremetal/models/ethos-u55-128/keyword_spotting_ds_cnn_large_clustered_int8/model.h b/applications/baremetal/models/ethos-u55-128/keyword_spotting_ds_cnn_large_clustered_int8/model.h index fc68d4f..db8e8d1 100644 --- a/applications/baremetal/models/ethos-u55-128/keyword_spotting_ds_cnn_large_clustered_int8/model.h +++ b/applications/baremetal/models/ethos-u55-128/keyword_spotting_ds_cnn_large_clustered_int8/model.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Arm Limited. All rights reserved. + * Copyright (c) 2021-2022 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -24,6 +24,8 @@ * Hexdump: xxd -i ds_cnn_clustered_vela.tflite model.h ******************************************************************************************************************/ +#define TENSOR_ARENA_SIZE 150000 + const char *modelName = "keyword_spotting_ds_cnn_large_clustered_int8"; unsigned char networkModelData[] __attribute__((aligned(16), section("network_model_sec"))) = { diff --git a/scripts/run_ctest.py b/scripts/run_ctest.py index 3e7abfc..cc02226 100755 --- a/scripts/run_ctest.py +++ b/scripts/run_ctest.py @@ -44,6 +44,23 @@ def check_output(args, **kwargs): __print_arguments(args) return subprocess.check_output(args, **kwargs) +def run_fvp(cmd): + # Run FVP and tee output to console while scanning for exit tag + ret = 1 + proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + while True: + line = proc.stdout.readline().decode() + if not line: + break + + if 'Application exit code: 0.' in line: + ret = 0 + + sys.stdout.write(line) + sys.stdout.flush() + + return ret + def run_corstone_300(args): if not args.arch or args.arch == 'ethos-u55': fvp = 'FVP_Corstone_SSE-300_Ethos-U55' @@ -74,25 +91,42 @@ def run_corstone_300(args): cmd += args.args - # Run FVP and tee output to console while scanning for exit tag - ret = 1 - proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - while True: - line = proc.stdout.readline().decode() - if not line: - break + return run_fvp(cmd) - if 'Application exit code: 0.' in line: - ret = 0 +def run_corstone_polaris(args): + # Verify supported FVP version + version = subprocess.check_output(['FVP_Corstone-Polaris', '--version']).decode() + supported_version = ['11.16'] - sys.stdout.write(line) - sys.stdout.flush() + if not [s for s in supported_version if s in version]: + raise Exception("Incorrect FVP version. Supported versions are '{}'.".format(supported_version)) - return ret + # FVP executable + cmd = ['FVP_Corstone-Polaris'] + + # NPU configuration + cmd += ['-C', 'ethosu.num_macs=' + str(args.macs)] + + # 32kB ITCM, 32kB DTCM, 2MB SRAM + cmd += ['-C', 'cpu0.CFGITCMSZ=6', + '-C', 'cpu0.CFGDTCMSZ=6', + '-C', 'mps3_board.sse300.NUMVMBANK=1', + '-C', 'mps3_board.sse300.VM_BANK_SIZE=2048'] + + # Output parameters + cmd += ['-C', 'mps3_board.visualisation.disable-visualisation=1', + '-C', 'mps3_board.telnetterminal0.start_telnet=0', + '-C', 'mps3_board.uart0.out_file="-"', + '-C', 'mps3_board.uart0.unbuffered_output=1', + '-C', 'mps3_board.uart0.shutdown_on_eot=1'] + + cmd += args.args + + return run_fvp(cmd) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Run a test with given test command and test binary.') - parser.add_argument('-t', '--target', choices=['corstone-300'], required=True, help='FVP target.') + parser.add_argument('-t', '--target', choices=['corstone-300', 'corstone-polaris'], required=True, help='FVP target.') parser.add_argument('-a', '--arch', choices=['ethos-u55', 'ethos-u65'], help='NPU architecture.') parser.add_argument('-m', '--macs', type=int, choices=[32, 64, 128, 256], default=128, help='NPU number of MACs.') parser.add_argument('args', nargs='+', help='Arguments.') @@ -100,3 +134,5 @@ if __name__ == '__main__': if args.target == 'corstone-300': sys.exit(run_corstone_300(args)) + elif args.target == 'corstone-polaris': + sys.exit(run_corstone_polaris(args)) diff --git a/targets/corstone-polaris/CMakeLists.txt b/targets/corstone-polaris/CMakeLists.txt new file mode 100644 index 0000000..0d47091 --- /dev/null +++ b/targets/corstone-polaris/CMakeLists.txt @@ -0,0 +1,135 @@ +# +# Copyright (c) 2020-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. +# + +############################################################################# +# Default parameters +############################################################################# + +# TODO Olympus CPU is backwards compatible with Cortex-M55 +set(TARGET_CPU "cortex-m55" CACHE INTERNAL "") + +if (NOT CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/toolchain/armclang.cmake") +endif() + +set(ETHOSU_TARGET_NPU_CONFIG "ethos-u55-128" CACHE STRING "NPU configuration") +set(ETHOSU_TARGET_NPU_COUNT 1 CACHE INTERNAL "Number of NPUs") +set(ETHOSU_TARGET_NPU_TA_COUNT 2 CACHE INTERNAL "Number of timing adapters per NPU") + +set(ETHOSU_PMU_EVENT_0 -1 CACHE STRING "PMU Event #0") +set(ETHOSU_PMU_EVENT_1 -1 CACHE STRING "PMU Event #1") +set(ETHOSU_PMU_EVENT_2 -1 CACHE STRING "PMU Event #2") +set(ETHOSU_PMU_EVENT_3 -1 CACHE STRING "PMU Event #3") + +set(MEMORY_MODEL "dram" CACHE STRING "Memory config for model") +set(MEMORY_ARENA "dram" CACHE STRING "Memory config for arena") + +set(SYSTEM_CORE_CLOCK "25000000" CACHE INTERNAL "System core clock (Hz)") + +############################################################################# +# Project +############################################################################# + +cmake_minimum_required(VERSION 3.21) + +project(ethos-u-corstone-polaris VERSION 0.0.1) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/helpers.cmake) + +############################################################################# +# Corstone-Polaris +############################################################################# + +get_filename_component(ETHOSU_TARGET ${CMAKE_CURRENT_SOURCE_DIR} NAME) +message("Configuring target ${ETHOSU_TARGET}") + +# Enable CTest +include(CTest) +set(Python3_FIND_STRATEGY LOCATION) +find_package(Python3 COMPONENTS Interpreter) +ethosu_get_architecture(${ETHOSU_TARGET_NPU_CONFIG}) +set(ETHOSU_COMMAND_DEFAULT ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/run_ctest.py + -t corstone-polaris + -a ethos-${ETHOSU_ARCH} + -m ${ETHOSU_NUM_MACS} + CACHE INTERNAL "Default test command") + +# Enable trustzone support in core_software +set(TRUSTZONE_BUILD OFF) + +# Include common targets +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../common target) + +target_compile_definitions(ethosu_target_common INTERFACE + # Confiugure NPU architecture and number of timing adapters + ETHOSU_NPU_COUNT=${ETHOSU_TARGET_NPU_COUNT} + ETHOSU_NPU_TA_COUNT=${ETHOSU_TARGET_NPU_TA_COUNT} + + # Configure PMU events + ETHOSU_PMU_EVENT_0=${ETHOSU_PMU_EVENT_0} + ETHOSU_PMU_EVENT_1=${ETHOSU_PMU_EVENT_1} + ETHOSU_PMU_EVENT_2=${ETHOSU_PMU_EVENT_2} + ETHOSU_PMU_EVENT_3=${ETHOSU_PMU_EVENT_3} + + # Placement or TLFu model and area. 0 = SRAM, 1 = DRAM + ETHOSU_MODEL=$ + ETHOSU_ARENA=$) + +# AXI Timing adaptors +set(registers MAXR MAXW MAXRW RLATENCY WLATENCY PULSE_ON PULSE_OFF BWCAP PERFCTRL PERFCNT MODE HISTBIN HISTCNT) + +foreach(register ${registers}) + foreach(index RANGE 0 1) + set(name ETHOSU_TA_${register}_${index}) + set(${name} -1 CACHE STRING "${name}") + + if (${name} GREATER_EQUAL 0) + target_compile_definitions(ethosu_target_common INTERFACE ${name}=${${name}}) + endif() + endforeach() +endforeach() + +# Linker script +set(LINK_FILE platform CACHE STRING "Link file") + +ethosu_target_link_options(ethosu_target_link INTERFACE + LINK_FILE ${LINK_FILE} + ENTRY Reset_Handler) + +# Add drivers +target_sources(ethosu_target_startup INTERFACE + retarget.c + target.cpp) + +target_link_libraries(ethosu_target_startup INTERFACE + $<$:ethosu_core_driver;timing_adapter> + mpu + ethosu_mhu_dummy + ethosu_uart_cmsdk_apb) + +if (TARGET ethosu_core_driver) + target_compile_definitions(ethosu_core_driver PUBLIC + ETHOSU) +endif() + +############################################################################### +# Applications +############################################################################### + +# Add all applications +add_subdirectory(../../applications applications) diff --git a/targets/corstone-polaris/platform.ld b/targets/corstone-polaris/platform.ld new file mode 100644 index 0000000..f886283 --- /dev/null +++ b/targets/corstone-polaris/platform.ld @@ -0,0 +1,337 @@ +/* + * 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. + */ + + /* + * Corstone-Polaris is the next generation Corstone-300 where the CPU + * has been upgraded to Cortex Olympus. + * + * This is a simplified picture of the Corstone-300 memory system. + * Please refer to the Corstone SSE-300 Technical Reference Manual for + * further information. + * + * https://developer.arm.com/ip-products/subsystem/corstone/corstone-300 + * + * +---------------+ +---------------+ +------+ + * | Ethos-U55 | | Cortex-M55 +--+ ITCM | + * | | | | +------+ + * | | | | + * | | | | +------+ + * | M1 M0 | | +--+ DTCM | + * +---+-------+---+ +-------+-------+ +------+ + * | | | + * | +---+---------------+-----+ + * | | AMBA AXI NIC-400-Lite | + * | +---+-----------------+---+ + * | | | + * +---+-------+------------+ +--+-------+ + * | AMBA AXI NIC-400 | | SSE-300 | + * +---+--------+--------+--+ | SRAM | + * | | | +----------+ + * +---+---+ +--+---+ +--+--+ + * | Flash | | BRAM | | DDR | + * +-------+ +------+ +-----+ + * + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * | Memory region name | Base addr | Size |IDAU| MCC load address + remarks | + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * | ITCM | 0x0000_0000 | 0x0000_8000 | NS | 0x0000_0000; 32 kiB | + * | ITCM | 0x1000_0000 | 0x0000_8000 | S | Secure alias for NS ITCM | + * | FPGA Data SRAM; BRAM | 0x0100_0000 | 0x0020_0000 | NS | 0x0100_0000; 2 MiB | + * | FPGA data SRAM; BRAM | 0x1100_0000 | 0x0020_0000 | S | Secure alias for NS BRAM | + * | DTCM | 0x2000_0000 | 0x0000_8000 | NS | 32 kiB; | + * | DTCM | 0x3000_0000 | 0x0000_8000 | S | Secure alias for NS DTCM | + * | SSE-300 internal SRAM | 0x2100_0000 | 0x0020_0000 | NS | 1 bank of 2 MiB; 3cc latency) | + * | SSE-300 internal SRAM | 0x3100_0000 | 0x0020_0000 | S | Secure alias for NS internal SRAM | + * | DDR | 0x6000_0000 | 0x1000_0000 | NS | 0x0800_0000; 256 MiB bank | + * | DDR | 0x7000_0000 | 0x1000_0000 | S | 0x0C00_0000; 256 MiB bank | + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * + * Note: Ethos-U55 can access BRAM, internal SRAM and the DDR sections => activation buffers and + * the model should only be placed in those regions. + * + * Note: Alias regions means that secure and non-secure addresses are mapped to the same physical + * memory banks. + */ + +/* default value - '1', for DRAM */ +#ifndef ETHOSU_MODEL +#define ETHOSU_MODEL 1 +#endif + +/* default value - '1', for DRAM */ +#ifndef ETHOSU_ARENA +#define ETHOSU_ARENA 1 +#endif + +#ifndef STACK_SIZE +#define STACK_SIZE 0x8000 +#endif + +#ifndef HEAP_SIZE +#define HEAP_SIZE 0x10000 +#endif + +__STACK_SIZE = STACK_SIZE; +__HEAP_SIZE = HEAP_SIZE; + +MEMORY +{ + ITCM (rx) : ORIGIN = 0x10000000, LENGTH = 0x00008000 + BRAM (rw) : ORIGIN = 0x11000000, LENGTH = 0x00200000 + DTCM (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + SRAM (rw) : ORIGIN = 0x31000000, LENGTH = 0x00200000 + QSPI (rw) : ORIGIN = 0x38000000, LENGTH = 0x00800000 + DDR (rwx) : ORIGIN = 0x70000000, LENGTH = 0x10000000 +} + +PHDRS +{ + rom_exec PT_LOAD; + rom_dram PT_LOAD; + null PT_NULL; +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions ITCM and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ + +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + *crt* (.text*) + *startup_ARMCM55.c.obj (.text*) + *system_ARMCM55.c.obj (.text*) + *target.cpp.obj (.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) + + KEEP(*(.eh_frame*)) + } > ITCM :rom_exec + + /* + * SG veneers: + * All SG veneers are placed in the special output section .gnu.sgstubs. Its start address + * must be set, either with the command line option '--section-start' or in a linker script, + * to indicate where to place these veneers in memory. + */ +/* + .gnu.sgstubs : + { + . = ALIGN(32); + } > ITCM :rom_exec +*/ + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > ITCM :rom_exec + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > ITCM :rom_exec + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (LOADADDR(.sram)) + LONG (ADDR(.sram)) + LONG (SIZEOF(.sram)) + + LONG (LOADADDR(.bram)) + LONG (ADDR(.bram)) + LONG (SIZEOF(.bram)) + + __copy_table_end__ = .; + } > ITCM :rom_exec + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + + LONG (ADDR(.bss)) + LONG (SIZEOF(.bss)) + + LONG (ADDR(.sram.bss)) + LONG (SIZEOF(.sram.bss)) + + __zero_table_end__ = .; + } > ITCM :rom_exec + + .sram : AT(__etext) + { + *(.text*) + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + *(vtable) + *(.data) + *(.data.*) + *(.rodata*) + +#if (ETHOSU_MODEL == 0) + . = ALIGN(16); + *(network_model_sec) +#endif + + . = 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*)) + } > SRAM :rom_dram + + .bram : AT(LOADADDR(.sram) + SIZEOF(.sram)) + { + . = ALIGN(16); + *(.sram.data) + } > BRAM :rom_dram + + .sram.bss : + { +#if (ETHOSU_ARENA == 0) + . = ALIGN(16); + *(.bss.tensor_arena) +#endif + + . = ALIGN(16); + *(.bss.ethosu_scratch); + } > SRAM :null + + .ddr : + { +#if (ETHOSU_ARENA == 1) + . = ALIGN(16); + *(.bss.tensor_arena) +#endif + +#if (ETHOSU_MODEL == 1) + . = ALIGN(16); + *(network_model_sec) +#endif + + . = ALIGN(4); + *(input_data_sec) + *(expected_output_data_sec) + *(output_data_sec) + + *(ethosu_core_in_queue ethosu_core_out_queue) + + /* Place data for scatter loading here */ + __etext = .; + } > DDR :rom_dram + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > SRAM :null + + .heap (COPY) : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + . = . + __HEAP_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > SRAM :null + + .stack (ORIGIN(DTCM) + LENGTH(DTCM) - __STACK_SIZE) (COPY) : + { + . = ALIGN(8); + __StackLimit = .; + . = . + __STACK_SIZE; + . = ALIGN(8); + __StackTop = .; + } > DTCM :null + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds DTCM limit */ + ASSERT(LENGTH(DTCM) >= __STACK_SIZE, "region DTCM overflowed with stack") +} diff --git a/targets/corstone-polaris/platform.scatter b/targets/corstone-polaris/platform.scatter new file mode 100644 index 0000000..84579f2 --- /dev/null +++ b/targets/corstone-polaris/platform.scatter @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019-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. + */ + +/* + * Corstone-Polaris is the next generation Corstone-300 where the CPU + * has been upgraded to Cortex Olympus. + * + * This is a simplified picture of the Corstone-300 memory system. + * Please refer to the Corstone SSE-300 Technical Reference Manual for + * further information. + * + * https://developer.arm.com/ip-products/subsystem/corstone/corstone-300 + * + * +---------------+ +---------------+ +------+ + * | Ethos-U55 | | Cortex-M55 +--+ ITCM | + * | | | | +------+ + * | | | | + * | | | | +------+ + * | M1 M0 | | +--+ DTCM | + * +---+-------+---+ +-------+-------+ +------+ + * | | | + * | +---+---------------+-----+ + * | | AMBA AXI NIC-400-Lite | + * | +---+-----------------+---+ + * | | | + * +---+-------+------------+ +--+-------+ + * | AMBA AXI NIC-400 | | SSE-300 | + * +---+--------+--------+--+ | SRAM | + * | | | +----------+ + * +---+---+ +--+---+ +--+--+ + * | Flash | | BRAM | | DDR | + * +-------+ +------+ +-----+ + * + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * | Memory region name | Base addr | Size |IDAU| MCC load address + remarks | + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * | ITCM | 0x0000_0000 | 0x0000_8000 | NS | 0x0000_0000; 32 kiB | + * | ITCM | 0x1000_0000 | 0x0000_8000 | S | Secure alias for NS ITCM | + * | FPGA Data SRAM; BRAM | 0x0100_0000 | 0x0020_0000 | NS | 0x0100_0000; 2 MiB | + * | FPGA data SRAM; BRAM | 0x1100_0000 | 0x0020_0000 | S | Secure alias for NS BRAM | + * | DTCM | 0x2000_0000 | 0x0000_8000 | NS | 32 kiB; | + * | DTCM | 0x3000_0000 | 0x0000_8000 | S | Secure alias for NS DTCM | + * | SSE-300 internal SRAM | 0x2100_0000 | 0x0020_0000 | NS | 1 bank of 2 MiB; 3cc latency) | + * | SSE-300 internal SRAM | 0x3100_0000 | 0x0020_0000 | S | Secure alias for NS internal SRAM | + * | DDR | 0x6000_0000 | 0x1000_0000 | NS | 0x0800_0000; 256 MiB bank | + * | DDR | 0x7000_0000 | 0x1000_0000 | S | 0x0C00_0000; 256 MiB bank | + * +-----------------------+-------------+-------------+----+--------------------------------------+ + * + * Note: Ethos-U55 can access BRAM, internal SRAM and the DDR sections => activation buffers and + * the model should only be placed in those regions. + * + * Note: Alias regions means that secure and non-secure addresses are mapped to the same physical + * memory banks. + */ + +/* default value - '1', for DRAM */ +#ifndef ETHOSU_MODEL +#define ETHOSU_MODEL 1 +#endif + +/* default value - '1', for DRAM */ +#ifndef ETHOSU_ARENA +#define ETHOSU_ARENA 1 +#endif + +#ifndef STACK_SIZE +#define STACK_SIZE 0x8000 +#endif + +#ifndef HEAP_SIZE +#define HEAP_SIZE 0x10000 +#endif + +#define ITCM_START 0x10000000 +#define ITCM_SIZE 0x00008000 + +#define BRAM_START 0x11000000 +#define BRAM_SIZE 0x00200000 + +#define DTCM_START 0x30000000 +#define DTCM_SIZE 0x00008000 + +#define SRAM_START 0x31000000 +#define SRAM_SIZE 0x00200000 + +#define DDR_START 0x70000000 +#define DDR_SIZE 0x10000000 + +/* ---------------------------------------------------------------------------- + Stack seal size definition + *----------------------------------------------------------------------------*/ + +APP_IMAGE ITCM_START ITCM_SIZE +{ + ; ITCM 32kB + rom_exec ITCM_START ITCM_SIZE + { + *.o (RESET, +First) + *(InRoot$$Sections) + ; Make sure reset_handler ends up in root segment, when split across + ; ITCM and DTCM + startup_ARMCM55.o + system_ARMCM55.o + target.o + } + + ; DTCM 32kB + ARM_LIB_STACK DTCM_START EMPTY ALIGN 8 STACK_SIZE {} + + ; Place heap at end of SSE-300 SRAM + ARM_LIB_HEAP (SRAM_START + SRAM_SIZE - HEAP_SIZE) EMPTY ALIGN 8 HEAP_SIZE {} +} + +; Place all SRAM, BRAM and DDR execution regions in DDR. We have plenty of DDR +; and can perform scatter loading from here. +LOAD_REGION_DDR DDR_START DDR_SIZE +{ + ; Place model and its affiliates in DRAM + rom_dram DDR_START + { +#if (ETHOSU_MODEL == 1) + * (network_model_sec) +#endif + * (input_data_sec) + * (expected_output_data_sec) + * (output_data_sec) + } + +#if (ETHOSU_ARENA == 1) + ; Place tensor arena in DRAM if we have a fast memory area + ARENA +0 UNINIT ALIGN 16 + { + * (.bss.tensor_arena) + } +#endif + + ; 2MB SSE-300 SRAM (3 cycles read latency) from M55/U55 + SRAM SRAM_START (SRAM_SIZE - HEAP_SIZE) + { +#if (ETHOSU_MODEL == 0) + ; Place network model in SRAM + * (network_model_sec) +#endif + +#if (ETHOSU_ARENA == 0) + ; Place tensor arena in SRAM + * (.bss.tensor_arena) +#endif + + ; Place scratch buffer in SRAM + * (.bss.ethosu_scratch) + } + + ; MPS3 BRAM + BRAM BRAM_START BRAM_SIZE + { + .ANY1 (+RO +RW +ZI) + * (.sram.data) + } +} diff --git a/targets/corstone-polaris/retarget.c b/targets/corstone-polaris/retarget.c new file mode 100644 index 0000000..eb1c908 --- /dev/null +++ b/targets/corstone-polaris/retarget.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2019-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 +#include +#include +#include + +#include "uart_stdout.h" + +// armclang retargeting +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) +#include +#include + +/* Standard IO device handles. */ +#define STDIN 0x8001 +#define STDOUT 0x8002 +#define STDERR 0x8003 + +#define RETARGET(fun) _sys##fun +#define IO_OUTPUT(len) 0 + +#else +/* + * This type is used by the _ I/O functions to denote an open + * file. + */ +typedef int FILEHANDLE; + +/* + * Open a file. May return -1 if the file failed to open. + */ +extern FILEHANDLE _open(const char * /*name*/, int /*openmode*/); + +/* Standard IO device handles. */ +#define STDIN 0x00 +#define STDOUT 0x01 +#define STDERR 0x02 + +#define RETARGET(fun) fun +#define IO_OUTPUT(len) len + +#endif + +/* Standard IO device name defines. */ +const char __stdin_name[] __attribute__((aligned(4))) = "STDIN"; +const char __stdout_name[] __attribute__((aligned(4))) = "STDOUT"; +const char __stderr_name[] __attribute__((aligned(4))) = "STDERR"; + +void _ttywrch(int ch) { + (void)fputc(ch, stdout); +} + +FILEHANDLE RETARGET(_open)(const char *name, int openmode) { + (void)openmode; + + if (strcmp(name, __stdin_name) == 0) { + return (STDIN); + } + + if (strcmp(name, __stdout_name) == 0) { + return (STDOUT); + } + + if (strcmp(name, __stderr_name) == 0) { + return (STDERR); + } + + return -1; +} + +int RETARGET(_write)(FILEHANDLE fh, const unsigned char *buf, unsigned int len, int mode) { + (void)mode; + + switch (fh) { + case STDOUT: + case STDERR: { + int c; + unsigned int i; + + for (i = 0; i < len; i++) { + c = fputc(buf[i], stdout); + if (c == EOF) { + return EOF; + } + } + + return IO_OUTPUT(len); + } + default: + return EOF; + } +} + +int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode) { + (void)mode; + + switch (fh) { + case STDIN: { + int c; + unsigned int i; + + for (i = 0; i < len; i++) { + c = fgetc(stdin); + if (c == EOF) { + return EOF; + } + + buf[i] = (unsigned char)c; + } + + return IO_OUTPUT(len); + } + default: + return EOF; + } +} + +int RETARGET(_istty)(FILEHANDLE fh) { + switch (fh) { + case STDIN: + case STDOUT: + case STDERR: + return 1; + default: + return 0; + } +} + +int RETARGET(_close)(FILEHANDLE fh) { + if (RETARGET(_istty(fh))) { + return 0; + } + + return -1; +} + +int RETARGET(_seek)(FILEHANDLE fh, long pos) { + (void)fh; + (void)pos; + + return -1; +} + +int RETARGET(_ensure)(FILEHANDLE fh) { + (void)fh; + + return -1; +} + +long RETARGET(_flen)(FILEHANDLE fh) { + if (RETARGET(_istty)(fh)) { + return 0; + } + + return -1; +} + +int RETARGET(_tmpnam)(char *name, int sig, unsigned maxlen) { + (void)name; + (void)sig; + (void)maxlen; + + return 1; +} + +char *RETARGET(_command_string)(char *cmd, int len) { + (void)len; + + return cmd; +} + +void RETARGET(_exit)(int return_code) { + char exit_code_buffer[64] = {0}; + const char *p = exit_code_buffer; + + /* Print out the exit code on the uart so any reader know how we exit. */ + /* By appending 0x04, ASCII for end-of-transmission the FVP model exits, + * if the configuration parameter shutdown_on_eot on the uart is enabled. + * For some versions of FVP, the shutdown_on_eot is broken, but the same + * behaviour can be created by passing specifying a shutdown_tag= for the + * uart when starting the model so that is added last as well. + */ + + snprintf(exit_code_buffer, + sizeof(exit_code_buffer), + "Application exit code: %d.\n" // Let the readers know how we exit + "\04\n" // end-of-transmission + "EXITTHESIM\n", // shutdown_tag + return_code); + + while (*p != '\0') { + UartPutc(*p++); + } + + while (1) {} +} + +int system(const char *cmd) { + (void)cmd; + + return 0; +} + +time_t time(time_t *timer) { + time_t current; + + current = 0; // To Do !! No RTC implemented + + if (timer != NULL) { + *timer = current; + } + + return current; +} + +void _clock_init(void) { +#if 0 + // Example implementation based on SysTick + // For instance, use a counting var in a SysTick interrupt handler + // for clock() to use + SysTick->LOAD = (uint32_t) ((SystemCoreClock/100)-1UL); + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); + SysTick->VAL = 0UL; + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; +#endif +} + +clock_t clock(void) { + return (clock_t)-1; +} + +int remove(const char *arg) { + (void)arg; + return 0; +} + +int rename(const char *oldn, const char *newn) { + (void)oldn; + (void)newn; + return 0; +} + +int fputc(int ch, FILE *f) { + (void)(f); + return UartPutc(ch); +} + +int fgetc(FILE *f) { + (void)f; + return UartPutc(UartGetc()); +} + +#ifndef ferror +/* arm-none-eabi-gcc with newlib uses a define for ferror */ +int ferror(FILE *f) { + (void)f; + return EOF; +} +#endif diff --git a/targets/corstone-polaris/target.cpp b/targets/corstone-polaris/target.cpp new file mode 100644 index 0000000..f925b75 --- /dev/null +++ b/targets/corstone-polaris/target.cpp @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2020-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. + */ + +/**************************************************************************** + * Includes + ****************************************************************************/ + +#include "target.hpp" + +#ifdef ETHOSU +#include +#include +#endif + +#include "mpu.hpp" +#include "uart_stdout.h" + +#include +#include +#include +#include + +using namespace EthosU; + +/**************************************************************************** + * Defines + ****************************************************************************/ + +#define ETHOSU_BASE_ADDRESS 0x40004000 +#define ETHOSU_IRQ 16 + +#define ETHOSU0_TA0_BASE_ADDRESS 0x48103000 +#define ETHOSU0_TA1_BASE_ADDRESS 0x48103200 + +/**************************************************************************** + * Variables + ****************************************************************************/ + +#if defined(ETHOSU_FAST_MEMORY_SIZE) && ETHOSU_FAST_MEMORY_SIZE > 0 +__attribute__((aligned(16), section(".bss.ethosu_scratch"))) uint8_t ethosu_scratch[ETHOSU_FAST_MEMORY_SIZE]; +#else +#define ethosu_scratch 0 +#define ETHOSU_FAST_MEMORY_SIZE 0 +#endif + +#ifdef ETHOSU +struct ethosu_driver ethosu0_driver; +#endif + +/**************************************************************************** + * Timing Adapters + ****************************************************************************/ + +#ifdef ETHOSU + +#ifndef ETHOSU_TA_MAXR_0 +#define ETHOSU_TA_MAXR_0 0 +#endif + +#ifndef ETHOSU_TA_MAXW_0 +#define ETHOSU_TA_MAXW_0 0 +#endif + +#ifndef ETHOSU_TA_MAXRW_0 +#define ETHOSU_TA_MAXRW_0 0 +#endif + +#ifndef ETHOSU_TA_RLATENCY_0 +#define ETHOSU_TA_RLATENCY_0 0 +#endif + +#ifndef ETHOSU_TA_WLATENCY_0 +#define ETHOSU_TA_WLATENCY_0 0 +#endif + +#ifndef ETHOSU_TA_PULSE_ON_0 +#define ETHOSU_TA_PULSE_ON_0 0 +#endif + +#ifndef ETHOSU_TA_PULSE_OFF_0 +#define ETHOSU_TA_PULSE_OFF_0 0 +#endif + +#ifndef ETHOSU_TA_BWCAP_0 +#define ETHOSU_TA_BWCAP_0 0 +#endif + +#ifndef ETHOSU_TA_PERFCTRL_0 +#define ETHOSU_TA_PERFCTRL_0 0 +#endif + +#ifndef ETHOSU_TA_PERFCNT_0 +#define ETHOSU_TA_PERFCNT_0 0 +#endif + +#ifndef ETHOSU_TA_MODE_0 +#define ETHOSU_TA_MODE_0 1 +#endif + +#ifndef ETHOSU_TA_HISTBIN_0 +#define ETHOSU_TA_HISTBIN_0 0 +#endif + +#ifndef ETHOSU_TA_HISTCNT_0 +#define ETHOSU_TA_HISTCNT_0 0 +#endif + +#ifndef ETHOSU_TA_MAXR_1 +#define ETHOSU_TA_MAXR_1 0 +#endif + +#ifndef ETHOSU_TA_MAXW_1 +#define ETHOSU_TA_MAXW_1 0 +#endif + +#ifndef ETHOSU_TA_MAXRW_1 +#define ETHOSU_TA_MAXRW_1 0 +#endif + +#ifndef ETHOSU_TA_RLATENCY_1 +#define ETHOSU_TA_RLATENCY_1 0 +#endif + +#ifndef ETHOSU_TA_WLATENCY_1 +#define ETHOSU_TA_WLATENCY_1 0 +#endif + +#ifndef ETHOSU_TA_PULSE_ON_1 +#define ETHOSU_TA_PULSE_ON_1 0 +#endif + +#ifndef ETHOSU_TA_PULSE_OFF_1 +#define ETHOSU_TA_PULSE_OFF_1 0 +#endif + +#ifndef ETHOSU_TA_BWCAP_1 +#define ETHOSU_TA_BWCAP_1 0 +#endif + +#ifndef ETHOSU_TA_PERFCTRL_1 +#define ETHOSU_TA_PERFCTRL_1 0 +#endif + +#ifndef ETHOSU_TA_PERFCNT_1 +#define ETHOSU_TA_PERFCNT_1 0 +#endif + +#ifndef ETHOSU_TA_MODE_1 +#define ETHOSU_TA_MODE_1 1 +#endif + +#ifndef ETHOSU_TA_HISTBIN_1 +#define ETHOSU_TA_HISTBIN_1 0 +#endif + +#ifndef ETHOSU_TA_HISTCNT_1 +#define ETHOSU_TA_HISTCNT_1 0 +#endif + +static uintptr_t ethosu_ta_base_addrs[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT] = { + {ETHOSU0_TA0_BASE_ADDRESS, ETHOSU0_TA1_BASE_ADDRESS}}; +struct timing_adapter ethosu_ta[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT]; +struct timing_adapter_settings ethosu_ta_settings[ETHOSU_NPU_TA_COUNT] = {{ETHOSU_TA_MAXR_0, + ETHOSU_TA_MAXW_0, + ETHOSU_TA_MAXRW_0, + ETHOSU_TA_RLATENCY_0, + ETHOSU_TA_WLATENCY_0, + ETHOSU_TA_PULSE_ON_0, + ETHOSU_TA_PULSE_OFF_0, + ETHOSU_TA_BWCAP_0, + ETHOSU_TA_PERFCTRL_0, + ETHOSU_TA_PERFCNT_0, + ETHOSU_TA_MODE_0, + 0, // Read only register + ETHOSU_TA_HISTBIN_0, + ETHOSU_TA_HISTCNT_0}, + {ETHOSU_TA_MAXR_1, + ETHOSU_TA_MAXW_1, + ETHOSU_TA_MAXRW_1, + ETHOSU_TA_RLATENCY_1, + ETHOSU_TA_WLATENCY_1, + ETHOSU_TA_PULSE_ON_1, + ETHOSU_TA_PULSE_OFF_1, + ETHOSU_TA_BWCAP_1, + ETHOSU_TA_PERFCTRL_1, + ETHOSU_TA_PERFCNT_1, + ETHOSU_TA_MODE_1, + 0, // Read only register + ETHOSU_TA_HISTBIN_1, + ETHOSU_TA_HISTCNT_1}}; + +#endif + +/**************************************************************************** + * Cache maintenance + ****************************************************************************/ + +#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) +extern "C" { +void ethosu_flush_dcache(uint32_t *p, size_t bytes) { + if (p) + SCB_CleanDCache_by_Addr(p, bytes); + else + SCB_CleanDCache(); +} + +void ethosu_invalidate_dcache(uint32_t *p, size_t bytes) { + if (p) + SCB_InvalidateDCache_by_Addr(p, bytes); + else + SCB_InvalidateDCache(); +} +} +#endif + +/**************************************************************************** + * Init + ****************************************************************************/ + +namespace { + +extern "C" { +struct ExcContext { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xPsr; +}; + +void HardFault_Handler() { + int irq; + struct ExcContext *e; + uint32_t sp; + + asm volatile("mrs %0, ipsr \n" // Read IPSR (Exceptio number) + "sub %0, #16 \n" // Get it into IRQn_Type range + "tst lr, #4 \n" // Select the stack which was in use + "ite eq \n" + "mrseq %1, msp \n" + "mrsne %1, psp \n" + "mov %2, sp \n" + : "=r"(irq), "=r"(e), "=r"(sp)); + + printf("Hard fault. irq=%d, pc=0x%08" PRIx32 ", lr=0x%08" PRIx32 ", xpsr=0x%08" PRIx32 ", sp=0x%08" PRIx32 "\n", + irq, + e->pc, + e->lr, + e->xPsr, + sp); + printf( + "%11s cfsr=0x%08" PRIx32 " bfar=0x%08" PRIx32 " mmfar=0x%08" PRIx32 "\n", "", SCB->CFSR, SCB->BFAR, SCB->MMFAR); + exit(1); +} +} + +#ifdef ETHOSU +void ethosuIrqHandler() { + ethosu_irq_handler(ðosu0_driver); +} +#endif + +} // namespace + +namespace EthosU { + +void targetSetup() { + // Initialize UART driver + UartStdOutInit(); + +#ifdef ETHOSU + // Initialize timing adapter(s) + for (int i = 0; i < ETHOSU_NPU_COUNT; i++) { + for (int j = 0; j < ETHOSU_NPU_TA_COUNT; j++) { + if (ta_init(ðosu_ta[i][j], ethosu_ta_base_addrs[i][j])) { + printf("Failed to initialize timing-adapter %d for NPU %d\n", j, i); + } else { + // Set the updated configuration + ta_set_all(ðosu_ta[i][j], ðosu_ta_settings[j]); + } + } + } + + // Initialize Ethos-U NPU driver + if (ethosu_init(ðosu0_driver, + reinterpret_cast(ETHOSU_BASE_ADDRESS), + ethosu_scratch, + ETHOSU_FAST_MEMORY_SIZE, + 1, + 1)) { + printf("Failed to initialize NPU.\n"); + return; + } + + // Assumes SCB->VTOR point to RW memory + NVIC_SetVector(static_cast(ETHOSU_IRQ), (uint32_t)ðosuIrqHandler); + NVIC_EnableIRQ(static_cast(ETHOSU_IRQ)); +#endif + + // MPU setup + const std::vector mpuConfig = { + { + // ITCM (NS) + ARM_MPU_RBAR(0x00000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 1, // Read-Only + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x00007fff, // Limit + Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate + }, + { + // ITCM (S) + ARM_MPU_RBAR(0x10000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 1, // Read-Only + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x10007fff, // Limit + Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate + }, + { + // FPGA DATA SRAM; BRAM (NS) + ARM_MPU_RBAR(0x01000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x011fffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // FPGA DATA SRAM; BRAM (S) + ARM_MPU_RBAR(0x11000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x111fffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // DTCM (NS) + ARM_MPU_RBAR(0x20000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 1), // eXecute Never enabled + ARM_MPU_RLAR(0x20007fff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // DTCM (S) + ARM_MPU_RBAR(0x30000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 1), // eXecute Never enabled + ARM_MPU_RLAR(0x30007fff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // SSE-300 internal SRAM (NS) + ARM_MPU_RBAR(0x21000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x211fffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // SSE-300 internal SRAM (S) + ARM_MPU_RBAR(0x31000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 0), // eXecute Never disabled + ARM_MPU_RLAR(0x311fffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // DDR (NS) + ARM_MPU_RBAR(0x60000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 1), // eXecute Never enabled + ARM_MPU_RLAR(0x6fffffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }, + { + // DDR (S) + ARM_MPU_RBAR(0x70000000, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 1), // eXecute Never enabled + ARM_MPU_RLAR(0x7fffffff, // Limit + Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate + }}; + + // Setup MPU configuration + Mpu::loadAndEnableConfig(&mpuConfig[0], mpuConfig.size()); + +#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + SCB_EnableICache(); + SCB_EnableDCache(); +#endif +} + +} // namespace EthosU -- cgit v1.2.1