Build system refactoring

The source tree is configured for a specific target as defined in the
targets directory.

The common target components are defined in targets/common. Targets
for real platform should include this directory to get the default
target libraries setup.

Change-Id: I7fced4bfacec97432cbbd4125bd5b4cdd21122e3
diff --git a/targets/common/CMakeLists.txt b/targets/common/CMakeLists.txt
new file mode 100644
index 0000000..fa9b953
--- /dev/null
+++ b/targets/common/CMakeLists.txt
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2021 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.
+#
+
+#############################################################################
+# Core software
+#############################################################################
+
+set(ETHOSU_CORE_SOFTWARE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../core_software" CACHE PATH "Path to Arm Ethos-U Core Software")
+
+set(CORE_SOFTWARE_RTOS "All" CACHE STRING "")
+
+add_subdirectory(${ETHOSU_CORE_SOFTWARE_PATH} core_software)
+
+###############################################################################
+# Target
+#
+# ethosu_target_init       # Init and drivers
+#     |
+#     v
+# ethosu_target_startup    # CMSIS startup
+#     |
+#     v
+# ethosu_target_link       # Target linker script
+#     |
+#     v
+# ethosu_target_common     # Common for all targets
+###############################################################################
+
+# Common
+add_library(ethosu_target_common INTERFACE)
+target_include_directories(ethosu_target_common INTERFACE include)
+
+# Link
+add_library(ethosu_target_link INTERFACE)
+target_link_libraries(ethosu_target_link INTERFACE ethosu_target_common)
+
+# Startup
+add_library(ethosu_target_startup INTERFACE)
+target_link_libraries(ethosu_target_startup INTERFACE ethosu_target_link)
+
+target_link_libraries(ethosu_target_startup INTERFACE $<TARGET_OBJECTS:cmsis_startup>)
+add_dependencies(ethosu_target_startup $<TARGET_OBJECTS:cmsis_startup>)
+
+# Init
+add_library(ethosu_target_init INTERFACE)
+target_link_libraries(ethosu_target_init INTERFACE ethosu_target_startup)
+target_sources(ethosu_target_init INTERFACE src/init.cpp)
+
diff --git a/targets/common/include/target.hpp b/targets/common/include/target.hpp
new file mode 100644
index 0000000..abe3fdc
--- /dev/null
+++ b/targets/common/include/target.hpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TARGET_HPP_
+#define _TARGET_HPP_
+
+#ifdef __cplusplus
+
+namespace EthosU {
+
+/**
+ * Initialize the target platform.
+ */
+void targetSetup();
+
+} // namespace EthosU
+
+#endif
+
+#endif
diff --git a/targets/common/src/init.cpp b/targets/common/src/init.cpp
new file mode 100644
index 0000000..6eecc42
--- /dev/null
+++ b/targets/common/src/init.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <target.hpp>
+
+__attribute__((constructor)) void init() {
+    EthosU::targetSetup();
+}
diff --git a/targets/corstone-300/CMakeLists.txt b/targets/corstone-300/CMakeLists.txt
index b141ac9..d162537 100644
--- a/targets/corstone-300/CMakeLists.txt
+++ b/targets/corstone-300/CMakeLists.txt
@@ -17,7 +17,7 @@
 #
 
 #############################################################################
-# Toolchain
+# Default parameters
 #############################################################################
 
 set(TARGET_CPU "cortex-m55")
@@ -26,6 +26,14 @@
     set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/toolchain/armclang.cmake")
 endif()
 
+set(ETHOSU_COMMAND_DEFAULT
+    FVP_Corstone_SSE-300_Ethos-U55
+        -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_tag="EXITTHESIM")
+
 #############################################################################
 # Project
 #############################################################################
@@ -34,42 +42,34 @@
 
 project(ethos-u-corstone-300 VERSION 0.0.1)
 
+include(CTest)
+
 include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/helpers.cmake)
 
 #############################################################################
-# Configuration
-#############################################################################
-
-set(ETHOS_U_CORE_SOFTWARE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../core_software" CACHE PATH "Path to Arm Ethos-U Core Software")
-
-#############################################################################
-# Core software
-#############################################################################
-
-set(CORE_SOFTWARE_RTOS "FreeRTOS" CACHE STRING "")
-
-add_subdirectory(${ETHOS_U_CORE_SOFTWARE_PATH} core_software)
-
-#############################################################################
 # Corstone-300
 #############################################################################
 
-add_executable(ethosu_corstone_300)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../common target)
 
-target_sources(ethosu_corstone_300 PRIVATE
-    main.cpp
+# Linker script
+ethosu_target_link_options(ethosu_target_link INTERFACE
+    LINK_FILE platform
+    ENTRY Reset_Handler)
+
+# Add drivers
+target_sources(ethosu_target_startup INTERFACE
     retarget.c
-    uart.c)
+    uart.c
+    target.cpp)
 
