Add Corstone-300 target

Change-Id: I34e9845abdccb3363953bd70fad7c6420865291e
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..6052b78
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+
+---
+Language: Cpp
+BasedOnStyle: LLVM
+IndentWidth: 4
+ColumnLimit: 120
+AccessModifierOffset: -4
+PointerAlignment: Right
+
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: true
+AlignConsecutiveMacros: true
+AlignEscapedNewlines: Left
+AlignTrailingComments: true
+
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortBlocksOnASingleLine: true
+AlwaysBreakTemplateDeclarations: true
+
+BinPackArguments: false
+BinPackParameters: false
+
+BreakInheritanceList: AfterColon
+BreakConstructorInitializers: AfterColon
+BreakBeforeBraces: Custom
+
+BraceWrapping:
+    AfterClass: false
+    AfterControlStatement: false
+    AfterEnum: false
+    AfterFunction: false
+    AfterNamespace: false
+    AfterObjCDeclaration: true
+    AfterStruct: false
+    AfterUnion: false
+    AfterExternBlock: false
+    BeforeCatch: false
+    BeforeElse: false
+    IndentBraces: false
+    SplitEmptyFunction: false
+    SplitEmptyRecord: false
+    SplitEmptyNamespace: true
+---
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/README.md b/README.md
index 480477a..8c5eb2d 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,43 @@
 [core_software](https://review.mlplatform.org/plugins/gitiles/ml/ethos-u/ethos-u-core-software)
 repository.
 
+# Targets
+
+## Corstone-300
+
+The
+[Corstone-300](https://developer.arm.com/ip-products/subsystem/corstone/corstone-300)
+is a reference design of how to to build a secure System on Chip (SoC). A fixed
+virtual platform (FVP) of the Corstone-300 including the Arm Ethos-U can be
+downloaded from the Ecosystem page at
+[developer.arm.com](https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps).
+
+### Building
+
+Building with default settings requires CMake for the configuration and make for
+building. This will produce an elf file which can be run on the FVP.
+
+```
+$ cmake -B build/corstone-300 targets/corstone-300
+$ make -C build/corstone-300
+```
+
+It is also possible to build with a different toolchain.
+
+```
+$ cmake -B build/corstone-300 targets/corstone-300 -DCMAKE_TOOLCHAIN_FILE=$PWD/cmake/toolchain/arm-none-eabi-gcc.cmake
+$ make -C build/corstone-300
+```
+
+### Testing
+
+Assuming that the Corstone-300 FVP has been downloaded, installed and placed in
+the PATH variable. Then the software binary can be tested like this.
+
+```
+$ FVP_Corstone_SSE-300_Ethos-U55 build/corstone-300/ethosu_corstone_300.elf
+```
+
 # License
 
 The Arm Ethos-U Core Platform is provided under an Apache-2.0 license. Please
diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake
new file mode 100644
index 0000000..e3b604a
--- /dev/null
+++ b/cmake/helpers.cmake
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+function(ethosu_link_options target scope)
+    cmake_parse_arguments(ARG "" "LINK_FILE" "" ${ARGN})
+
+    if (CMAKE_CXX_COMPILER_ID STREQUAL "ARMClang")
+        set(LINK_FILE_OUT ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_LINK_FILE}.scatter)
+        set(LINK_FILE_OPTION "--scatter")
+
+    elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+        set(LINK_FILE ${ARG_LINK_FILE}.ld)
+        set(LINK_FILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/${LINK_FILE})
+        set(LINK_FILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/${LINK_FILE})
+        set(LINK_FILE_OPTION "-T")
+
+        set(prop "$<TARGET_PROPERTY:${target},COMPILE_DEFINITIONS>")
+        add_custom_command(
+            OUTPUT ${LINK_FILE_OUT}
+            DEPENDS ${LINK_FILE_IN}
+            BYPRODUCTS ${LINK_FILE_OUT}
+            COMMAND ${CMAKE_C_COMPILER} -E -x c -P -o ${LINK_FILE_OUT} ${LINK_FILE_IN}
+            COMMAND_EXPAND_LISTS "$<$<BOOL:${prop}>:-D$<JOIN:${prop},;-D>>"
+            COMMENT "Preprocessing and generating linker script"
+            VERBATIM)
+        add_custom_target(${target}-linker-script
+            DEPENDS ${LINK_FILE_OUT}
+            VERBATIM)
+        add_dependencies(${target} ${target}-linker-script)
+    endif()
+
+    target_link_options(${target} ${scope} ${LINK_FILE_OPTION} ${LINK_FILE_OUT})
+    set_target_properties(${target} PROPERTIES LINK_DEPENDS ${LINK_FILE_OUT})
+endfunction()
diff --git a/cmake/toolchain/arm-none-eabi-gcc.cmake b/cmake/toolchain/arm-none-eabi-gcc.cmake
new file mode 100644
index 0000000..ea95eef
--- /dev/null
+++ b/cmake/toolchain/arm-none-eabi-gcc.cmake
@@ -0,0 +1,91 @@
+#
+# 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.
+#
+
+if (NOT TARGET_CPU)
+    set(TARGET_CPU "cortex-m4")
+endif()
+
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
+set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
+
+# Convert TARGET_CPU=Cortex-M33+nofp+nodsp into
+#   - CMAKE_SYSTEM_PROCESSOR=cortex-m33
+#   - TARGET_CPU_FEATURES=no-fp;no-dsp
+string(REPLACE "+" ";" TARGET_CPU_FEATURES ${TARGET_CPU})
+list(POP_FRONT TARGET_CPU_FEATURES CMAKE_SYSTEM_PROCESSOR)
+string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR)
+
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# Select C/C++ version
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_CXX_STANDARD 14)
+
+# Compile options
+add_compile_options(
+    -mcpu=${TARGET_CPU}
+    -mthumb
+    "$<$<COMPILE_LANGUAGE:CXX>:-fno-unwind-tables;-fno-rtti;-fno-exceptions>")
+
+# Link options
+add_link_options(
+    -mcpu=${TARGET_CPU}
+    -mthumb
+    --specs=nosys.specs)
+
+# Set floating point unit
+if("${TARGET_CPU}" MATCHES "\\+fp")
+    set(FLOAT hard)
+elseif("${TARGET_CPU}" MATCHES "\\+nofp")
+    set(FLOAT soft)
+elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "cortex-m33" OR
+       "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "cortex-m55")
+    set(FLOAT hard)
+else()
+    set(FLOAT soft)
+endif()
+
+if (FLOAT)
+    add_compile_options(-mfloat-abi=${FLOAT})
+    add_link_options(-mfloat-abi=${FLOAT})
+endif()
+
+# Compilation warnings
+add_compile_options(
+    -Wall
+    -Wextra
+    -Wsign-compare
+    -Wunused
+    -Wswitch-default
+#    -Wformat
+    -Wdouble-promotion
+    -Wredundant-decls
+    -Wshadow
+#    -Wcast-align
+    -Wnull-dereference
+    -Wno-format-extra-args
+    -Wno-unused-function
+    -Wno-unused-parameter
+    -Wno-unused-label
+    -Wno-missing-field-initializers
+    -Wno-return-type)
diff --git a/cmake/toolchain/armclang.cmake b/cmake/toolchain/armclang.cmake
new file mode 100644
index 0000000..72eb456
--- /dev/null
+++ b/cmake/toolchain/armclang.cmake
@@ -0,0 +1,86 @@
+#
+# 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.
+#
+
+if (NOT TARGET_CPU)
+    set(TARGET_CPU "cortex-m4")
+endif()
+
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_C_COMPILER "armclang")
+set(CMAKE_CXX_COMPILER "armclang")
+set(CMAKE_LINKER "armlink")
+
+# Convert TARGET_CPU=Cortex-M33+nofp+nodsp into
+#   - CMAKE_SYSTEM_PROCESSOR=cortex-m33
+#   - __CPU_FEATURES=no-fp;no-dsp
+string(REPLACE "+" ";" __CPU_FEATURES ${TARGET_CPU})
+list(POP_FRONT __CPU_FEATURES CMAKE_SYSTEM_PROCESSOR)
+string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR)
+
+# Link target
+set(__LINK_TARGET ${CMAKE_SYSTEM_PROCESSOR})
+
+if ("nodsp" IN_LIST __CPU_FEATURES)
+    string(APPEND __LINK_TARGET ".no_dsp")
+endif()
+
+if ("nofp" IN_LIST __CPU_FEATURES)
+    string(APPEND __LINK_TARGET ".no_fp")
+endif()
+
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "cortex-m55")
+    set(__LINK_TARGET 8.1-M.Main.dsp)
+endif()
+
+# Define C/C++ standards
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_CXX_STANDARD 14)
+
+# Compile options
+add_compile_options(
+    -mcpu=${TARGET_CPU}
+    -mthumb
+    "$<$<CONFIG:DEBUG>:-gdwarf-3>"
+    "$<$<COMPILE_LANGUAGE:CXX>:-fno-unwind-tables;-fno-rtti;-fno-exceptions>")
+
+# Link options
+add_link_options(
+    --cpu=${__LINK_TARGET}
+    --lto
+    --info common,debug,sizes,totals,veneers,unused
+    --symbols
+    --diag_suppress=L6439W)
+
+# Compilation warnings
+add_compile_options(
+    -Wall
+    -Wextra
+    -Wsign-compare
+    -Wunused
+    -Wswitch-default
+    -Wformat
+    -Wdouble-promotion
+    -Wredundant-decls
+    -Wshadow
+    -Wcast-align
+    -Wnull-dereference
+    -Wno-format-extra-args
+    -Wno-unused-function
+    -Wno-unused-label
+    -Wno-missing-field-initializers
+    -Wno-return-type)
diff --git a/targets/corstone-300/CMakeLists.txt b/targets/corstone-300/CMakeLists.txt
new file mode 100644
index 0000000..b141ac9
--- /dev/null
+++ b/targets/corstone-300/CMakeLists.txt
@@ -0,0 +1,75 @@
+#
+# 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.
+#
+
+#############################################################################
+# Toolchain
+#############################################################################
+
+set(TARGET_CPU "cortex-m55")
+
+if (NOT CMAKE_TOOLCHAIN_FILE)
+    set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/toolchain/armclang.cmake")
+endif()
+
+#############################################################################
+# Project
+#############################################################################
+
+cmake_minimum_required(VERSION 3.15.6)
+
+project(ethos-u-corstone-300 VERSION 0.0.1)
+
+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)
+
+target_sources(ethosu_corstone_300 PRIVATE
+    main.cpp
+    retarget.c
+    uart.c)
+
+target_link_libraries(ethosu_corstone_300 PRIVATE
+    ethosu_core
+    $<TARGET_OBJECTS:cmsis_startup>
+    cmsis_device)
+
+add_dependencies(ethosu_corstone_300 cmsis_startup)
+
+target_link_options(ethosu_corstone_300 PRIVATE
+    --entry Reset_Handler)
+
+ethosu_link_options(ethosu_corstone_300 PRIVATE
+                    LINK_FILE platform)
diff --git a/targets/corstone-300/main.cpp b/targets/corstone-300/main.cpp
new file mode 100644
index 0000000..0e05993
--- /dev/null
+++ b/targets/corstone-300/main.cpp
@@ -0,0 +1,277 @@
+/*
+ * 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,
+                  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,
+                             QueueHandle_t _queue) :
+    InferenceJob(_name, _networkModel, _input, _output, _expectedOutput, _numBytesToPrint),
+    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.ld b/targets/corstone-300/platform.ld
new file mode 100644
index 0000000..937bc4c
--- /dev/null
+++ b/targets/corstone-300/platform.ld
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2009-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.
+ */
+
+/*
+ *-------- <<< Use Configuration Wizard in Context Menu >>> -------------------
+ */
+
+/*---------------------- ITCM Configuration ----------------------------------
+  <h> Flash Configuration
+    <o0> Flash Base Address <0x0-0xFFFFFFFF:8>
+    <o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
+  </h>
+  -----------------------------------------------------------------------------*/
+__ROM_BASE = 0x00000000;
+__ROM_SIZE = 0x00080000;
+
+/*--------------------- DTCM RAM Configuration ----------------------------
+  <h> RAM Configuration
+    <o0> RAM Base Address    <0x0-0xFFFFFFFF:8>
+    <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+  </h>
+ -----------------------------------------------------------------------------*/
+__RAM_BASE = 0x20000000;
+__RAM_SIZE = 0x00080000;
+
+/*--------------------- Embedded SRAM Configuration ----------------------------
+  <h> SRAM Configuration
+    <o0> SRAM Base Address    <0x0-0xFFFFFFFF:8>
+    <o1> SRAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+  </h>
+ -----------------------------------------------------------------------------*/
+__SRAM_BASE = 0x21000000;
+__SRAM_SIZE = 0x00200000;
+
+/*--------------------- Stack / Heap Configuration ----------------------------
+  <h> Stack / Heap Configuration
+    <o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+    <o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+  </h>
+  -----------------------------------------------------------------------------*/
+__STACK_SIZE = 0x00008000;
+__HEAP_SIZE  = 0x00008000;
+
+/*--------------------- Embedded RAM Configuration ----------------------------
+  <h> DDR Configuration
+    <o0> DDR Base Address    <0x0-0xFFFFFFFF:8>
+    <o1> DDR Size (in Bytes) <0x0-0xFFFFFFFF:8>
+  </h>
+ -----------------------------------------------------------------------------*/
+__DDR_BASE = 0x60000000;
+__DDR_SIZE = 0x02000000;
+
+/*
+ *-------------------- <<< end of configuration section >>> -------------------
+ */
+
+MEMORY
+{
+  ITCM  (rx)  : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
+  DTCM  (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
+  SRAM  (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
+  DDR   (rwx) : ORIGIN = __DDR_BASE, LENGTH = __DDR_SIZE
+}
+
+/* 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))
+    *(.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*))
+  } > ITCM
+
+  /*
+   * 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
+*/
+  .ARM.extab :
+  {
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+  } > ITCM
+
+  __exidx_start = .;
+  .ARM.exidx :
+  {
+    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+  } > ITCM
+  __exidx_end = .;
+
+  .copy.table :
+  {
+    . = ALIGN(4);
+    __copy_table_start__ = .;
+    LONG (__etext)
+    LONG (__data_start__)
+    LONG (__data_end__ - __data_start__)
+    /* Add each additional data section here */
+    __copy_table_end__ = .;
+  } > ITCM
+
+  .zero.table :
+  {
+    . = ALIGN(4);
+    __zero_table_start__ = .;
+    /* Add each additional bss section here */
+/*
+    LONG (__bss2_start__)
+    LONG (__bss2_end__ - __bss2_start__)
+*/
+    __zero_table_end__ = .;
+  } > ITCM
+
+  /**
+   * Location counter can end up 2byte aligned with narrow Thumb code but
+   * __etext is assumed by startup code to be the LMA of a section in DTCM
+   * which must be 4byte aligned
+   */
+  __etext = ALIGN (4);
+
+  .data : AT (__etext)
+  {
+    __data_start__ = .;
+    *(vtable)
+    *(.data)
+    *(.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__ = .;
+
+  } > DTCM
+
+  /*
+   * Secondary data section, optional
+   *
+   * Remember to add each additional data section
+   * to the .copy.table above to asure proper
+   * initialization during startup.
+   */
+/*
+  __etext2 = ALIGN (4);
+
+  .data2 : AT (__etext2)
+  {
+    . = ALIGN(4);
+    __data2_start__ = .;
+    *(.data2)
+    *(.data2.*)
+    . = ALIGN(4);
+    __data2_end__ = .;
+
+  } > RAM2
+*/
+
+#ifndef ETHOSU_FAST_MEMORY_SIZE
+  .sram :
+  {
+    . = ALIGN(16);
+    *(.bss.NoInit)
+    . = ALIGN(16);
+  } > SRAM AT > SRAM
+#else
+  .sram :
+  {
+    . = ALIGN(16);
+    *(.bss.ethosu_fast_memory);
+    . = ALIGN(16);
+  } > SRAM AT > SRAM
+
+  .bss.NoInit :
+  {
+    . = ALIGN(16);
+    *(.bss.NoInit)
+    . = ALIGN(16);
+  } > DDR AT > DDR
+#endif
+
+  .bss :
+  {
+    . = ALIGN(4);
+    __bss_start__ = .;
+    *(.bss)
+    *(.bss.*)
+    *(COMMON)
+    . = ALIGN(4);
+    __bss_end__ = .;
+  } > DTCM AT > DTCM
+
+
+  /*
+   * Secondary bss section, optional
+   *
+   * Remember to add each additional bss section
+   * to the .zero.table above to asure proper
+   * initialization during startup.
+   */
+/*
+  .bss2 :
+  {
+    . = ALIGN(4);
+    __bss2_start__ = .;
+    *(.bss2)
+    *(.bss2.*)
+    . = ALIGN(4);
+    __bss2_end__ = .;
+  } > RAM2 AT > RAM2
+*/
+
+  .ddr :
+  {
+    /* __attribute__((aligned(16))) is not handled by the cmsis startup code.
+     * Force the alignement here as a workaround */
+    . = ALIGN(4);
+    *(input_data_sec)
+    . = ALIGN(16);
+    *(network_model_sec)
+    *(expected_output_data_sec)
+    . = ALIGN (16);
+  } > DDR
+
+  .heap (COPY) :
+  {
+    . = ALIGN(8);
+    __end__ = .;
+    PROVIDE(end = .);
+    . = . + __HEAP_SIZE;
+    . = ALIGN(8);
+    __HeapLimit = .;
+  } > DTCM
+
+  .stack (ORIGIN(DTCM) + LENGTH(DTCM) - __STACK_SIZE) (COPY) :
+  {
+    . = ALIGN(8);
+    __StackLimit = .;
+    . = . + __STACK_SIZE;
+    . = ALIGN(8);
+    __StackTop = .;
+  } > DTCM
+  PROVIDE(__stack = __StackTop);
+
+  /* Check if data + heap + stack exceeds DTCM limit */
+  ASSERT(__StackLimit >= __HeapLimit, "region DTCM overflowed with stack")
+}
diff --git a/targets/corstone-300/platform.scatter b/targets/corstone-300/platform.scatter
new file mode 100644
index 0000000..e3037a7
--- /dev/null
+++ b/targets/corstone-300/platform.scatter
@@ -0,0 +1,82 @@
+#! cpp
+
+/*
+ * Copyright (c) 2019-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 STACK_SIZE
+#define STACK_SIZE 0x8000
+#endif
+
+#ifndef HEAP_SIZE
+#define HEAP_SIZE 0x8000
+#endif
+
+APP_IMAGE 0x00000000 0x01000000
+{
+    ; ITCM 512kB
+    rom_exec 0x00000000 0x00080000
+    {
+        *.o (RESET, +First)
+        *(InRoot$$Sections)
+        .ANY (+RO)
+    }
+
+    ; Shared between Cortex-M and the NPU
+    DATA_SRAM 0x01000000 UNINIT 0x00200000 {}
+
+    ; SSE-300 SRAM (3 cycles read latency) from M55/U55
+    ; 2x2MB - only first part mapped
+    SRAM 0x21000000 UNINIT 0x00200000
+    {
+#ifndef ETHOSU_FAST_MEMORY_SIZE
+        ; Place tensor arena in SRAM if we do not have a fast memory area
+        * (.bss.NoInit) ; Tensor Arena
+#else
+        * (.bss.ethosu_scratch)
+#endif
+    }
+
+    ; DTCM 512kB
+    ; Only accessible from the Cortex-M
+    DTCM 0x20000000 (0x00080000 - STACK_SIZE - HEAP_SIZE)
+    {
+        .ANY (+RW +ZI)
+    }
+
+    ARM_LIB_HEAP  (0x20080000 - STACK_SIZE - HEAP_SIZE) EMPTY ALIGN 8 HEAP_SIZE {}
+    ARM_LIB_STACK (0x20080000 - STACK_SIZE) EMPTY ALIGN 8 STACK_SIZE {}
+}
+
+LOAD_REGION_1 0x60000000 0x02000000
+{
+    ; 2GB DDR4 available
+    rom_dram 0x60000000 0x02000000
+    {
+        * (network_model_sec)
+        * (input_data_sec)
+        * (expected_output_data_sec)
+    }
+
+#ifdef ETHOSU_FAST_MEMORY_SIZE
+    ; Place tensor arena in DRAM if we have a fast memory area
+    ARENA +0 UNINIT ALIGN 16
+    {
+        * (.bss.NoInit) ; Tensor Arena
+    }
+#endif
+}
diff --git a/targets/corstone-300/retarget.c b/targets/corstone-300/retarget.c
new file mode 100644
index 0000000..1598427
--- /dev/null
+++ b/targets/corstone-300/retarget.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2019-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "uart.h"
+
+// armclang retargeting
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
+#include <rt_misc.h>
+#include <rt_sys.h>
+
+/* Standard IO device handles. */
+#define STDIN  0x8001
+#define STDOUT 0x8002
+#define STDERR 0x8003
+
+#define RETARGET(fun) _sys##fun
+
+#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
+
+#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;
+
+        while (len-- > 0) {
+            c = fputc(*buf++, stdout);
+            if (c == EOF) {
+                return EOF;
+            }
+        }
+
+        return 0;
+    }
+    default:
+        return EOF;
+    }
+}
+
+int RETARGET(_read)(FILEHANDLE fh, unsigned char *buf, unsigned int len, int mode) {
+    (void)mode;
+
+    switch (fh) {
+    case STDIN: {
+        int c;
+
+        while (len-- > 0) {
+            c = fgetc(stdin);
+            if (c == EOF) {
+                return EOF;
+            }
+
+            *buf++ = (unsigned char)c;
+        }
+
+        return 0;
+    }
+    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) {
+    exit(return_code);
+}
+
+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;
+}
+
+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);
+}
+
+int fgetc(FILE *f) {
+    (void)f;
+    return uart_putc(uart_getc());
+}
+
+#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-300/uart.c b/targets/corstone-300/uart.c
new file mode 100644
index 0000000..cba54d8
--- /dev/null
+++ b/targets/corstone-300/uart.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019-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 "uart.h"
+#include "uart_config.h"
+#include <stdint.h>
+#include <stdio.h>
+
+#define CNTLQ     0x11
+#define CNTLS     0x13
+#define DEL       0x7F
+#define BACKSPACE 0x08
+#define CR        0x0D
+#define LF        0x0A
+#define ESC       0x1B
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+
+#define __IO volatile
+#define __I  volatile const
+#define __O  volatile
+
+typedef struct {
+    __IO uint32_t DATA;  /* Offset: 0x000 (R/W) Data Register    */
+    __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register  */
+    __IO uint32_t CTRL;  /* Offset: 0x008 (R/W) Control Register */
+    union {
+        __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */
+        __O uint32_t INTCLEAR;  /* Offset: 0x00C ( /W) Interrupt Clear Register  */
+    };
+    __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */
+} CMSDK_UART_TypeDef;
+
+#define CMSDK_UART0_BASE     UART0_BASE
+#define CMSDK_UART0          ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE)
+#define CMSDK_UART0_BAUDRATE UART0_BAUDRATE
+
+void uart_init(void) {
+    // SystemCoreClock / 9600
+    CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE;
+
+    CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */
+                         (1ul << 1)); /* RX enable */
+}
+
+// Output a character
+unsigned char uart_putc(unsigned char my_ch) {
+    while ((CMSDK_UART0->STATE & 1))
+        ; // Wait if Transmit Holding register is full
+
+    if (my_ch == '\n') {
+        CMSDK_UART0->DATA = '\r';
+        while ((CMSDK_UART0->STATE & 1))
+            ; // Wait if Transmit Holding register is full
+    }
+
+    CMSDK_UART0->DATA = my_ch; // write to transmit holding register
+
+    return (my_ch);
+}
+
+// Get a character
+unsigned char uart_getc(void) {
+    unsigned char my_ch;
+    // unsigned int  cnt;
+
+    while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty
+    {
+#if 0
+        cnt = MPS3_FPGAIO->CLK100HZ / 50;
+        if (cnt & 0x8)
+            MPS3_FPGAIO->LED = 0x01 << (cnt & 0x7);
+        else
+            MPS3_FPGAIO->LED = 0x80 >> (cnt & 0x7);
+#endif
+    }
+
+    my_ch = CMSDK_UART0->DATA;
+
+    // Convert CR to LF
+    if (my_ch == '\r')
+        my_ch = '\n';
+
+    return (my_ch);
+}
+
+// Get line from terminal
+unsigned int uart_getline(char *lp, unsigned int len) {
+    unsigned int cnt = 0;
+    char c;
+
+    do {
+        c = uart_getc();
+        switch (c) {
+        case CNTLQ: /* ignore Control S/Q             */
+        case CNTLS:
+            break;
+        case BACKSPACE:
+        case DEL:
+            if (cnt == 0) {
+                break;
+            }
+            cnt--;           /* decrement count                */
+            lp--;            /* and line pointer               */
+            uart_putc(0x08); /* echo backspace                 */
+            uart_putc(' ');
+            uart_putc(0x08);
+            fflush(stdout);
+            break;
+        case ESC:
+        case 0:
+            *lp = 0; /* ESC - stop editing line        */
+            return 0;
+        case CR: /* CR - done, stop editing line   */
+            *lp = c;
+            lp++;  /* increment line pointer         */
+            cnt++; /* and count                      */
+            c = LF;
+        default:
+            uart_putc(*lp = c); /* echo and store character       */
+            fflush(stdout);
+            lp++;  /* increment line pointer         */
+            cnt++; /* and count                      */
+            break;
+        }
+    } while (cnt < len - 2 && c != LF); /* check limit and CR             */
+    *lp = 0;                            /* mark end of string             */
+    return 1;
+}
diff --git a/targets/corstone-300/uart.h b/targets/corstone-300/uart.h
new file mode 100644
index 0000000..a430e9e
--- /dev/null
+++ b/targets/corstone-300/uart.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019-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 _UART_STDOUT_H_
+#define _UART_STDOUT_H_
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void uart_init(void);
+unsigned char uart_putc(unsigned char my_ch);
+unsigned char uart_getc(void);
+unsigned int uart_getline(char *lp, unsigned int len);
+
+#if __cplusplus
+}
+#endif
+
+#endif
diff --git a/targets/corstone-300/uart_config.h b/targets/corstone-300/uart_config.h
new file mode 100644
index 0000000..3df76ab
--- /dev/null
+++ b/targets/corstone-300/uart_config.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019-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.
+ */
+
+#pragma once
+
+#define UART0_BASE        0x49303000
+#define UART0_BAUDRATE    115200
+#define SYSTEM_CORE_CLOCK 25000000