summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2021-04-02 14:17:53 -0700
committerGitHub <noreply@github.com>2021-04-02 14:17:53 -0700
commit3fee3ac61fcab2dbc7a376e969a6b2cf213f3724 (patch)
treeb32c91e6e7bbea9bcbd74ee1537615d2e3391183
parentaaece955299c9e25709ca477fcaeb0f5dd49bbf3 (diff)
downloadfreertos-git-3fee3ac61fcab2dbc7a376e969a6b2cf213f3724.tar.gz
Add RISC-V demo for the spike simulator. (#532)
* Add RISC-V demo for the spike simulator. * Figuring out what the header checker wants. * Fix more headers. * Ignore htif.c and htif.h for header checks. These files are already stamped with BSD-3-Clause, which I'm not allowed to remove. There are numerous other files with the same license in FreeRTOS, so I assume this is fine. * Use proxy syscalls for RV32. Looks like spike won't be changed to make htif character writes work propery for RV32. This is now an even closer copy of the version in opensbi, which is arguably strictly better. * Support RV64 builds to use with spike. OpenOCD does not currently support debugging 64-bit FreeRTOS, but now that I have a target to test hopefully that will be remedied shortly. * Tweak rv32 instructions. This way you can have separate cross-tools installations that can coexist side by side. Co-authored-by: Joseph Julicher <jjulicher@mac.com>
-rwxr-xr-x.github/scripts/core_checker.py3
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/FreeRTOSConfig.h103
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/Makefile82
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/README.md106
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/fake_rom.lds117
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.c142
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.h21
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/main.c116
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/main_blinky.c137
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-reg.h42
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.c60
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.h52
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/spike-1.cfg33
-rw-r--r--FreeRTOS/Demo/RISC-V-spike-htif_GCC/start.S84
14 files changed, 1097 insertions, 1 deletions
diff --git a/.github/scripts/core_checker.py b/.github/scripts/core_checker.py
index 97e9bd590..d9d279979 100755
--- a/.github/scripts/core_checker.py
+++ b/.github/scripts/core_checker.py
@@ -265,7 +265,8 @@ FREERTOS_IGNORED_FILES = [
'requirements.txt',
'run-cbmc-proofs.py',
'.editorconfig',
- 'lcovrc'
+ 'lcovrc',
+ 'htif.c', 'htif.h'
]
FREERTOS_HEADER = [
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/FreeRTOSConfig.h
new file mode 100644
index 000000000..2b5949250
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/FreeRTOSConfig.h
@@ -0,0 +1,103 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "riscv-virt.h"
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+/* See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html */
+#define configMTIME_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIME )
+#define configMTIMECMP_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIMECMP )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 1
+#define configCPU_CLOCK_HZ ( 1000000 )
+#define configTICK_RATE_HZ ( ( TickType_t ) 10 )
+#define configMAX_PRIORITIES ( 7 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 512 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) 64500 )
+#define configMAX_TASK_NAME_LEN ( 16 )
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 0
+#define configUSE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 8
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MALLOC_FAILED_HOOK 1
+#define configUSE_APPLICATION_TASK_TAG 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH 6
+#define configTIMER_TASK_STACK_DEPTH ( 110 )
+
+/* RISC-V definitions. */
+#define configISR_STACK_SIZE_WORDS 2048
+
+/* Task priorities. Allow these to be overridden. */
+#ifndef uartPRIMARY_PRIORITY
+ #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
+#endif
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_eTaskGetState 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 1
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xSemaphoreGetMutexHolder 1
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/Makefile b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/Makefile
new file mode 100644
index 000000000..929da07ef
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/Makefile
@@ -0,0 +1,82 @@
+XLEN ?= 32
+CROSS = riscv$(XLEN)-unknown-elf-
+CC = $(CROSS)gcc
+OBJCOPY = $(CROSS)objcopy
+ARCH = $(CROSS)ar
+DEBUG ?= 0
+
+ifeq ($(XLEN), 64)
+ MARCH = rv64ima
+ MABI = lp64
+ STACK_SIZE = 600
+else
+ MARCH = rv32ima
+ MABI = ilp32
+ STACK_SIZE = 300
+endif
+
+BUILD_DIR = build
+RTOS_SOURCE_DIR = $(abspath ../../Source)
+DEMO_SOURCE_DIR = $(abspath ../Common/Minimal)
+
+CPPFLAGS = \
+ -D__riscv_float_abi_soft \
+ -DportasmHANDLE_INTERRUPT=handle_trap \
+ -I . -I ../Common/include \
+ -I $(RTOS_SOURCE_DIR)/include \
+ -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V \
+ -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions
+CFLAGS = -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany \
+ -Wall \
+ -fmessage-length=0 \
+ -ffunction-sections \
+ -fdata-sections \
+ -fno-builtin-printf
+ASFLAGS = -march=$(MARCH) -mabi=$(MABI) -mcmodel=medany
+LDFLAGS = -nostartfiles -Tfake_rom.lds \
+ -Xlinker --gc-sections \
+ -Xlinker --defsym=__stack_size=$(STACK_SIZE)
+
+ifeq ($(DEBUG), 1)
+ CFLAGS += -Og -ggdb3
+else
+ CFLAGS += -Os
+endif
+
+SRCS = main.c main_blinky.c riscv-virt.c htif.c \
+ $(DEMO_SOURCE_DIR)/EventGroupsDemo.c \
+ $(DEMO_SOURCE_DIR)/TaskNotify.c \
+ $(DEMO_SOURCE_DIR)/TimerDemo.c \
+ $(DEMO_SOURCE_DIR)/blocktim.c \
+ $(DEMO_SOURCE_DIR)/dynamic.c \
+ $(DEMO_SOURCE_DIR)/recmutex.c \
+ $(RTOS_SOURCE_DIR)/event_groups.c \
+ $(RTOS_SOURCE_DIR)/list.c \
+ $(RTOS_SOURCE_DIR)/queue.c \
+ $(RTOS_SOURCE_DIR)/stream_buffer.c \
+ $(RTOS_SOURCE_DIR)/tasks.c \
+ $(RTOS_SOURCE_DIR)/timers.c \
+ $(RTOS_SOURCE_DIR)/portable/MemMang/heap_4.c \
+ $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/port.c
+
+ASMS = start.S \
+ $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/portASM.S
+
+OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) $(ASMS:%.S=$(BUILD_DIR)/%.o)
+DEPS = $(SRCS:%.c=$(BUILD_DIR)/%.d) $(ASMS:%.S=$(BUILD_DIR)/%.d)
+
+$(BUILD_DIR)/RTOSDemo.axf: $(OBJS) fake_rom.lds Makefile
+ $(CC) $(LDFLAGS) $(OBJS) -o $@
+
+$(BUILD_DIR)/%.o: %.c Makefile
+ @mkdir -p $(@D)
+ $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
+
+$(BUILD_DIR)/%.o: %.S Makefile
+ @mkdir -p $(@D)
+ $(CC) $(CPPFLAGS) $(ASFLAGS) -MMD -MP -c $< -o $@
+
+clean:
+ rm -rf $(BUILD_DIR)
+
+-include $(DEPS)
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/README.md b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/README.md
new file mode 100644
index 000000000..03e4499fb
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/README.md
@@ -0,0 +1,106 @@
+# Emulating generic RISC-V 32bit machine on spike
+
+## Requirements
+
+1. GNU RISC-V toolchains (tested on Crosstool-NG)
+2. spike from https://github.com/riscv/riscv-isa-sim
+3. OpenOCD from https://github.com/riscv/riscv-openocd
+
+## How to build toolchain
+
+Clone the Crosstool-NG and build.
+
+```
+$ git clone https://github.com/crosstool-ng/crosstool-ng
+$ cd crosstool-ng
+$ ./bootstrap
+$ ./configure --enable-local
+$ make
+$ ./ct-ng menuconfig
+```
+
+For RV32 builds, change the following configs:
+
+```
+CT_EXPERIMENTAL=y
+CT_ARCH_RISCV=y
+CT_ARCH_64=n
+CT_ARCH_ARCH=rv32ima
+CT_ARCH_ABI=ilp32
+CT_TARGET_CFLAGS="-mcmodel=medany"
+CT_TARGET_LDFLAGS="-mcmodel=medany"
+CT_MULTILIB=y
+CT_DEBUG_GDB=y
+```
+
+For RV64 builds, change the following configs:
+
+```
+CT_EXPERIMENTAL=y
+CT_ARCH_RISCV=y
+CT_ARCH_64=y
+CT_ARCH_ARCH=rv32ima
+CT_ARCH_ABI=ilp32
+CT_TARGET_CFLAGS="-mcmodel=medany"
+CT_TARGET_LDFLAGS="-mcmodel=medany"
+CT_MULTILIB=y
+CT_DEBUG_GDB=y
+```
+
+Build the GNU toolchain for RISC-V.
+
+```
+$ ./ct-ng build
+```
+
+A toolchain is installed at ~/x-tools/riscv64-unknown-elf directory.
+
+
+## How to build
+
+Add path of toolchain that is described above section.
+
+```
+$ export PATH=~/x-tools/riscv64-unknown-elf/bin:$PATH
+```
+
+To build, simply run `make`. If you want a debug build, pass `DEBUG=1`. If
+you want an RV64 build, pass `XLEN=64`.
+
+The resulting executable file is ./build/RTOSDemo.axf.
+
+## How to run
+
+RV32:
+```
+$ spike -p1 --isa RV32IMA -m0x80000000:0x10000000 --rbb-port 9824 \
+ ./build/RTOSDemo.axf
+```
+
+RV64:
+```
+$ spike -p1 --isa RV64IMA -m0x80000000:0x10000000 --rbb-port 9824 \
+ ./build/RTOSDemo.axf
+```
+
+## How to debug with gdb
+
+Start OpenOCD in one terminal:
+```
+$ openocd -f spike-1.cfg
+```
+
+Start gdb in another:
+```
+$ riscv64-unknown-elf-gdb ./build/RTOSDemo.axf
+...
+(gdb) target extended-remote localhost:3333
+...
+(gdb) info threads
+```
+
+(As of 3/22/2021 OpenOCD's RISC-V FreeRTOS awareness is still incomplete.)
+
+## Description
+
+This demo starts separate transmit and receive threads. The transmit thread sends integers through a queue. Both threads print out what they're sending/receiving using HTIF.
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/fake_rom.lds b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/fake_rom.lds
new file mode 100644
index 000000000..b63fad8f0
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/fake_rom.lds
@@ -0,0 +1,117 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY( _start )
+
+MEMORY
+{
+ /* Fake ROM area */
+ rom (rxa) : ORIGIN = 0x80000000, LENGTH = 512K
+ ram (wxa) : ORIGIN = 0x80080000, LENGTH = 512K
+}
+
+SECTIONS
+{
+ .init :
+ {
+ _text = .;
+ KEEP (*(SORT_NONE(.init)))
+ } >rom AT>rom
+
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom AT>rom
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ _etext = .;
+ } >rom AT>rom
+
+ .rodata.align :
+ {
+ . = ALIGN(4);
+ _rodata = .;
+ } >rom AT>rom
+
+ .rodata.start :
+ {
+ _rodata_lma = LOADADDR(.rodata.start);
+ } >rom AT>rom
+
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+
+ . = ALIGN(4);
+ _erodata = .;
+ } >rom AT>rom
+
+ .data.align :
+ {
+ . = ALIGN(4);
+ _data = .;
+ } >ram AT>rom
+
+ .data.start :
+ {
+ _data_lma = LOADADDR(.data.start);
+ } >ram AT>rom
+
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.sdata2 .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+
+ . = ALIGN(4);
+ _edata = .;
+ } >ram AT>rom
+
+ .bss.align :
+ {
+ . = ALIGN(4);
+ _bss = .;
+ } >ram AT>rom
+
+ .bss.start :
+ {
+ _bss_lma = LOADADDR(.bss.start);
+ } >ram AT>rom
+
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram AT>rom
+
+ . = ALIGN(8);
+ _end = .;
+
+ .stack :
+ {
+ . = ALIGN(16);
+ . += __stack_size;
+ _stack_top = .;
+ } >ram AT>ram
+}
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.c b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.c
new file mode 100644
index 000000000..74c30c23c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.c
@@ -0,0 +1,142 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020, The Regents of the University of California
+ * (Regents). All Rights Reserved.
+ */
+
+#include <htif.h>
+
+#define HTIF_DATA_BITS 48
+#define HTIF_DATA_MASK ((1ULL << HTIF_DATA_BITS) - 1)
+#define HTIF_DATA_SHIFT 0
+#define HTIF_CMD_BITS 8
+#define HTIF_CMD_MASK ((1ULL << HTIF_CMD_BITS) - 1)
+#define HTIF_CMD_SHIFT 48
+#define HTIF_DEV_BITS 8
+#define HTIF_DEV_MASK ((1ULL << HTIF_DEV_BITS) - 1)
+#define HTIF_DEV_SHIFT 56
+
+#define HTIF_DEV_SYSTEM 0
+#define HTIF_DEV_CONSOLE 1
+
+#define HTIF_CONSOLE_CMD_GETC 0
+#define HTIF_CONSOLE_CMD_PUTC 1
+
+#if __riscv_xlen == 64
+# define TOHOST_CMD(dev, cmd, payload) \
+ (((uint64_t)(dev) << HTIF_DEV_SHIFT) | \
+ ((uint64_t)(cmd) << HTIF_CMD_SHIFT) | \
+ (uint64_t)(payload))
+#else
+# define TOHOST_CMD(dev, cmd, payload) ({ \
+ if ((dev) || (cmd)) __builtin_trap(); \
+ (payload); })
+#endif
+#define FROMHOST_DEV(fromhost_value) \
+ ((uint64_t)((fromhost_value) >> HTIF_DEV_SHIFT) & HTIF_DEV_MASK)
+#define FROMHOST_CMD(fromhost_value) \
+ ((uint64_t)((fromhost_value) >> HTIF_CMD_SHIFT) & HTIF_CMD_MASK)
+#define FROMHOST_DATA(fromhost_value) \
+ ((uint64_t)((fromhost_value) >> HTIF_DATA_SHIFT) & HTIF_DATA_MASK)
+
+#define PK_SYS_write 64
+
+volatile uint64_t tohost __attribute__((section(".htif")));
+volatile uint64_t fromhost __attribute__((section(".htif")));
+static int htif_console_buf;
+
+static void __check_fromhost()
+{
+ uint64_t fh = fromhost;
+ if (!fh)
+ return;
+ fromhost = 0;
+
+ /* this should be from the console */
+ if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
+ __builtin_trap();
+ switch (FROMHOST_CMD(fh)) {
+ case HTIF_CONSOLE_CMD_GETC:
+ htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
+ break;
+ case HTIF_CONSOLE_CMD_PUTC:
+ break;
+ default:
+ __builtin_trap();
+ }
+}
+
+static void __set_tohost(uint64_t dev, uint64_t cmd, uint64_t data)
+{
+ while (tohost)
+ __check_fromhost();
+ tohost = TOHOST_CMD(dev, cmd, data);
+}
+
+#if __riscv_xlen == 32
+static void do_tohost_fromhost(uint64_t dev, uint64_t cmd, uint64_t data)
+{
+ __set_tohost(HTIF_DEV_SYSTEM, cmd, data);
+
+ while (1) {
+ uint64_t fh = fromhost;
+ if (fh) {
+ if (FROMHOST_DEV(fh) == HTIF_DEV_SYSTEM &&
+ FROMHOST_CMD(fh) == cmd) {
+ fromhost = 0;
+ break;
+ }
+ __check_fromhost();
+ }
+ }
+}
+
+void htif_putc(char ch)
+{
+ /* HTIF devices are not supported on RV32, so do a proxy write call */
+ volatile uint64_t magic_mem[8];
+ magic_mem[0] = PK_SYS_write;
+ magic_mem[1] = HTIF_DEV_CONSOLE;
+ magic_mem[2] = (uint64_t)(uintptr_t)&ch;
+ magic_mem[3] = HTIF_CONSOLE_CMD_PUTC;
+ do_tohost_fromhost(HTIF_DEV_SYSTEM, 0, (uint64_t)(uintptr_t)magic_mem);
+}
+#else
+void htif_putc(char ch)
+{
+ __set_tohost(HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_PUTC, ch);
+}
+#endif
+
+int htif_getc(void)
+{
+ int ch;
+
+#if __riscv_xlen == 32
+ /* HTIF devices are not supported on RV32 */
+ return -1;
+#endif
+
+ __check_fromhost();
+ ch = htif_console_buf;
+ if (ch >= 0) {
+ htif_console_buf = -1;
+ __set_tohost(HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
+ }
+
+ return ch - 1;
+}
+
+int htif_system_reset_check(uint32_t type, uint32_t reason)
+{
+ return 1;
+}
+
+void htif_system_reset(uint32_t type, uint32_t reason)
+{
+ while (1) {
+ fromhost = 0;
+ tohost = 1;
+ }
+}
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.h b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.h
new file mode 100644
index 000000000..1b08d365b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/htif.h
@@ -0,0 +1,21 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020, The Regents of the University of California
+ * (Regents). All Rights Reserved.
+ */
+
+#ifndef __HTIF_H__
+#define __HTIF_H__
+
+#include <stdint.h>
+
+void htif_putc(char ch);
+
+int htif_getc(void);
+
+int htif_system_reset_check(uint32_t type, uint32_t reason);
+
+void htif_system_reset(uint32_t type, uint32_t reason);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main.c b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main.c
new file mode 100644
index 000000000..1d4b78f32
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main.c
@@ -0,0 +1,116 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+/* FreeRTOS kernel includes. */
+#include <FreeRTOS.h>
+#include <task.h>
+
+/* Run a simple demo just prints 'Blink' */
+#define DEMO_BLINKY 1
+
+void vApplicationMallocFailedHook( void );
+void vApplicationIdleHook( void );
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
+void vApplicationTickHook( void );
+
+int main_blinky( void );
+
+/*-----------------------------------------------------------*/
+
+int main( void )
+{
+ int ret;
+
+#if defined(DEMO_BLINKY)
+ ret = main_blinky();
+#else
+#error "Please add or select demo."
+#endif
+
+ return ret;
+}
+
+/*-----------------------------------------------------------*/
+
+void vApplicationMallocFailedHook( void )
+{
+ /* vApplicationMallocFailedHook() will only be called if
+ configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
+ function that will get called if a call to pvPortMalloc() fails.
+ pvPortMalloc() is called internally by the kernel whenever a task, queue,
+ timer or semaphore is created. It is also called by various parts of the
+ demo application. If heap_1.c or heap_2.c are used, then the size of the
+ heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
+ FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
+ to query the size of free heap space that remains (although it does not
+ provide information on how the remaining heap might be fragmented). */
+ taskDISABLE_INTERRUPTS();
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationIdleHook( void )
+{
+ /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
+ to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
+ task. It is essential that code added to this hook function never attempts
+ to block in any way (for example, call xQueueReceive() with a block time
+ specified, or call vTaskDelay()). If the application makes use of the
+ vTaskDelete() API function (as this demo application does) then it is also
+ important that vApplicationIdleHook() is permitted to return to its calling
+ function, because it is the responsibility of the idle task to clean up
+ memory allocated by the kernel to any task that has since been deleted. */
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
+{
+ ( void ) pcTaskName;
+ ( void ) pxTask;
+
+ /* Run time stack overflow checking is performed if
+ configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
+ function is called if a stack overflow is detected. */
+ taskDISABLE_INTERRUPTS();
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationTickHook( void )
+{
+}
+/*-----------------------------------------------------------*/
+
+void vAssertCalled( void )
+{
+volatile uint32_t ulSetTo1ToExitFunction = 0;
+
+ taskDISABLE_INTERRUPTS();
+ while( ulSetTo1ToExitFunction != 1 )
+ {
+ __asm volatile( "NOP" );
+ }
+}
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main_blinky.c b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main_blinky.c
new file mode 100644
index 000000000..f2604f8b2
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/main_blinky.c
@@ -0,0 +1,137 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+/* FreeRTOS kernel includes. */
+#include <FreeRTOS.h>
+#include <task.h>
+#include <queue.h>
+
+#include <stdio.h>
+
+#include "riscv-virt.h"
+
+/* Priorities used by the tasks. */
+#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+
+/* The rate at which data is sent to the queue. The 200ms value is converted
+to ticks using the pdMS_TO_TICKS() macro. */
+#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
+
+/* The maximum number items the queue can hold. The priority of the receiving
+task is above the priority of the sending task, so the receiving task will
+preempt the sending task and remove the queue items each time the sending task
+writes to the queue. Therefore the queue will never have more than one item in
+it at any time, and even with a queue length of 1, the sending task will never
+find the queue full. */
+#define mainQUEUE_LENGTH ( 1 )
+
+/*-----------------------------------------------------------*/
+
+/* The queue used by both tasks. */
+static QueueHandle_t xQueue = NULL;
+
+/*-----------------------------------------------------------*/
+
+static void prvQueueSendTask( void *pvParameters )
+{
+ TickType_t xNextWakeTime;
+ unsigned long ulValueToSend = 0UL;
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ /* Initialise xNextWakeTime - this only needs to be done once. */
+ xNextWakeTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ /* Place this task in the blocked state until it is time to run again. */
+ vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
+
+ ulValueToSend++;
+
+ char buf[40];
+ sprintf( buf, "%d: %s: send %ld", xGetCoreID(),
+ pcTaskGetName( xTaskGetCurrentTaskHandle() ),
+ ulValueToSend );
+ vSendString( buf );
+
+ /* 0 is used as the block time so the sending operation will not block -
+ * it shouldn't need to block as the queue should always be empty at
+ * this point in the code. */
+ xQueueSend( xQueue, &ulValueToSend, 0U );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static void prvQueueReceiveTask( void *pvParameters )
+{
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ for( ;; )
+ {
+
+ unsigned long ulReceivedValue;
+ /* Wait until something arrives in the queue - this task will block
+ indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
+ FreeRTOSConfig.h. */
+ xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
+
+ /* To get here something must have been received from the queue. */
+ char buf[40];
+ sprintf( buf, "%d: %s: received %ld", xGetCoreID(),
+ pcTaskGetName( xTaskGetCurrentTaskHandle() ),
+ ulReceivedValue );
+ vSendString( buf );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+int main_blinky( void )
+{
+ vSendString( "Hello FreeRTOS!" );
+
+ /* Create the queue. */
+ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
+
+ if( xQueue != NULL )
+ {
+ /* Start the two tasks as described in the comments at the top of this
+ file. */
+ xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE * 2U, NULL,
+ mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
+ xTaskCreate( prvQueueSendTask, "Tx", configMINIMAL_STACK_SIZE * 2U, NULL,
+ mainQUEUE_SEND_TASK_PRIORITY, NULL );
+ }
+
+ vTaskStartScheduler();
+
+ return 0;
+}
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-reg.h b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-reg.h
new file mode 100644
index 000000000..f199f2154
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-reg.h
@@ -0,0 +1,42 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#ifndef RISCV_REG_H_
+#define RISCV_REG_H_
+
+#if __riscv_xlen == 32
+#define REGSIZE 4
+#define REGSHIFT 2
+#define LOAD lw
+#define STOR sw
+#elif __riscv_xlen == 64
+#define REGSIZE 8
+#define REGSHIFT 3
+#define LOAD ld
+#define STOR sd
+#endif /* __riscv_xlen */
+
+#endif /* RISCV_REG_H_ */
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.c b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.c
new file mode 100644
index 000000000..a1fd73b22
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.c
@@ -0,0 +1,60 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#include <FreeRTOS.h>
+
+#include <string.h>
+
+#include "riscv-virt.h"
+#include "htif.h"
+
+int xGetCoreID( void )
+{
+int id;
+
+ __asm ("csrr %0, mhartid" : "=r" ( id ) );
+
+ return id;
+}
+
+void vSendString( const char *s )
+{
+ portENTER_CRITICAL();
+
+ while (*s) {
+ htif_putc(*s);
+ s++;
+ }
+ htif_putc('\n');
+
+ portEXIT_CRITICAL();
+}
+
+void handle_trap(void)
+{
+ while (1)
+ ;
+}
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.h b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.h
new file mode 100644
index 000000000..c22d9a664
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/riscv-virt.h
@@ -0,0 +1,52 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#ifndef RISCV_VIRT_H_
+#define RISCV_VIRT_H_
+
+#include "riscv-reg.h"
+
+#ifdef __ASSEMBLER__
+#define CONS(NUM, TYPE)NUM
+#else
+#define CONS(NUM, TYPE)NUM##TYPE
+#endif /* __ASSEMBLER__ */
+
+#define PRIM_HART 0
+
+#define CLINT_ADDR CONS(0x02000000, UL)
+#define CLINT_MSIP CONS(0x0000, UL)
+#define CLINT_MTIMECMP CONS(0x4000, UL)
+#define CLINT_MTIME CONS(0xbff8, UL)
+
+#ifndef __ASSEMBLER__
+
+int xGetCoreID( void );
+void vSendString( const char * s );
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* RISCV_VIRT_H_ */
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/spike-1.cfg b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/spike-1.cfg
new file mode 100644
index 000000000..572a94ea2
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/spike-1.cfg
@@ -0,0 +1,33 @@
+adapter_khz 10000
+
+interface remote_bitbang
+remote_bitbang_host localhost
+remote_bitbang_port 9824
+
+set _CHIPNAME riscv
+jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos auto
+#target create $_TARGETNAME riscv -chain-position $_TARGETNAME
+$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 8096 -work-area-backup 1
+
+
+gdb_report_data_abort enable
+gdb_report_register_access_error enable
+
+# Expose an unimplemented CSR so we can test non-existent register access
+# behavior.
+riscv expose_csrs 2288
+riscv expose_custom 1,12345-12348
+
+init
+
+set challenge [riscv authdata_read]
+riscv authdata_write [expr $challenge + 1]
+
+halt
+
+reg mstatus 0
+
+arm semihosting enable
diff --git a/FreeRTOS/Demo/RISC-V-spike-htif_GCC/start.S b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/start.S
new file mode 100644
index 000000000..08a5114b4
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V-spike-htif_GCC/start.S
@@ -0,0 +1,84 @@
+/*
+ * FreeRTOS V202012.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#include "riscv-virt.h"
+
+ .section .init
+ .globl _start
+ .type _start,@function
+_start:
+ .cfi_startproc
+ .cfi_undefined ra
+.option push
+.option norelax
+ la gp, __global_pointer$
+.option pop
+
+ // Continue primary hart
+ csrr a0, mhartid
+ li a1, PRIM_HART
+ bne a0, a1, secondary
+
+ // Primary hart
+ la sp, _stack_top
+
+ // Load data section
+ la a0, _data_lma
+ la a1, _data
+ la a2, _edata
+ bgeu a1, a2, 2f
+1:
+ LOAD t0, (a0)
+ STOR t0, (a1)
+ addi a0, a0, REGSIZE
+ addi a1, a1, REGSIZE
+ bltu a1, a2, 1b
+2:
+
+ // Clear bss section
+ la a0, _bss
+ la a1, _ebss
+ bgeu a0, a1, 2f
+1:
+ STOR zero, (a0)
+ addi a0, a0, REGSIZE
+ bltu a0, a1, 1b
+2:
+
+ // argc, argv, envp is 0
+ li a0, 0
+ li a1, 0
+ li a2, 0
+ jal main
+1:
+ wfi
+ j 1b
+
+secondary:
+ // TODO: Multicore is not supported
+ wfi
+ j secondary
+ .cfi_endproc