-target_link_libraries(ethosu_corstone_300 PRIVATE
-    ethosu_core
-    $<TARGET_OBJECTS:cmsis_startup>
-    cmsis_device)
+target_compile_definitions(ethosu_core_driver PUBLIC ETHOSU)
+target_link_libraries(ethosu_target_startup INTERFACE ethosu_core_driver)
 
-add_dependencies(ethosu_corstone_300 cmsis_startup)
+###############################################################################
+# Applications
+###############################################################################
 
-target_link_options(ethosu_corstone_300 PRIVATE
-    --entry Reset_Handler)
+# Add all applications
+add_subdirectory(../../applications applications)
 
-ethosu_link_options(ethosu_corstone_300 PRIVATE
-                    LINK_FILE platform)
diff --git a/targets/corstone-300/main.cpp b/targets/corstone-300/main.cpp
deleted file mode 100644
index 8a8b978..0000000
--- a/targets/corstone-300/main.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2020 Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/****************************************************************************
- * Includes
- ****************************************************************************/
-
-// FreeRTOS
-#include "FreeRTOS.h"
-#include "queue.h"
-#include "task.h"
-
-// Ethos-U
-#include "ethosu_driver.h"
-#include "inference_process.hpp"
-#include "uart.h"
-
-// System includes
-#include <stdio.h>
-
-using namespace std;
-using namespace InferenceProcess;
-
-/****************************************************************************
- * Defines
- ****************************************************************************/
-
-#define ETHOSU_BASE_ADDRESS 0x48102000
-
-#define ETHOSU_IRQ 56
-
-/****************************************************************************
- * InferenceJob
- ****************************************************************************/
-
-namespace {
-
-struct xInferenceJob : public InferenceJob {
-    QueueHandle_t queue;
-    bool status;
-
-    xInferenceJob();
-    xInferenceJob(const string &name,
-                  const DataPtr &networkModel,
-                  const vector<DataPtr> &input,
-                  const vector<DataPtr> &output,
-                  const vector<DataPtr> &expectedOutput,
-                  size_t numBytesToPrint,
-                  const vector<uint8_t> &pmuEventConfig,
-                  const uint32_t pmuCycleCounterEnable,
-                  QueueHandle_t queue);
-};
-
-xInferenceJob::xInferenceJob() : InferenceJob(), queue(nullptr), status(false) {}
-
-xInferenceJob::xInferenceJob(const std::string &_name,
-                             const DataPtr &_networkModel,
-                             const std::vector<DataPtr> &_input,
-                             const std::vector<DataPtr> &_output,
-                             const std::vector<DataPtr> &_expectedOutput,
-                             size_t _numBytesToPrint,
-                             const vector<uint8_t> &_pmuEventConfig,
-                             const uint32_t _pmuCycleCounterEnable,
-                             QueueHandle_t _queue) :
-    InferenceJob(_name,
-                 _networkModel,
-                 _input,
-                 _output,
-                 _expectedOutput,
-                 _numBytesToPrint,
-                 _pmuEventConfig,
-                 _pmuCycleCounterEnable),
-    queue(_queue), status(false) {}
-
-} // namespace
-
-/****************************************************************************
- * Functions
- ****************************************************************************/
-
-namespace {
-
-uint8_t networkModelData[] = {
-    0x1C, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4C, 0x33, 0x00, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C,
-    0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00,
-    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-    0x30, 0x02, 0x00, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-    0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x75, 0x6E, 0x74, 0x69,
-    0x6D, 0x65, 0x5F, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00,
-    0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x31, 0x2E, 0x35, 0x2E, 0x30, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x4D, 0x4C, 0x49, 0x52, 0x20, 0x43,
-    0x6F, 0x6E, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08,
-    0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
-    0x20, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00,
-    0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
-    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00,
-    0x00, 0x0E, 0x00, 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x05, 0x38, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
-    0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00,
-    0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x92, 0xFF, 0xFF,
-    0xFF, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00,
-    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10,
-    0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x70, 0x6F, 0x6F, 0x6C, 0x30, 0x2F, 0x6D, 0x61, 0x78, 0x5F, 0x70, 0x6F,
-    0x6F, 0x6C, 0x69, 0x6E, 0x67, 0x32, 0x64, 0x2F, 0x4D, 0x61, 0x78, 0x50, 0x6F, 0x6F, 0x6C, 0x00, 0x8C, 0xFF, 0xFF,
-    0xFF, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0x80, 0x00, 0x3C, 0x01, 0x00,
-    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x08, 0x00, 0x07,
-    0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
-    0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-    0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x61,
-    0x74, 0x61, 0x30, 0x2F, 0x50, 0x6C, 0x61, 0x63, 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x00, 0x00, 0x00, 0x0C,
-    0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-    0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0x80, 0x00, 0x3C, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00};
-
-uint8_t inputData[] = {
-    0xAC, 0x0A, 0x7F, 0x8C, 0x2F, 0xAA, 0xC4, 0x97, 0x75, 0xA6, 0x16, 0xB7, 0xC0, 0xCC, 0x21, 0xD8, 0x43, 0xB3, 0x4E,
-    0x9A, 0xFB, 0x52, 0xA2, 0xDB, 0xC3, 0x76, 0x7D, 0x8B, 0x67, 0x7D, 0xE5, 0xD8, 0x09, 0xA4, 0x74, 0x6C, 0xD3, 0xDE,
-    0xA1, 0x9F, 0x15, 0x51, 0x59, 0xA5, 0xF2, 0xD6, 0x66, 0x62, 0x24, 0xB7, 0x05, 0x70, 0x57, 0x3A, 0x2B, 0x4C, 0x46,
-    0x3C, 0x4B, 0xE4, 0xD8, 0xBD, 0x84, 0x0E, 0x58, 0x9A, 0xB2, 0xF6, 0x8C, 0xCD, 0xCC, 0x45, 0x3A, 0x39, 0x29, 0x62,
-    0xC1, 0x42, 0x48, 0x7A, 0xE6, 0x7D, 0xAE, 0xCA, 0x27, 0x4A, 0xEA, 0xCF, 0x57, 0xA8, 0x65, 0x87, 0xAE, 0xC8, 0xDF,
-    0x7A, 0x58, 0x5E, 0x6B, 0x91, 0x51, 0x8B, 0x8D, 0x64, 0xA5, 0xE6, 0xF3, 0xEC, 0x19, 0x42, 0x09, 0xD6, 0x4D, 0x6B,
-    0x2F, 0x12, 0x48, 0x98, 0x5F, 0x56, 0x09, 0x1B, 0x4E, 0x16, 0x94, 0x97, 0xEE, 0xA5, 0x73, 0x08, 0x2D, 0x05, 0xD0,
-    0x13, 0x45, 0x5E, 0xF3, 0x92, 0x26, 0xD5, 0xC5, 0x1E, 0x08, 0xF5, 0xFE, 0x47, 0x35, 0xC7, 0x4F, 0x07, 0xEE, 0x23,
-    0xAF, 0x1D, 0xB9, 0xDE, 0xC0, 0x09, 0xBE, 0xDE, 0x52, 0xBB, 0x86, 0xFA, 0x63, 0x60, 0x3E, 0x79, 0xD8, 0xA7, 0x95,
-    0xCC, 0xB1, 0x7C, 0x08, 0xCD, 0xF3, 0x82, 0x23, 0x76, 0x1D, 0x03, 0x3E, 0x85, 0x93, 0xC2, 0xD0, 0xC7, 0x93, 0x0C,
-    0xCB, 0xAD, 0x8E, 0x3B, 0x47, 0x1E, 0xA7, 0x61, 0x7B, 0xB8, 0x20, 0xDD, 0xD1, 0xA3, 0xC1, 0x3F, 0xFF, 0x94, 0x09,
-    0xCD, 0xB2, 0x24, 0xB9, 0x4A, 0x91, 0x89, 0x7F, 0xD2, 0xD5, 0xF1, 0x20, 0xA2, 0x34, 0xC2, 0x1F, 0xDA, 0x97, 0x85,
-    0xCA, 0xC2, 0x1C, 0x1B, 0xF4, 0x48, 0x27, 0x6A, 0x97, 0xE0, 0x3D, 0x79, 0xA3, 0xEA, 0xB9, 0x43, 0xFE, 0x79, 0xB3,
-    0x2F, 0xCB, 0x2D, 0x34, 0xC6, 0x72, 0xAB, 0xA6, 0xBC, 0xB7, 0x44, 0xC6, 0x74, 0x1C, 0xD8, 0x6F, 0x37, 0x22, 0xE3,
-    0x84, 0x91, 0x80, 0xA8, 0x9D, 0x22, 0x80, 0x68, 0xCF, 0x04, 0xA4, 0xE7, 0xFA, 0x52, 0x35, 0x5C, 0x1D, 0x9E, 0x85,
-    0x17, 0x51, 0x26, 0x26, 0x4E, 0xB2, 0x9C, 0xE8, 0x0D, 0xEA, 0x38, 0xF4, 0x62, 0xEF, 0x9D, 0x11, 0xF1, 0xF0, 0x62,
-    0x4F, 0x79, 0x99, 0xF1, 0x84, 0xB1, 0x10, 0xE7, 0x69, 0xC6, 0x8B, 0xAE, 0x2A, 0xEC, 0x2F, 0x73, 0xBA, 0xB5, 0x08,
-    0x5C, 0x1F, 0xBA, 0xF1, 0x9C, 0x78, 0x53, 0xE1, 0x6F, 0x01, 0x51, 0x00, 0xE7, 0x41, 0xF5, 0x97, 0xB2, 0xE7, 0x6F,
-    0x6A, 0x19, 0xA9, 0xEF, 0x6A, 0x0F, 0x39, 0x68, 0x45, 0xF8, 0x23, 0x39, 0xB1, 0xAA, 0x66, 0x2F, 0x34, 0xA7, 0x77,
-    0xEC, 0xAE, 0xAB, 0x0B, 0xBB, 0xC0, 0x2B, 0xAE, 0xA1, 0xDB, 0x35, 0x52, 0xDC, 0xAF, 0x5B, 0x5B, 0x50, 0x01, 0x21,
-    0x80, 0xF7, 0x2C, 0xC0, 0x8E, 0xE9, 0xBF, 0x50, 0x63, 0xCA, 0x9A, 0x9B, 0x35, 0x26, 0x1C, 0x5D, 0x8C, 0x4B, 0x36,
-    0x53, 0x79, 0x6A, 0xF8, 0x91, 0xAA, 0x3F, 0xD6, 0x09, 0x54, 0x30, 0x48, 0x70, 0xCB, 0xC8, 0x5F, 0xA2, 0x44, 0x11,
-    0x06, 0xFD, 0x06, 0xB3, 0x7D, 0xF5, 0xC4, 0x9B, 0x1F, 0x1A, 0x2F, 0x44, 0x1D, 0xA7, 0x7F, 0xF2, 0x78, 0x35, 0xF4,
-    0x37, 0x93, 0xA2, 0x83, 0x94, 0x4B, 0x29, 0xCC, 0xF3, 0xCB, 0xFE, 0x64, 0x1B, 0x32, 0xA7, 0xB4, 0x24, 0xF4, 0x94,
-    0xE8, 0xB7, 0xD7, 0x40, 0x4E, 0x0F, 0x14, 0x6A, 0x8F, 0x24, 0x60, 0x77, 0x94, 0xC6, 0x85, 0x79, 0xE3, 0xAC, 0x92,
-    0x3E, 0xBA, 0x5B, 0x9E, 0x9F, 0x17, 0x3B, 0xB2, 0x28, 0xCF, 0xAA, 0x87, 0x56, 0x8D, 0x8B, 0x41, 0x1C, 0x75, 0x91,
-    0xBC, 0xAC, 0x55, 0x37, 0x05, 0xA8, 0x30, 0x22, 0x34, 0x51, 0x31, 0xF5, 0x5F, 0x23, 0x45, 0xA6, 0x41, 0xC7, 0xA9,
-    0x38, 0x53, 0x32, 0xA3, 0x16, 0x17, 0xF3, 0xC0, 0xC5, 0x64, 0x5E, 0x5F, 0x5C, 0x9B, 0xA9, 0xC5, 0x9C, 0x2C, 0xD2,
-    0x5E, 0x6E, 0x79, 0x03, 0x00, 0xA1, 0xDB, 0x18, 0x71, 0xD7, 0x72, 0x9F, 0xB2, 0x8E, 0x83, 0xD6, 0x24, 0xF5, 0x74,
-    0xAC, 0xA2, 0xE7, 0x99, 0x18, 0x30, 0x63, 0xD1, 0xF8, 0x5D, 0x3F, 0xF9, 0xF9, 0x83, 0x49, 0xD1, 0xE0, 0x62, 0x86,
-    0xF9, 0x77, 0x2A, 0xBE, 0x76, 0x82, 0xCD, 0x03, 0x0D, 0xFA, 0x70, 0x51, 0x43, 0x0E, 0xE7, 0x27, 0xD7, 0x9A, 0x95,
-    0x2B, 0x7F, 0x73, 0xC9, 0x60, 0x40, 0xBD, 0x7F, 0xE9, 0x1D, 0x05, 0x00, 0x36, 0x08, 0x0A, 0x8A, 0xF7, 0x13, 0x71,
-    0x72, 0x09, 0x66, 0x48, 0x2B, 0x32, 0xC6, 0xFA, 0xBA, 0x33, 0xC5, 0x1E, 0x7F, 0x8D, 0x04, 0x5C, 0x17, 0xD8, 0xCF,
-    0x4B, 0xBB, 0xD6, 0x1B, 0x7B, 0x82, 0xF0, 0x64, 0x1E, 0x79, 0x19, 0x4C, 0xB0, 0x62, 0x58, 0x67, 0x51, 0x3E, 0xDE,
-    0x66, 0xE1, 0xA3, 0x23, 0x0D, 0x6A, 0xDE, 0x7A, 0x11, 0xEB, 0x7B, 0xF8, 0x6B, 0x10, 0xC3, 0xA7, 0x81, 0x37, 0x52,
-    0xDA, 0x45, 0xB1, 0xAE, 0x37, 0xB0, 0x90, 0xE3, 0xCA, 0x0C, 0x91, 0x94, 0x5C, 0x77, 0xDD, 0xD1, 0x90, 0xF0, 0x43,
-    0x32, 0xCA, 0x4B, 0x82, 0x9B, 0x95, 0xF3, 0x85, 0x0E, 0x5B, 0xAE, 0xEA, 0x29, 0x7C, 0x0C, 0x18, 0x3A, 0xFC, 0xD0,
-    0xEB, 0xC1, 0x3A, 0x71, 0x93, 0x24, 0xDC, 0x46, 0x15, 0x0A, 0x5B, 0xE6, 0xED, 0x56, 0x90, 0x18, 0x47, 0x2B, 0xBC,
-    0x8D, 0x51, 0x68, 0x33, 0x65, 0x02, 0x0B, 0x68, 0xDB, 0xAA, 0x02, 0xBB, 0xA3, 0xD7, 0x33, 0x81, 0xBD, 0x21, 0x50,
-    0x34, 0xAD, 0xA5, 0x20, 0x38, 0x61, 0xB7, 0xB6, 0x14, 0x65, 0xD7, 0x80, 0x84, 0x16, 0x4A, 0x26, 0x5B, 0xC5, 0x43,
-    0x13, 0xA1, 0xE5, 0x2E, 0xAE, 0x94, 0xD7, 0x65, 0x2A, 0xB6, 0x25, 0x96, 0x73, 0xB5, 0x85, 0x8D, 0xB8, 0xC4, 0x25,
-    0x05, 0xBC, 0x89, 0x39, 0x2A, 0xE8, 0x69, 0x35, 0xD4, 0x4D, 0xBE, 0xAB, 0x5E, 0x1E, 0xB9, 0x33, 0x01, 0x18, 0x35,
-    0x7D, 0x25, 0x7D, 0x62, 0x85, 0xAD, 0x02, 0x83, 0xD2, 0x91, 0x03, 0x3E, 0x1F, 0x45, 0x5E, 0x20, 0x28, 0xB4, 0xE2,
-    0xAC, 0x35, 0xBC, 0x6B, 0x97, 0xD9, 0x49, 0x0D, 0xFD, 0x51, 0xF6, 0x70, 0xF7, 0xEB, 0x6E, 0x28, 0x49, 0xAE, 0x3F,
-    0x48, 0x35, 0x90, 0xC1, 0x13, 0x0C, 0x7F, 0x93, 0x5F, 0xB2, 0x66, 0x65, 0x48, 0x0F, 0x90, 0x97, 0x9A, 0xC5, 0x62,
-    0xE5, 0xC2, 0x19, 0x7F, 0x92, 0xF8, 0x54, 0x90, 0xA3, 0xB4, 0xE0, 0x1B, 0x39, 0x43, 0xE9, 0x3C, 0xE4, 0xEC, 0x5B,
-    0xE7, 0xF3, 0x3D, 0x1F, 0x18, 0xAE, 0x0E, 0xCF, 0x76, 0x72, 0x60, 0x9F, 0xFE, 0x72, 0x04, 0x3D, 0xAE, 0xD8, 0xC3,
-    0x9F, 0x83, 0xFA, 0xED, 0x12, 0x11, 0xB3, 0x8B, 0x68, 0xBF, 0x1D, 0xFC, 0xD3, 0x24, 0x4C, 0x56, 0xAA, 0x5B, 0xC4,
-    0xCD, 0x0D, 0x55, 0xD0, 0x79, 0x0B, 0x6D, 0x69, 0x6D, 0x66, 0x81, 0x65, 0x4B, 0x93, 0xE9, 0xAC, 0xB8, 0xFA, 0x8F,
-    0xE1, 0x10, 0xA6, 0xF2, 0x3F, 0x98, 0x4C, 0xCE, 0x94, 0x9D, 0x13, 0x2F, 0x50, 0x95, 0x68, 0xB9, 0xE1, 0x6E, 0x84,
-    0x25, 0xF7, 0x19, 0xC0, 0x49, 0xB1, 0xD0, 0xA5, 0xA5, 0x96, 0xBC, 0x43, 0xAA, 0xB9, 0x79, 0x07, 0xE0, 0xA8, 0x76,
-    0xCB, 0x56, 0x80, 0x75, 0x34, 0x80, 0x88, 0xBD, 0xE5, 0xC1, 0xF4, 0x53, 0x36, 0x04, 0x3B, 0xA1, 0x8A, 0xDC, 0xA4,
-    0x68, 0x27, 0x16, 0x65, 0xA0, 0xC3, 0x81, 0x6C, 0xE4, 0x3C, 0x6A, 0x9E, 0xFB, 0x95, 0x3C, 0x9B, 0xFB, 0xEA, 0x90,
-    0x79, 0x79, 0xD8, 0xE9, 0x04, 0x46, 0x95, 0x5A, 0x78, 0xD5, 0x01, 0x34, 0x4D, 0x1F, 0xA9, 0x50, 0xB7};
-
-uint8_t expectedData[] = {
-    0xFE, 0xB3, 0x7F, 0xC7, 0xFB, 0xAA, 0xEE, 0xDB, 0xF3, 0xA6, 0xB9, 0xDE, 0xC5, 0xCC, 0xE5, 0xF5, 0xF3, 0xBB, 0x86,
-    0xFA, 0xD3, 0xDE, 0xA1, 0x9F, 0xD8, 0xC2, 0xD0, 0xE4, 0xF2, 0xD6, 0xCB, 0xCD, 0xE6, 0xCD, 0xB2, 0xF6, 0xB9, 0xCD,
-    0xEA, 0xCF, 0x7F, 0xDD, 0xD5, 0xF1, 0xC1, 0xC8, 0xFF, 0xC2, 0xA3, 0xEA, 0xB9, 0x91, 0xFE, 0xC2, 0xB3, 0x64, 0xF4,
-    0xE6, 0xF3, 0xEC, 0x97, 0xE0, 0xEE, 0xD6, 0xB7, 0xE9, 0xF8, 0x91, 0xAA, 0xE7, 0xFA, 0x9B, 0x54, 0xE3, 0x84, 0x9E,
-    0xCB, 0xC8, 0x9D, 0xA2, 0x7F, 0xF2, 0xB2, 0xFD, 0xF4, 0xB3, 0xEA, 0xF5, 0xF4, 0xC6, 0xEF, 0xAE, 0xCC, 0xF3, 0xF0,
-    0xFE, 0xBA, 0xF5, 0x97, 0xB2, 0xE7, 0xC6, 0xF4, 0x9C, 0xE8, 0xEF, 0xE1, 0x6F, 0xBA, 0x68, 0x9E, 0xF8, 0xAE, 0xA1,
-    0xDB, 0xAA, 0xCF, 0xDC, 0xAF, 0xA7, 0x8D, 0xF5, 0xAE, 0xAB, 0x80, 0xF7, 0xC0, 0xC7, 0xC5, 0xF8, 0x6B, 0xD2, 0xC3,
-    0xDE, 0x81, 0xF3, 0xC0, 0xDA, 0xDB, 0xB1, 0xDE, 0xD7, 0xB0, 0xEB, 0xE3, 0xCA, 0xF9, 0xF9, 0x94, 0xF5, 0xD1, 0xEA,
-    0xD1, 0xE7, 0xF9, 0x77, 0x3A, 0xFC, 0xD1, 0xF8, 0xCD, 0xBC, 0x8D, 0xFA, 0x7F, 0xE9, 0x65, 0x15, 0xE7, 0x68, 0xE6,
-    0xED, 0x95, 0xF7, 0xA3, 0xD7, 0x80, 0xD8, 0xCF, 0x4B, 0xBB, 0xD6, 0xC6, 0xFA, 0xBA, 0xF0, 0xE5, 0xB7, 0xB6, 0x94,
-    0xD7, 0xD7, 0xED, 0xB6, 0x55, 0xD4, 0x8B, 0xBE, 0xBF, 0x8D, 0xFC, 0xD3, 0x81, 0x65, 0xBC, 0xAA, 0xE9, 0xC4, 0xE2,
-    0xFA, 0xB9, 0xE1, 0x6E, 0xA6, 0xF2, 0xF7, 0x98, 0xFD, 0xCE, 0xF6, 0xD0, 0xF7, 0xEB, 0xB4, 0xBD, 0xE5, 0xC1, 0xF4,
-    0x9A, 0xC5, 0xE0, 0xE5, 0xC2, 0xCB, 0xDC, 0xA4, 0xF8, 0xB2, 0x90, 0xA3, 0xB4, 0xE0, 0xE9, 0x72, 0xE4, 0xE9, 0xFE,
-    0xE4, 0xFB, 0x95, 0xE7, 0xF3, 0xFB, 0xEA, 0x90, 0xFA};
-
-void ethosuIrqHandler() {
-    ethosu_irq_handler();
-}
-
-void inferenceProcessTask(void *pvParameters) {
-    QueueHandle_t queue = reinterpret_cast<QueueHandle_t>(pvParameters);
-
-    class InferenceProcess inferenceProcess;
-
-    while (true) {
-        xInferenceJob *job;
-
-        // Wait for inference job
-        xQueueReceive(queue, &job, portMAX_DELAY);
-        printf("Received inference job. job=%p, name=%s\n", job, job->name.c_str());
-
-        bool status = inferenceProcess.runJob(*job);
-        job->status = status;
-
-        // Return inference job response
-        xQueueSend(job->queue, &job, portMAX_DELAY);
-    }
-
-    vTaskDelete(NULL);
-}
-
-void inferenceJobTask(void *pvParameters) {
-    QueueHandle_t inferenceProcessQueue = reinterpret_cast<QueueHandle_t>(pvParameters);
-
-    // Create queue for response messages
-    QueueHandle_t senderQueue = xQueueCreate(10, sizeof(xInferenceJob *));
-
-    // Inference job
-    DataPtr networkModel(networkModelData, sizeof(networkModelData));
-    DataPtr input(inputData, sizeof(inputData));
-    DataPtr expected(expectedData, sizeof(expectedData));
-
-    xInferenceJob job;
-    xInferenceJob *j = &job;
-    job.name         = "19_08_01";
-    job.networkModel = networkModel;
-    job.input.push_back(input);
-    job.expectedOutput.push_back(expected);
-    job.queue = senderQueue;
-
-    // Send job
-    printf("Sending inference job\n");
-    xQueueSend(inferenceProcessQueue, &j, portMAX_DELAY);
-
-    // Wait for response
-    xQueueReceive(senderQueue, &j, portMAX_DELAY);
-    printf("Received inference job response. status=%u\n", j->status);
-
-    vTaskDelete(NULL);
-}
-
-} // namespace
-
-int main() {
-    // Initialize UART driver
-    uart_init();
-
-    // Initialize Ethos-U driver
-    if (ethosu_init(reinterpret_cast<const void *>(ETHOSU_BASE_ADDRESS))) {
-        printf("Failed to initialize Arm Ethos-U.\n");
-        return 1;
-    }
-
-    NVIC_SetVector(static_cast<IRQn_Type>(ETHOSU_IRQ), reinterpret_cast<uint32_t>(&ethosuIrqHandler));
-    NVIC_EnableIRQ(static_cast<IRQn_Type>(ETHOSU_IRQ));
-
-    // Inference process
-    QueueHandle_t inferenceProcessQueue = xQueueCreate(10, sizeof(xInferenceJob *));
-    xTaskCreate(inferenceProcessTask, "inferenceProcess", 2 * 1024, inferenceProcessQueue, 1, nullptr);
-
-    // Inference job task
-    xTaskCreate(inferenceJobTask, "inferenceJob", 2 * 1024, inferenceProcessQueue, 2, nullptr);
-
-    // Run the scheduler
-    vTaskStartScheduler();
-
-    return 0;
-}
diff --git a/targets/corstone-300/platform.scatter b/targets/corstone-300/platform.scatter
index e3037a7..2ab371f 100644
--- a/targets/corstone-300/platform.scatter
+++ b/targets/corstone-300/platform.scatter
@@ -26,22 +26,90 @@
 #define HEAP_SIZE 0x8000
 #endif
 
