diff --git a/system/testcodes/bootloader/bootloader_defs.makefile b/system/testcodes/bootloader/bootloader_defs.makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f110d1d7f11702c4717003b25a131b3b0e9e6961
--- /dev/null
+++ b/system/testcodes/bootloader/bootloader_defs.makefile
@@ -0,0 +1 @@
+LINKER_NAME = cmsdk_bootloader
\ No newline at end of file
diff --git a/system/testcodes/defs.makefile b/system/testcodes/defs.makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a5bdf8615ceb63406701b3f76a6617c8ed1dc3e9
--- /dev/null
+++ b/system/testcodes/defs.makefile
@@ -0,0 +1,134 @@
+#//-----------------------------------------------------------------------------
+#// NanoSoC Software Build Defs Makefile
+#// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+#//
+#// Contributors
+#//
+#// David Mapstone (d.a.mapstone@soton.ac.uk)
+#//
+#// Copyright � 2021-3, SoC Labs (www.soclabs.org)
+#//-----------------------------------------------------------------------------
+
+# Program file
+SOFTWARE_NAME    ?= bootloader
+
+include $(SOFTWARE_NAME)/$(SOFTWARE_NAME)_defs.makefile
+
+# Choose the core instantiated, can be
+#  - CORTEX_M0
+CPU_PRODUCT = CORTEX_M0
+
+TARGET = arm-none-eabi
+
+# Tool chain : ds6 / ds5 / gcc / keil
+TOOL_CHAIN     ?= ds5
+
+# Shared software directory
+SOFTWARE_DIR = $(NANOSOC_TECH_DIR)/software
+CMSIS_DIR    = $(SOFTWARE_DIR)/cmsis
+CORE_DIR     = $(CMSIS_DIR)/CMSIS/Include
+
+DEVICE_DIR    = $(CMSIS_DIR)/Device/ARM/CMSDK_CM0
+USER_DEFINE   = -DCORTEX_M0
+
+ifeq ($(TOOL_CHAIN),ds5)
+  CPU_TYPE      = --cpu Cortex-M0
+endif
+
+ifeq ($(TOOL_CHAIN),ds6)
+  CPU_TYPE        = -mcpu=Cortex-M0
+endif
+
+ifeq ($(TOOL_CHAIN),gcc)
+  CPU_TYPE        = -mcpu=cortex-m0
+endif
+
+
+# Endian Option
+COMPILE_BIGEND = 0
+
+DEPS_LIST       = makefile
+
+# Startup code directory for Development Studio
+ifeq ($(TOOL_CHAIN),ds5)
+ STARTUP_DIR  = $(DEVICE_DIR)/Source/ARM
+endif
+
+ifeq ($(TOOL_CHAIN),ds6)
+ STARTUP_DIR  = $(DEVICE_DIR)/Source/ARM
+endif
+
+# Startup code directory for gcc
+ifeq ($(TOOL_CHAIN),gcc)
+ STARTUP_DIR  = $(DEVICE_DIR)/Source/GCC
+endif
+
+STARTUP_FILE = startup_CMSDK_CM0
+SYSTEM_FILE  = system_CMSDK_CM0
+
+# ---------------------------------------------------------------------------------------
+# Development Studio options
+
+# MicroLIB option
+COMPILE_MICROLIB = 0
+
+# Small Multiply (Cortex-M0/M0+ has small multiplier option)
+COMPILE_SMALLMUL = 0
+
+# C and ASM Compiler Tool Setup - use armcc and armasm for ds-5 and armclang for ds-6
+ifeq ($(TOOL_CHAIN),ds5)
+  CC_TOOL   = armcc
+  ASM_TOOL = armasm
+  ARM_TARGET = -Otime
+endif
+
+ifeq ($(TOOL_CHAIN),ds6)
+  ARM_TARGET = --target=arm-$(TARGET)
+  CC_TOOL   = armclang
+  ASM_TOOL = armclang -masm=armasm $(ARM_TARGET) -c
+endif
+
+ARM_CC_OPTIONS   = $(ARM_TARGET) -c -O3 -g -I $(DEVICE_DIR)/Include -I $(CORE_DIR) $(USER_DEFINE)
+
+ARM_ASM_OPTIONS  = -g
+ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
+		--rw_base 0x30000000 --ro_base 0x10000000 --map
+
+ifeq ($(COMPILE_BIGEND),1)
+ # Big Endian
+ ARM_CC_OPTIONS   += --bigend
+ ARM_ASM_OPTIONS  += --bigend
+ ARM_LINK_OPTIONS += --be8
+endif
+
+ifeq ($(COMPILE_MICROLIB),1)
+ # MicroLIB
+ ARM_CC_OPTIONS   += --library_type=microlib
+ ARM_ASM_OPTIONS  += --library_type=microlib --pd "__MICROLIB SETA 1"
+ ARM_LINK_OPTIONS += --library_type=microlib
+endif
+
+ifeq ($(COMPILE_SMALLMUL),1)
+ # In Cortex-M0, small multiply takes 32 cycles
+ ARM_CC_OPTIONS  += --multiply_latency=32
+endif
+
+# ---------------------------------------------------------------------------------------
+# gcc options
+
+GNG_CC      = $(TARGET)-gcc
+GNU_OBJDUMP = $(TARGET)-objdump
+GNU_OBJCOPY = $(TARGET)-objcopy
+
+LINKER_NAME        ?= cmsdk_cm0
+LINKER_SCRIPT_PATH  = $(SOFTWARE_DIR)/common/scripts
+LINKER_SCRIPT       = $(LINKER_SCRIPT_PATH)/$(LINKER_NAME).ld
+
+GNU_CC_FLAGS = -g -O3 -mthumb $(CPU_TYPE)
+
+ifeq ($(COMPILE_BIGEND),1)
+ # Big Endian
+ GNU_CC_FLAGS   += -mbig-endian
+endif
+# ---------------------------------------------------------------------------------------
+
diff --git a/system/testcodes/makefile b/system/testcodes/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..48b0a9ba82dcbd5764a6acece389b21aca192904
--- /dev/null
+++ b/system/testcodes/makefile
@@ -0,0 +1,139 @@
+#//-----------------------------------------------------------------------------
+#// customised Cortex-M0 'nanosoc' controller
+#// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
+#//
+#// Contributors
+#//
+#// David Flynn (d.w.flynn@soton.ac.uk)
+#//
+#// Copyright � 2021-3, SoC Labs (www.soclabs.org)
+#//-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# The confidential and proprietary information contained in this file may
+# only be used by a person authorised under and to the extent permitted
+# by a subsisting licensing agreement from Arm Limited or its affiliates.
+#
+#            (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates.
+#                ALL RIGHTS RESERVED
+#
+# This entire notice must be reproduced on all copies of this file
+# and copies of this file may only be made by a person if such person is
+# permitted to do so under the terms of a subsisting license agreement
+# from Arm Limited or its affiliates.
+#
+#      SVN Information
+#
+#      Checked In          : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
+#
+#      Revision            : $Revision: 371321 $
+#
+#      Release Information : Cortex-M System Design Kit-r1p1-00rel0
+#-----------------------------------------------------------------------------
+#
+# Cortex-M System Design Kit software compilation make file
+#
+#-----------------------------------------------------------------------------
+#
+#  Configurations
+#
+include defs.makefile
+
+all: all_$(TOOL_CHAIN)
+
+# ---------------------------------------------------------------------------------------
+# DS-5
+all_ds5 : $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex $(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst
+all_ds6 : $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex $(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst
+
+
+$(SOFTWARE_NAME)/$(SOFTWARE_NAME).o :  $(SOFTWARE_DIR)/common/bootloader/$(SOFTWARE_NAME).c $(DEPS_LIST)
+	$(CC_TOOL) $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+$(SOFTWARE_NAME)/$(SYSTEM_FILE).o : $(DEVICE_DIR)/Source/$(SYSTEM_FILE).c $(DEPS_LIST)
+	$(CC_TOOL) $(ARM_CC_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+$(SOFTWARE_NAME)/$(STARTUP_FILE).o : $(STARTUP_DIR)/$(STARTUP_FILE).s $(DEPS_LIST)
+	$(ASM_TOOL) $(ARM_ASM_OPTIONS) $(CPU_TYPE) $< -o  $@
+
+$(SOFTWARE_NAME)/$(SOFTWARE_NAME).ELF : $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o $(SOFTWARE_NAME)/$(SYSTEM_FILE).o $(SOFTWARE_NAME)/$(STARTUP_FILE).o $(DEPS_LIST)
+	armlink $(ARM_LINK_OPTIONS) $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o $(SOFTWARE_NAME)/$(SYSTEM_FILE).o  $(SOFTWARE_NAME)/$(STARTUP_FILE).o -o $@
+
+$(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex : $(SOFTWARE_NAME)/$(SOFTWARE_NAME).ELF $(DEPS_LIST)
+	fromelf --vhx --8x1 $< --output $@
+
+$(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst : $(SOFTWARE_NAME)/$(SOFTWARE_NAME).ELF $(DEPS_LIST)
+	fromelf -c -d -e -s $< --output $@
+
+# ---------------------------------------------------------------------------------------
+# gcc
+
+all_gcc:
+	$(GNG_CC) $(GNU_CC_FLAGS) $(STARTUP_DIR)/$(STARTUP_FILE).s \
+		$(SOFTWARE_DIR)/common/bootloader/$(SOFTWARE_NAME).c \
+		$(DEVICE_DIR)/Source/$(SYSTEM_FILE).c \
+		-I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
+		-L $(LINKER_SCRIPT_PATH) \
+		-D__STACK_SIZE=0x200 \
+		-D__HEAP_SIZE=0x1000 \
+		$(USER_DEFINE) -T $(LINKER_SCRIPT) -o $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o
+	# Generate disassembly code
+	$(GNU_OBJDUMP) -S $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o > $(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst
+	# Generate binary file
+	$(GNU_OBJCOPY) -S $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o -O binary $(SOFTWARE_NAME)/$(SOFTWARE_NAME).bin
+	# Generate hex file
+	$(GNU_OBJCOPY) -S $(SOFTWARE_NAME)/$(SOFTWARE_NAME).o --adjust-vma -0x10000000 -O verilog $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex
+
+# Note:
+# Objcopy use --adjust-vma so that the Verilog hex address start at address 0 instead of actual address 0x10000000
+#
+# If the version of object copy you are using does not support verilog hex file output,
+# you can generate the hex file from binary file using the following command
+#       od -v -A n -t x1 --width=1  $(TESTNAME).bin > $(TESTNAME).hex
+
+
+# ---------------------------------------------------------------------------------------
+# Keil MDK
+
+all_keil:
+	@echo "Please compile your project code and press ENTER when ready"
+	@read dummy
+
+# ---------------------------------------------------------------------------------------
+# Binary
+
+all_bin: $(SOFTWARE_NAME)/$(SOFTWARE_NAME).bin
+	# Generate hex file from binary
+	od -v -A n -t x1 --width=1  $(SOFTWARE_NAME)/$(SOFTWARE_NAME).bin > $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex
+
+# ---------------------------------------------------------------------------------------
+# Clean
+clean :
+	@rm -rf *.o
+	@if [ -e $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex ] ; then \
+	  rm -rf $(SOFTWARE_NAME)/$(SOFTWARE_NAME).hex ; \
+	fi
+	@if [ -e $(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst ] ; then \
+	  rm -rf $(SOFTWARE_NAME)/$(SOFTWARE_NAME).lst ; \
+	fi
+	@if [ -e $(SOFTWARE_NAME)/$(SOFTWARE_NAME).ELF ] ; then \
+	  rm -rf $(SOFTWARE_NAME)/$(SOFTWARE_NAME).ELF ; \
+	fi
+	@if [ -e $(SOFTWARE_NAME)/$(SOFTWARE_NAME).bin ] ; then \
+	  rm -rf $(SOFTWARE_NAME)/$(SOFTWARE_NAME).bin ; \
+	fi
+	@rm -rf *.crf
+	@rm -rf *.plg
+	@rm -rf *.tra
+	@rm -rf *.htm
+	@rm -rf *.map
+	@rm -rf *.dep
+	@rm -rf *.d
+	@rm -rf *.lnp
+	@rm -rf *.bak
+	@rm -rf *.lst
+	@rm -rf *.axf
+	@rm -rf *.sct
+	@rm -rf *.__i
+	@rm -rf *._ia
+