-APP_IMAGE 0x00000000 0x01000000
+#if defined(TRUSTZONE_BUILD) && !defined(ETHOSU_TEST)
+/*
+ * Include trustzone.h with common addresses and sizes.
+ * The build configuration sets whether TRUSTZONE_SECURE is set or
+ * TRUSTZONE_NONSECURE which sets the memory start addresses and sizes.
+ */
+
+#include "trustzone.h"
+#define USE_TRUSTZONE
+
+#else //TRUSTZONE_BUILD
+
+#define LR_START   0x10000000
+#define LR_SIZE    0x01000000
+
+#define ITCM_START 0x10000000
+#define ITCM_SIZE  0x00080000
+
+#define BRAM_START 0x11000000
+#define BRAM_SIZE  0x00200000
+
+#define DTCM_START 0x30000000
+#define DTCM_SIZE  0x00080000
+
+#define SRAM_START 0x31000000
+#define SRAM_SIZE  0x00200000
+
+#define DDR_START  0x70000000
+#define DDR_SIZE   0x02000000
+
+#define STACK_HEAP 0x30080000
+
+#endif //TRUSTZONE_BUILD
+
+/* ----------------------------------------------------------------------------
+  Stack seal size definition
+ *----------------------------------------------------------------------------*/
+#if defined(USE_TRUSTZONE) && defined(TRUSTZONE_SECURE)
+#define __STACKSEAL_SIZE   ( 8 )
+#else
+#define __STACKSEAL_SIZE   ( 0 )
+#endif
+
+APP_IMAGE LR_START LR_SIZE
 {
     ; ITCM 512kB
-    rom_exec 0x00000000 0x00080000
+    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
         .ANY (+RO)
     }
 
+#if defined(USE_TRUSTZONE) && defined(TRUSTZONE_SECURE)
+    ; MPS3 BRAM
     ; Shared between Cortex-M and the NPU
-    DATA_SRAM 0x01000000 UNINIT 0x00200000 {}
+    BRAM BRAM_START UNINIT (BRAM_SIZE - TZ_NSC_SIZE)
+    {
+    }
+
+    ROM_NSC TZ_NSC_START TZ_NSC_SIZE
+    {
+        *(Veneer$$CMSE)
+    }
+#else
+    ; MPS3 BRAM
+    BRAM BRAM_START UNINIT BRAM_SIZE
+    {
+    }
+#endif
+
+    ; DTCM 512kB
+    ; Only accessible from the Cortex-M
+    DTCM DTCM_START (DTCM_SIZE - STACK_SIZE - HEAP_SIZE - __STACKSEAL_SIZE)
+    {
+        .ANY1 (+RW +ZI)
+    }
 
     ; SSE-300 SRAM (3 cycles read latency) from M55/U55
     ; 2x2MB - only first part mapped
-    SRAM 0x21000000 UNINIT 0x00200000
+    SRAM SRAM_START UNINIT SRAM_SIZE
     {
 #ifndef ETHOSU_FAST_MEMORY_SIZE
         ; Place tensor arena in SRAM if we do not have a fast memory area
@@ -51,25 +119,29 @@
 #endif
     }
 
-    ; DTCM 512kB
-    ; Only accessible from the Cortex-M
-    DTCM 0x20000000 (0x00080000 - STACK_SIZE - HEAP_SIZE)
-    {
-        .ANY (+RW +ZI)
-    }
+    ARM_LIB_HEAP  (STACK_HEAP - STACK_SIZE - __STACKSEAL_SIZE - HEAP_SIZE) EMPTY ALIGN 8 HEAP_SIZE {}
+    ARM_LIB_STACK (STACK_HEAP - STACK_SIZE - __STACKSEAL_SIZE) EMPTY ALIGN 8 STACK_SIZE {}
 
-    ARM_LIB_HEAP  (0x20080000 - STACK_SIZE - HEAP_SIZE) EMPTY ALIGN 8 HEAP_SIZE {}
-    ARM_LIB_STACK (0x20080000 - STACK_SIZE) EMPTY ALIGN 8 STACK_SIZE {}
+#if defined(USE_TRUSTZONE) && defined(TRUSTZONE_SECURE)
+    STACKSEAL +0 EMPTY __STACKSEAL_SIZE {
+        ; Reserve empty region for stack seal immediately after stack
+    }
+#endif
 }
 
-LOAD_REGION_1 0x60000000 0x02000000
+LOAD_REGION_1 DDR_START DDR_SIZE
 {
     ; 2GB DDR4 available
-    rom_dram 0x60000000 0x02000000
+    rom_dram DDR_START
+#if defined(USE_TRUSTZONE) && defined(TRUSTZONE_NONSECURE)
+    {
+    }
+#else //trustzone secure or non-trustzone
     {
         * (network_model_sec)
         * (input_data_sec)
         * (expected_output_data_sec)
+        * (output_data_sec)
     }
 
 #ifdef ETHOSU_FAST_MEMORY_SIZE
@@ -79,4 +151,5 @@
         * (.bss.NoInit) ; Tensor Arena
     }
 #endif
+#endif
 }
diff --git a/targets/corstone-300/retarget.c b/targets/corstone-300/retarget.c
index 1598427..d53431f 100644
--- a/targets/corstone-300/retarget.c
+++ b/targets/corstone-300/retarget.c
@@ -183,7 +183,28 @@
 }
 
 void RETARGET(_exit)(int return_code) {
-    exit(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') {
+        uart_putc(*p++);
+    }
+
+    while (1) {}
 }
 
 int system(const char *cmd) {
@@ -231,12 +252,6 @@
     return 0;
 }
 
-void exit(int code) {
-    uart_putc((char)0x4);
-    uart_putc((char)code);
-    while (1) {}
-}
-
 int fputc(int ch, FILE *f) {
     (void)(f);
     return uart_putc(ch);
diff --git a/targets/corstone-300/target.cpp b/targets/corstone-300/target.cpp
new file mode 100644
index 0000000..3d18680
--- /dev/null
+++ b/targets/corstone-300/target.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/****************************************************************************
+ * Includes
+ ****************************************************************************/
+
+#include "target.hpp"
+
+#ifdef ETHOSU
+#include <ethosu_driver.h>
+#endif
+
+#include "uart.h"
+
+#include <stdio.h>
+
+using namespace EthosU;
+
+/****************************************************************************
+ * Defines
+ ****************************************************************************/
+
+#define ETHOSU_BASE_ADDRESS 0x48102000
+
+#define ETHOSU_IRQ 56
+
+/****************************************************************************
+ * 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
+
+/****************************************************************************
+ * 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 {
+
+#ifdef ETHOSU
+void ethosuIrqHandler() {
+    ethosu_irq_handler();
+}
+#endif
+
+} // namespace
+
+namespace EthosU {
+
+void targetSetup() {
+    // Initialize UART driver
+    uart_init();
+
+#ifdef ETHOSU
+    // Initialize Ethos-U NPU driver
+    if (ethosu_init_v3(reinterpret_cast<void *>(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<IRQn_Type>(ETHOSU_IRQ), (uint32_t)&ethosuIrqHandler);
+    NVIC_EnableIRQ(static_cast<IRQn_Type>(ETHOSU_IRQ));
+#endif
+}
+
+} // namespace EthosU