diff --git a/targets/riscv_nuclei_demo_soc_gcc/.gitignore b/targets/riscv_nuclei_demo_soc_gcc/.gitignore
new file mode 100644
index 00000000..2395b36e
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/.gitignore
@@ -0,0 +1,9 @@
+# ignore openocd logfile and build folder
+targets/*/GCC/build/
+*.log
+*.lst
+*.bin
+*.dasm
+*.elf
+*.hex
+*.map
\ No newline at end of file
diff --git a/targets/riscv_nuclei_demo_soc_gcc/GCC/Makefile b/targets/riscv_nuclei_demo_soc_gcc/GCC/Makefile
new file mode 100644
index 00000000..4277eb49
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/GCC/Makefile
@@ -0,0 +1,222 @@
+# ------------------------------------------------
+# Generic Makefile (based on gcc)
+#
+# ChangeLog :
+# 2021-04-02 - first version
+# ------------------------------------------------
+
+######################################
+# target
+######################################
+TARGET = Nuclei-demo-soc
+
+######################################
+# building variables
+######################################
+# debug build?
+DEBUG = 1
+# optimization
+OPT = -O2
+
+
+#######################################
+# paths
+#######################################
+# Build path
+BUILD_DIR = build
+
+#######################################
+# Base directory
+#######################################
+# LiteOS top path
+LITEOSTOPDIR := ../../../
+
+######################################
+# source
+######################################
+# C sources
+C_SOURCES = \
+$(wildcard ../Src/*.c) \
+$(wildcard ../SoC/hbird/Common/Source/*.c) \
+$(wildcard ../SoC/hbird/Common/Source/Drivers/*.c) \
+$(wildcard ../SoC/hbird/Common/Source/Stubs/*.c)
+
+# ASM sources
+ASMS_SOURCES = \
+$(wildcard ../SoC/hbird/Common/Source/GCC/*.S)
+
+
+#######################################
+# binaries
+#######################################
+PREFIX = riscv-nuclei-elf-
+# The gcc compiler bin path can be either defined in make command via NUCLEI_TOOL_ROOT variable (> make NUCLEI_TOOL_ROOT=xxx)
+# either it can be added to the PATH environment variable.
+NUCLEI_RISCV_GCC_ROOT ?= $(NUCLEI_TOOL_ROOT)/gcc
+NUCLEI_OPENOCD_ROOT ?= $(NUCLEI_TOOL_ROOT)/openocd
+
+NUCLEI_TOOL_ROOT_EXIST = 0
+ifneq ($(wildcard $(NUCLEI_RISCV_GCC_ROOT)),)
+ifneq ($(wildcard $(NUCLEI_OPENOCD_ROOT)),)
+NUCLEI_TOOL_ROOT_EXIST = 1
+endif
+endif
+
+ifeq ($(NUCLEI_TOOL_ROOT_EXIST),1)
+CC = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gcc
+AS = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gcc -x assembler-with-cpp
+CP = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)objcopy
+DP = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)objdump
+SZ = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)size
+GDB = $(NUCLEI_RISCV_GCC_ROOT)/bin/$(PREFIX)gdb
+OPENOCD := $(NUCLEI_OPENOCD_ROOT)/bin/openocd
+else
+CC = $(PREFIX)gcc
+AS = $(PREFIX)gcc -x assembler-with-cpp
+CP = $(PREFIX)objcopy
+DP = $(PREFIX)objdump
+SZ = $(PREFIX)size
+GDB = $(PREFIX)gdb
+OPENOCD := openocd
+endif
+HEX = $(CP) -O ihex
+BIN = $(CP) -O binary -S
+
+ECHO := echo
+
+OPENOCD_CFG := openocd_hbird.cfg
+
+#######################################
+# CFLAGS
+#######################################
+#risc-v arch & abi
+CORE_ARCH_ABI = -march=rv32imafc -mabi=ilp32f
+
+#other flags
+OTHER_FLAGS += -g -mcmodel=medany -fno-common
+
+# macros for gcc
+# AS defines
+AS_DEFS = -DDOWNLOAD_MODE=DOWNLOAD_MODE_ILM
+
+# C defines
+C_DEFS = -DDOWNLOAD_MODE=DOWNLOAD_MODE_ILM
+
+
+# AS includes
+AS_INCLUDES =
+
+# C includes
+C_INCLUDES = \
+-I../OS_CONFIG \
+-I../Src \
+-I../SoC/hbird/Board/hbird_eval/Include \
+-I../SoC/hbird/Common/Include \
+-I../SoC/hbird/Common/Source/Stubs
+
+# compile gcc flags
+ASFLAGS = $(AS_DEFS) $(OPT) $(CORE_ARCH_ABI) $(OTHER_FLAGS) $(AS_INCLUDES) -Wall -fdata-sections -ffunction-sections
+
+CFLAGS = $(C_DEFS) $(C_INCLUDES) $(OPT) $(CORE_ARCH_ABI) $(OTHER_FLAGS) -Wall -fdata-sections -ffunction-sections
+
+# Generate dependency information
+CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
+
+# Set your GDB port using variable GDB_PORT
+GDB_PORT ?= 3333
+## Makefile Variable GDBREMOTE
+## You can change GDBREMOTE to other gdb remotes
+## eg. if you have started openocd server with (bindto 0.0.0.0 defined in openocd.cfg)
+## make sure your machine can connect to remote machine
+## in remote machine(ipaddr 192.168.43.199, port 3333) which connect the hardware board,
+## then you can change the GDBREMOTE to 192.168.43.199:3333
+## GDBREMOTE ?= 192.168.43.199:3333
+GDBREMOTE ?= | $(OPENOCD) --pipe -f $(OPENOCD_CFG)
+
+GDB_UPLOAD_ARGS ?= --batch
+GDB_UPLOAD_CMDS += -ex "monitor halt"
+GDB_UPLOAD_CMDS += -ex "monitor flash protect 0 0 last off"
+GDB_UPLOAD_CMDS += -ex "load"
+GDB_UPLOAD_CMDS += -ex "monitor resume"
+GDB_UPLOAD_CMDS += -ex "quit"
+
+OPENOCD_PORT_ARGS = -c "gdb_port $(GDB_PORT)"
+
+OPENOCD_ARGS += -f $(OPENOCD_CFG)
+GDB_CMDS += -ex "set remotetimeout 240"
+GDB_CMDS += -ex "target extended-remote localhost:$(GDB_PORT)"
+
+#######################################
+# LDFLAGS
+#######################################
+# link script
+LDSCRIPT = gcc_hbird_ilm.ld
+
+# libraries
+LIBS = -lm
+LIBDIR =
+LDFLAGS = $(CORE_ARCH_ABI) $(OTHER_FLAGS) -specs=nano.specs -specs=nosys.specs -T $(LDSCRIPT) $(LIBDIR) $(LIBS) -nostartfiles -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
+
+# default action: build all
+all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).dasm $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
+
+include liteos_m.mk
+
+#######################################
+# build the application
+#######################################
+# list of objects
+OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
+vpath %.c $(sort $(dir $(C_SOURCES)))
+# list of ASM program objects
+OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o)))
+vpath %.s $(sort $(dir $(ASM_SOURCES)))
+
+$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
+ $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
+
+$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
+ $(AS) -c $(CFLAGS) $< -o $@
+
+$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile $(LDSCRIPT)
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+ $(SZ) $@
+
+$(BUILD_DIR)/%.dasm: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(DP) -D -S $< > $@
+
+$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(HEX) $< $@
+
+$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
+ $(BIN) $< $@
+
+$(BUILD_DIR):
+ mkdir $@
+
+#######################################
+# clean up
+#######################################
+clean:
+ -rm -fR $(BUILD_DIR)
+
+#######################################
+# upload & debug
+#######################################
+upload: $(BUILD_DIR)/$(TARGET).elf
+ @$(ECHO) "Download and run $<"
+ $(GDB) $< -ex "set remotetimeout 240" \
+ -ex "target remote $(GDBREMOTE)" \
+ $(GDB_UPLOAD_ARGS) $(GDB_UPLOAD_CMDS)
+
+debug: $(BUILD_DIR)/$(TARGET).elf
+ @$(ECHO) "Download and debug $<"
+ $(GDB) $< -ex "set remotetimeout 240" \
+ -ex "target remote $(GDBREMOTE)"
+
+#######################################
+# dependencies
+#######################################
+-include $(wildcard $(BUILD_DIR)/*.d)
+
+# *** EOF ***
diff --git a/targets/riscv_nuclei_demo_soc_gcc/GCC/gcc_hbird_ilm.ld b/targets/riscv_nuclei_demo_soc_gcc/GCC/gcc_hbird_ilm.ld
new file mode 100644
index 00000000..36c5954f
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/GCC/gcc_hbird_ilm.ld
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * @file gcc_hbird_ilm.ld
+ * @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
+ * @version V1.0.0
+ * @date 17. Dec 2019
+ ******************************************************************************/
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+MEMORY
+{
+
+ ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
+ ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
+}
+
+
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 10K;
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 10K;
+
+ .init :
+ {
+ *(.vtable)
+ KEEP (*(SORT_NONE(.init)))
+ } >ilm AT>ilm
+
+ .ilalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _ilm_lma = . );
+ } >ilm AT>ilm
+
+ .ialign :
+ {
+ PROVIDE( _ilm = . );
+ } >ilm AT>ilm
+
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >ilm AT>ilm
+
+ .rodata : ALIGN(4)
+ {
+ . = ALIGN(4);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ *(.gnu.linkonce.r.*)
+
+ } >ilm AT>ilm
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } >ilm AT>ilm
+
+ . = ALIGN(4);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ PROVIDE( _eilm = . );
+
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >ilm AT>ilm
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >ilm AT>ilm
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >ilm AT>ilm
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >ilm AT>ilm
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >ilm AT>ilm
+
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } >ilm AT>ilm
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } >ram AT>ilm
+
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ . = ALIGN(4);
+ __osdriv_start = .;
+ KEEP (*(osdriv))
+ __osdriv_end = .;
+ } >ram AT>ilm
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram AT>ram
+
+ . = ALIGN(8);
+ PROVIDE( end = . );
+
+ .stack : ALIGN(0x10)
+ {
+ . = __stack_size;
+ PROVIDE( _sp = . );
+ } >ram AT>ram
+ PROVIDE( _end = . );
+ .heap : ALIGN(0x10)
+ {
+ . = __heap_size;
+ PROVIDE( _heap_end = . );
+ PROVIDE( __los_heap_addr_start__ = . );
+ . = __heap_size == 0 ? 0 : ORIGIN(ram) + LENGTH(ram);
+ PROVIDE( __los_heap_addr_end__ = . );
+ } >ram AT>ram
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/GCC/liteos_m.mk b/targets/riscv_nuclei_demo_soc_gcc/GCC/liteos_m.mk
new file mode 100644
index 00000000..d12ec490
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/GCC/liteos_m.mk
@@ -0,0 +1,38 @@
+LITEOSTOPDIR := ../../../
+LITEOSTOPDIR := $(realpath $(LITEOSTOPDIR))
+
+# Common
+C_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/src/*.c) \
+ $(wildcard $(LITEOSTOPDIR)/kernel/src/mm/*.c) \
+ $(wildcard $(LITEOSTOPDIR)/components/cpup/*.c) \
+ $(wildcard $(LITEOSTOPDIR)/components/los_backtrace/*.c) \
+ $(wildcard $(LITEOSTOPDIR)/components/bounds_checking_function/src/*.c) \
+ $(wildcard $(LITEOSTOPDIR)/utils/*.c)
+
+C_INCLUDES += -I$(LITEOSTOPDIR)/utils \
+ -I$(LITEOSTOPDIR)/kernel/include \
+ -I$(LITEOSTOPDIR)/components/cpup \
+ -I$(LITEOSTOPDIR)/components/los_backtrace \
+ -I$(LITEOSTOPDIR)/components/bounds_checking_function/include
+
+# NMSIS related
+C_INCLUDES += -I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/Core/Include \
+ -I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/DSP/Include \
+ -I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/nmsis/NN/Include
+
+ASM_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.s)
+
+ASMS_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.S)
+
+C_SOURCES += $(wildcard $(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc/*.c)
+
+C_INCLUDES += -I. \
+ -I$(LITEOSTOPDIR)/kernel/arch/include \
+ -I$(LITEOSTOPDIR)/kernel/arch/risc-v/nuclei/gcc
+
+# list of ASM .S program objects
+OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
+vpath %.S $(sort $(dir $(ASMS_SOURCES)))
+
+$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
+ $(CC) -c $(CFLAGS) $< -o $@
diff --git a/targets/riscv_nuclei_demo_soc_gcc/GCC/openocd_hbird.cfg b/targets/riscv_nuclei_demo_soc_gcc/GCC/openocd_hbird.cfg
new file mode 100644
index 00000000..4f2378e7
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/GCC/openocd_hbird.cfg
@@ -0,0 +1,54 @@
+adapter_khz 1000
+
+interface ftdi
+ftdi_vid_pid 0x0403 0x6010
+ftdi_oscan1_mode on
+
+## bindto 0.0.0.0 can be used to cover all available interfaces.
+## Uncomment bindto line to enable remote machine debug
+# bindto 0.0.0.0
+
+## If ftdi_device_desc not specified, the device description is ignored during device selection.
+## So if you want to specify a dedicated FTDI device, you can select following device description:
+## "Dual RS232-HS" is for HummingBird Debugger V1
+## "USB <-> JTAG-DEBUGGER" is for HummingBird Debugger V2
+## Uncomment one which match your device description
+# ftdi_device_desc "Dual RS232-HS"
+# ftdi_device_desc "USB <-> JTAG-DEBUGGER"
+
+transport select jtag
+
+ftdi_layout_init 0x0008 0x001b
+ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
+ftdi_layout_signal TCK -data 0x0001
+ftdi_layout_signal TDI -data 0x0002
+ftdi_layout_signal TDO -input 0x0004
+ftdi_layout_signal TMS -data 0x0008
+ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
+
+set _CHIPNAME riscv
+jtag newtap $_CHIPNAME cpu -irlen 5
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME riscv -chain-position $_TARGETNAME
+$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME
+# Set the ILM space also as flash, to make sure it can be add breakpoint with hardware trigger
+#flash bank onboard_ilm fespi 0x80000000 0 0 0 $_TARGETNAME
+
+# Expose Nuclei self-defined CSRS
+# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
+# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
+riscv expose_csrs 416-496,770-800,835-850,1227-1231,1483-1486,1984-2032,2064-2070,2370-2380,2490-2500,4032-4040
+
+init
+
+if {[ info exists pulse_srst]} {
+ ftdi_set_signal nSRST 0
+ ftdi_set_signal nSRST z
+}
+halt
+# We must turn on this because otherwise the IDE version debug cannot download the program into flash
+flash protect 0 0 last off
diff --git a/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h b/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h
new file mode 100644
index 00000000..f568ecec
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/OS_CONFIG/target_config.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 Nuclei Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**@defgroup los_config System configuration items
+ * @ingroup kernel
+ */
+
+#ifndef _TARGET_CONFIG_H
+#define _TARGET_CONFIG_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/*=============================================================================
+ System clock module configuration
+=============================================================================*/
+#define OS_SYS_CLOCK (8000000)
+#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
+#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
+/*=============================================================================
+ Hardware interrupt module configuration
+=============================================================================*/
+#define LOSCFG_PLATFORM_HWI 1
+#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
+#define LOSCFG_PLATFORM_HWI_LIMIT 32
+/*=============================================================================
+ Task module configuration
+=============================================================================*/
+#define LOSCFG_BASE_CORE_TSK_LIMIT 12
+#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE (0x500U)
+#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2E0U)
+#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (0x130U)
+#define LOSCFG_BASE_CORE_TIMESLICE 1
+#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 10
+/*=============================================================================
+ Semaphore module configuration
+=============================================================================*/
+#define LOSCFG_BASE_IPC_SEM 1
+#define LOSCFG_BASE_IPC_SEM_LIMIT 48
+/*=============================================================================
+ Mutex module configuration
+=============================================================================*/
+#define LOSCFG_BASE_IPC_MUX 1
+#define LOSCFG_BASE_IPC_MUX_LIMIT 10
+/*=============================================================================
+ Queue module configuration
+=============================================================================*/
+#define LOSCFG_BASE_IPC_QUEUE 1
+#define LOSCFG_BASE_IPC_QUEUE_LIMIT 6
+/*=============================================================================
+ Software timer module configuration
+=============================================================================*/
+#define LOSCFG_BASE_CORE_SWTMR 1
+#define LOSCFG_BASE_CORE_SWTMR_ALIGN 1
+#define LOSCFG_BASE_CORE_SWTMR_LIMIT 6
+/*=============================================================================
+ Memory module configuration
+=============================================================================*/
+#define LOSCFG_SYS_HEAP_SIZE 0x9000UL
+#define OS_SYS_MEM_SIZE 0x2000UL
+#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK 0
+#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK 1
+#define LOSCFG_MEM_MUL_POOL 0
+#define OS_SYS_MEM_NUM 20
+#define LOSCFG_KERNEL_MEM_SLAB 0
+/*=============================================================================
+ Exception module configuration
+=============================================================================*/
+#define LOSCFG_PLATFORM_EXC 0
+/* =============================================================================
+ printf module configuration
+============================================================================= */
+#define LOSCFG_KERNEL_PRINTF 1
+/* =============================================================================
+ enable backtrace
+============================================================================= */
+#define LOSCFG_BACKTRACE_TYPE 0
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+
+#endif /* _TARGET_CONFIG_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/README.md b/targets/riscv_nuclei_demo_soc_gcc/README.md
new file mode 100644
index 00000000..b1b9edc5
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/README.md
@@ -0,0 +1,194 @@
+# Nuclei DDR200T开发板LiteOS使用说明
+
+## Nuclei DDR200T开发板简介
+
+Nuclei DDR200T开发板是一款集成了FPGA和通用MCU的RISC-V评估开发板。其中FPGA子系统采用Xilinx XC7A200T-2 FPGA芯片,提供板载FPGA JTAG下载器、丰富的板载存储(Flash,DDR,eMMC,EEPROM)、丰富的接口资源(数字、模拟)以及蜂鸟调试器接口。MCU子系统采用GD32VF103 MCU芯片,提供板载调试器以及JTAG调试接口。
+
+开发板资料链接:
+
+- [Nuclei DDR200T开发板详细介绍](https://www.nucleisys.com/upload/files/fpga/doc/Nuclei_FPGA_DebugKit_Intro_20201220.pdf)
+- [Nuclei DDR200T开发板原理图](https://www.nucleisys.com/upload/files/fpga/doc/Nuclei_DDR200T.pdf)
+
+## 文件结构
+
+```
+├── components # 可选组件
+│ ├── cppsupport # C++支持
+│ └── cpup # CPUP功能
+├── kal # 内核抽象层
+│ └── posix # posix标准接口支持
+├── kernel # 内核最小功能集支持
+│ ├── arch # 内核指令架构层代码
+│ │ ├── risc-v # risc-v架构的代码
+│ │ │ └── nuclei # nuclei内核相关代码
+│ │ │ └── gcc # gcc编译器相关代码
+│ │ │ ├── nmsis # nmsis内核标准
+│ │ └── include # 对外接口存放目录
+│ │ ├── los_arch_atomic.h # 定义通用arch的原子操作
+│ │ ├── los_arch_context.h # 定义通用arch的上下文切换
+│ │ ├── los_arch.h # 定义通用arch初始化
+│ │ └── los_arch_interrupt.h # 定义通用arch中断
+│ ├── include # 对外接口存放目录
+│ │ ├── los_config.h # 功能开关和配置参数
+│ │ ├── los_event.h # 事件
+│ │ ├── los_liteos.h # liteos最小功能集对外提供的头文件
+│ │ ├── los_memory.h # 堆内存管理
+│ │ ├── los_mutex.h # 互斥锁
+│ │ ├── los_queue.h # 队列
+│ │ ├── los_scheduler.h # 调度算法
+│ │ ├── los_sem.h # 信号量
+│ │ ├── los_task.h # 任务
+│ │ └── los_timer.h # 定时器
+│ └── src # 内核最小功能集源码
+├── targets # 板级工程目录
+│ ├── riscv_nuclei_demo_soc_gcc # Nuclei DDR200T开发板相关代码
+│ ├── GCC # 编译相关
+│ ├── OS_CONFIG # 开发板配置功能开关和配置参数
+│ ├── SoC # SOC相关代码
+│ └── Src # application相关代码
+├── utils # 通用公共目录
+ ├── include
+ │ ├── los_compiler.h # 编译工具配置,类型定义
+ │ ├── los_debug.h # debug,printf相关
+ │ ├── los_error.h # 错误定义
+ │ └── los_list.h
+ └── src
+```
+
+## 使用说明
+
+软件需求:linux环境
+
+硬件需求:Nuclei DDR200T开发板
+
+[环境配置](#sectionb1)
+
+[编译源码](#sectionb2)
+
+[下载调试、运行](#sectionb3)
+
+本示例将新建并运行两个任务,可以在控制台查看任务执行打印信息。
+
+### 环境配置
+
+- **工具链配置**
+
+请先确认您使用的是centos系统或Ububntu 64bit。
+
+1. 新建一个`Nuclei` 文件夹,比如`~/home/Nuclei`
+2. 参考下图,从[Nuclei Download Center](https://nucleisys.com/download.php)下载工具链和OpenOCD。
+ - CentOS或Ubuntu系统请点击图中红框1下载RISC-V GNU工具链
+ - 点击图中蓝框2-1下载64bit的OpenOCD
+ - **确保Make工具版本不低于3.82**: ubuntu系统使用`sudo apt-get install make`指令安装`make`工具, CentOS系统使用`sudo yum install make`指令安装。
+
+图1 Linux环境要下载的Nuclei Tools
+
+
+
+
+
+3. 在之前新建的`Nuclei`文件夹中新建`gcc`文件夹和`openocd`文件夹。
+ - 解压缩之前下载的**gnu工具链**到任意文件夹中,复制其中`bin`文件件所在层级的所有内容到`gcc`文件夹中。
+ - 同样解压缩之前下载的**OpenOCD**到任意文件夹中,复制其中`bin`文件件所在层级的所有内容到`openocd`文件夹中。
+
+> 注意:
+>
+> 请务必下载并解压缩Linux版本的工具,不要下载windows版本工具。
+
+- **驱动配置**
+
+驱动配置步骤如下:
+
+1. 连接开发板到Linux中,确保USB被Linux识别出来。
+
+2. 在控制台中使用lsusb指令查看信息,参考的打印信息如下:
+
+ ```
+ Bus 001 Device 010: ID 0403:6010 Future Technology Devices International, Ltd FT2232xxxx
+ ```
+
+3. 将github(https://github.com/riscv-mcu/ses_nuclei_sdk_projects/blob/master/misc/99-openocd.rules)上misc文件夹内99-openocd.rules文件复制到当前路径下,控制台中输入sudo cp 99-openocd.rules /etc/udev/rules.d/99-openocd.rules指令复制文件到指定路径下。
+
+4. 断开调试器再重新连接到Linux系统中。
+
+5. 使用ls /dev/ttyUSB*命令查看ttyUSB信息,参考输出如下:
+
+ ```
+ /dev/ttyUSB0 /dev/ttyUSB1
+ ```
+
+6. 使用ls -l /dev/ttyUSB1命令查看分组信息,参考输出如下:
+
+ ```
+ crw-rw-r-- 1 root plugdev 188, 1 Nov 28 12:53 /dev/ttyUSB1
+ ```
+
+ 可以看到ttyUSB1已经加入plugdev组,接下来我们要将自己添加到plugdev组。使用whoami命令查看当前用户名,我们将其记录为\< your_user_name >。
+
+7. 使用sudo usermod -a -G plugdev \命令将自己添加进plugdev组。
+
+8. 再次确认当前用户名已属于plugdev组,使用groups命令,可以看到打印信息中有plugdev即成功将当前用户添加至plugdev组。
+
+### 编译源码
+
+编译前请在当前控制台中配置`NUCLEI_TOOL_ROOT`路径,假设`Nuclei`文件夹所在路径为`/home/Nuclei`,输入`export NUCLEI_TOOL_ROOT=/home/Nuclei` 。或者使用时make选项增加`NUCLEI_TOOL_ROOT=/home/Nuclei`。
+
+配置路径后打开至代码根目录下的/target/riscv_nuclei_demo_soc_gcc/GCC位置,输入如下指令开始编译:
+
+```
+make all
+```
+
+编译结束后部分参考输出如下:
+
+```
+ text data bss dec hex filename
+ 21900 112 65426 87438 1558e build/Nuclei-demo-soc.elf
+```
+
+若编译前想清理工程,请使用如下指令:
+
+```
+make clean
+```
+
+### 下载调试、运行
+
+调试或运行前请先是用蜂鸟调试器连接Nuclei DDR200T开发板,确保已按照[环境配置](#sectionb1)中驱动配置部分配置完成。
+
+同样配置好`NUCLEI_TOOL_ROOT`路径并打开至代码根目录下的/target/riscv_nuclei_demo_soc_gcc/GCC位置,输入如下指令进入GDB调试:
+
+```
+make debug
+```
+
+等待到进入GDB调试界面时,输入`load`指令下载编译好的elf文件,就可以开始调试。
+
+若想直接运行,请在调试时所在位置输入如下指令:
+
+```
+make upload
+```
+
+运行时可以查看串口打印内容,使用串口查看工具,这里以`minicom`为例,若未安装此工具可自行安装或使用其他串口查看工具。打开控制台,输入`minicom -D /dev/ttyUSB1 -b 115200`指令打开串口查看工具。
+
+运行时参考输出如下:
+
+```
+Nuclei SDK Build Time: Mar 31 2021, 03:29:57
+Download Mode: ILM
+CPU Frequency 7998996 Hz
+entering kernel init...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry2 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry1 running...
+TaskSampleEntry2 running...
+TaskSampleEntry1 running...
+```
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Include/board_hbird_eval.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Include/board_hbird_eval.h
new file mode 100644
index 00000000..0c3840e8
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Include/board_hbird_eval.h
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+#ifndef _BOARD_HBIRD_EVAL_H_
+#define _BOARD_HBIRD_EVAL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "nuclei_sdk_soc.h"
+
+
+// Interrupt Numbers
+#define SOC_BUTTON_1_IRQn SOC_INT49_IRQn
+#define SOC_BUTTON_2_IRQn SOC_INT50_IRQn
+// Interrupt Handler Definitions
+#define SOC_BUTTON_1_HANDLER eclic_irq49_handler
+#define SOC_BUTTON_2_HANDLER eclic_irq50_handler
+// GPIO Bit Offset
+#define SOC_LED_RED_GPIO_OFS 19
+#define SOC_LED_GREEN_GPIO_OFS 21
+#define SOC_LED_BLUE_GPIO_OFS 22
+#define SOC_BUTTON_1_GPIO_OFS 30
+#define SOC_BUTTON_2_GPIO_OFS 31
+
+// GPIO Bit Mask
+#define SOC_LED_RED_GPIO_MASK (1<rom AT>rom
+
+ .ilalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _ilm_lma = . );
+ } >rom AT>rom
+
+ .ialign :
+ {
+ PROVIDE( _ilm = . );
+ } >rom AT>rom
+
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom AT>rom
+
+ .rodata : ALIGN(4)
+ {
+ . = ALIGN(4);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ *(.gnu.linkonce.r.*)
+
+ } >rom AT>rom
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom AT>rom
+
+ . = ALIGN(4);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ PROVIDE( _eilm = . );
+
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom AT>rom
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >rom AT>rom
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >rom AT>rom
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >rom AT>rom
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >rom AT>rom
+
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } >rom AT>rom
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } >ram AT>rom
+
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >ram AT>rom
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram AT>ram
+
+ . = ALIGN(8);
+ PROVIDE( _end = . );
+ PROVIDE( end = . );
+
+ .stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
+ {
+ PROVIDE( _heap_end = . );
+ . = __stack_size;
+ PROVIDE( _sp = . );
+ } >ram AT>ram
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flash.ld b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flash.ld
new file mode 100644
index 00000000..5e3ab24b
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flash.ld
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * @file gcc_hbird_flash.ld
+ * @brief GNU Linker Script for Nuclei N/NX based device in Flash Download Mode
+ * @version V1.0.0
+ * @date 17. Dec 2019
+ ******************************************************************************/
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+MEMORY
+{
+ flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 4M
+ ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
+ ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
+}
+
+
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+
+ .init :
+ {
+ KEEP (*(SORT_NONE(.init)))
+ } >flash AT>flash
+
+ .ilalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _ilm_lma = . );
+ } >flash AT>flash
+
+ .ialign :
+ {
+ PROVIDE( _ilm = . );
+ } >ilm AT>flash
+
+ .text :
+ {
+ *(.vtable_ilm)
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >ilm AT>flash
+
+ .rodata : ALIGN(4)
+ {
+ . = ALIGN(4);
+ } >ilm AT>flash
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } >ilm AT>flash
+
+ . = ALIGN(4);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ PROVIDE( _eilm = . );
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >flash AT>flash
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >flash AT>flash
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >flash AT>flash
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >flash AT>flash
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >flash AT>flash
+
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } >flash AT>flash
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } >ram AT>flash
+
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ . = ALIGN(4);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ *(.gnu.linkonce.r.*)
+ } >ram AT>flash
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram AT>ram
+
+ . = ALIGN(8);
+ PROVIDE( _end = . );
+ PROVIDE( end = . );
+
+ .stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
+ {
+ PROVIDE( _heap_end = . );
+ . = __stack_size;
+ PROVIDE( _sp = . );
+ } >ram AT>ram
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flashxip.ld b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flashxip.ld
new file mode 100644
index 00000000..6a8b7dd4
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_flashxip.ld
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * @file gcc_hbird_flashxip.ld
+ * @brief GNU Linker Script for Nuclei N/NX based device in FlashXIP Download Mode
+ * @version V1.0.0
+ * @date 17. Dec 2019
+ ******************************************************************************/
+
+/*********** Use Configuration Wizard in Context Menu *************************/
+
+OUTPUT_ARCH( "riscv" )
+/********************* Flash Configuration ************************************
+ * Flash Configuration
+ * Flash Base Address <0x0-0xFFFFFFFF:8>
+ * Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
+ *
+ */
+__ROM_BASE = 0x20000000;
+__ROM_SIZE = 0x00400000;
+
+/*--------------------- ILM RAM Configuration ---------------------------
+ * ILM RAM Configuration
+ * ILM RAM Base Address <0x0-0xFFFFFFFF:8>
+ * ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+ *
+ */
+__ILM_RAM_BASE = 0x80000000;
+__ILM_RAM_SIZE = 0x00010000;
+
+/*--------------------- Embedded RAM Configuration ---------------------------
+ * RAM Configuration
+ * RAM Base Address <0x0-0xFFFFFFFF:8>
+ * RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
+ *
+*/
+__RAM_BASE = 0x90000000;
+__RAM_SIZE = 0x00010000;
+
+/********************* Stack / Heap Configuration ****************************
+ * Stack / Heap Configuration
+ * Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+ * Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+ *
+ */
+__STACK_SIZE = 0x00000800;
+__HEAP_SIZE = 0x00000800;
+
+/**************************** end of configuration section ********************/
+
+/* Define base address and length of flash and ram */
+MEMORY
+{
+ flash (rxai!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
+ ram (wxa!ri) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
+}
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH,ILM and RAM.
+ * It references following symbols, which must be defined in code:
+ * _Start : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * _ilm_lma
+ * _ilm
+ * __etext
+ * _etext
+ * etext
+ * _eilm
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * _data_lma
+ * _edata
+ * edata
+ * __data_end__
+ * __bss_start
+ * __fbss
+ * _end
+ * end
+ * __heap_end
+ * __StackLimit
+ * __StackTop
+ * __STACK_SIZE
+ */
+/* Define entry label of program */
+ENTRY(_start)
+SECTIONS
+{
+ __STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2K;
+
+ .init :
+ {
+ /* vector table locate at flash */
+ *(.vtable)
+ KEEP (*(SORT_NONE(.init)))
+ } >flash AT>flash
+
+ .ilalign :
+ {
+ . = ALIGN(4);
+ /* Create a section label as _ilm_lma which located at flash */
+ PROVIDE( _ilm_lma = . );
+ } >flash AT>flash
+
+ .ialign :
+ {
+ /* Create a section label as _ilm which located at flash */
+ PROVIDE( _ilm = . );
+ } >flash AT>flash
+
+ /* Code section located at flash */
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >flash AT>flash
+
+ .rodata : ALIGN(4)
+ {
+ . = ALIGN(4);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >flash AT>flash
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } >flash AT>flash
+
+ . = ALIGN(4);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ PROVIDE( _eilm = . );
+
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >flash AT>flash
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >flash AT>flash
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >flash AT>flash
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ * the constructors, so we make sure it is
+ * first. Because this is a wildcard, it
+ * doesn't matter if the user does not
+ * actually link against crtbegin.o; the
+ * linker won't look for a file to match a
+ * wildcard. The wildcard also means that it
+ * doesn't matter which directory crtbegin.o
+ * is in.
+ */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ * the crtend.o file until after the sorted ctors.
+ * The .ctor section from the crtend file contains the
+ * end of ctors marker and it must be last
+ */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >flash AT>flash
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >flash AT>flash
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } >flash AT>flash
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } >ram AT>flash
+
+ /* Define data section virtual address is ram and physical address is flash */
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>flash
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram AT>ram
+
+ . = ALIGN(8);
+ PROVIDE( _end = . );
+ PROVIDE( end = . );
+ /* Define stack and head location at ram */
+ .stack ORIGIN(ram) + LENGTH(ram) - __STACK_SIZE :
+ {
+ PROVIDE( _heap_end = . );
+ . = __STACK_SIZE;
+ PROVIDE( _sp = . );
+ } >ram AT>ram
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_ilm.ld b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_ilm.ld
new file mode 100644
index 00000000..1ac5b909
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/Source/GCC/gcc_hbird_ilm.ld
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * @file gcc_hbird_ilm.ld
+ * @brief GNU Linker Script for Nuclei N/NX based device in ilm Download Mode
+ * @version V1.0.0
+ * @date 17. Dec 2019
+ ******************************************************************************/
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+MEMORY
+{
+
+ ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
+ ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
+}
+
+
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+
+ .init :
+ {
+ *(.vtable)
+ KEEP (*(SORT_NONE(.init)))
+ } >ilm AT>ilm
+
+ .ilalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _ilm_lma = . );
+ } >ilm AT>ilm
+
+ .ialign :
+ {
+ PROVIDE( _ilm = . );
+ } >ilm AT>ilm
+
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >ilm AT>ilm
+
+ .rodata : ALIGN(4)
+ {
+ . = ALIGN(4);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ /* section information for finsh shell */
+ . = ALIGN(4);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(4);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ *(.gnu.linkonce.r.*)
+
+ } >ilm AT>ilm
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } >ilm AT>ilm
+
+ . = ALIGN(4);
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ PROVIDE( _eilm = . );
+
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >ilm AT>ilm
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >ilm AT>ilm
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >ilm AT>ilm
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >ilm AT>ilm
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >ilm AT>ilm
+
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } >ilm AT>ilm
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } >ram AT>ilm
+
+ .data :
+ {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >ram AT>ilm
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram AT>ram
+
+ . = ALIGN(8);
+ PROVIDE( _end = . );
+ PROVIDE( end = . );
+
+ .stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
+ {
+ PROVIDE( _heap_end = . );
+ . = __stack_size;
+ PROVIDE( _sp = . );
+ } >ram AT>ram
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/openocd_hbird.cfg b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/openocd_hbird.cfg
new file mode 100644
index 00000000..a0fa06db
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Board/hbird_eval/openocd_hbird.cfg
@@ -0,0 +1,49 @@
+adapter_khz 1000
+
+interface ftdi
+## If ftdi_device_desc not specified, the device description is ignored during device selection.
+## So if you want to specify a dedicated FTDI device, you can select following device description:
+## "Dual RS232-HS" is for HummingBird Debugger V1
+## "USB <-> JTAG-DEBUGGER" is for HummingBird Debugger V2
+## Uncomment one which match your device description
+# ftdi_device_desc "Dual RS232-HS"
+# ftdi_device_desc "USB <-> JTAG-DEBUGGER"
+ftdi_vid_pid 0x0403 0x6010
+ftdi_oscan1_mode off
+
+transport select jtag
+
+ftdi_layout_init 0x0008 0x001b
+ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
+ftdi_layout_signal TCK -data 0x0001
+ftdi_layout_signal TDI -data 0x0002
+ftdi_layout_signal TDO -input 0x0004
+ftdi_layout_signal TMS -data 0x0008
+ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
+
+set _CHIPNAME riscv
+jtag newtap $_CHIPNAME cpu -irlen 5
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME riscv -chain-position $_TARGETNAME
+$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME
+# Set the ILM space also as flash, to make sure it can be add breakpoint with hardware trigger
+#flash bank onboard_ilm fespi 0x80000000 0 0 0 $_TARGETNAME
+
+# Expose Nuclei self-defined CSRS range 770-800,835-850,1984-2032,2064-2070
+# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
+# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
+riscv expose_csrs 770-800,835-850,1984-2032,2064-2070
+
+init
+#reset
+if {[ info exists pulse_srst]} {
+ ftdi_set_signal nSRST 0
+ ftdi_set_signal nSRST z
+}
+halt
+# We must turn on this because otherwise the IDE version debug cannot download the program into flash
+flash protect 0 0 last off
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird.h
new file mode 100644
index 00000000..70be9b14
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird.h
@@ -0,0 +1,459 @@
+/******************************************************************************
+ * @file hbird.h
+ * @brief NMSIS Core Peripheral Access Layer Header File for
+ * Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
+ * @version V1.00
+ * @date 22. Nov 2019
+ ******************************************************************************/
+/*
+ * Copyright (c) 2019 Nuclei 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 __HBIRD_H__
+#define __HBIRD_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup Nuclei
+ * @{
+ */
+
+
+/** @addtogroup hbird
+ * @{
+ */
+
+
+/** @addtogroup Configuration_of_NMSIS
+ * @{
+ */
+
+
+
+/* =========================================================================================================================== */
+/* ================ Interrupt Number Definition ================ */
+/* =========================================================================================================================== */
+
+typedef enum IRQn
+{
+/* ======================================= Nuclei Core Specific Interrupt Numbers ======================================== */
+
+ Reserved0_IRQn = 0, /*!< Internal reserved */
+ Reserved1_IRQn = 1, /*!< Internal reserved */
+ Reserved2_IRQn = 2, /*!< Internal reserved */
+ SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */
+ Reserved3_IRQn = 4, /*!< Internal reserved */
+ Reserved4_IRQn = 5, /*!< Internal reserved */
+ Reserved5_IRQn = 6, /*!< Internal reserved */
+ SysTimer_IRQn = 7, /*!< System Timer Interrupt */
+ Reserved6_IRQn = 8, /*!< Internal reserved */
+ Reserved7_IRQn = 9, /*!< Internal reserved */
+ Reserved8_IRQn = 10, /*!< Internal reserved */
+ Reserved9_IRQn = 11, /*!< Internal reserved */
+ Reserved10_IRQn = 12, /*!< Internal reserved */
+ Reserved11_IRQn = 13, /*!< Internal reserved */
+ Reserved12_IRQn = 14, /*!< Internal reserved */
+ Reserved13_IRQn = 15, /*!< Internal reserved */
+ Reserved14_IRQn = 16, /*!< Internal reserved */
+ Reserved15_IRQn = 17, /*!< Internal reserved */
+ Reserved16_IRQn = 18, /*!< Internal reserved */
+
+/* =========================================== hbird Specific Interrupt Numbers ========================================= */
+/* ToDo: add here your device specific external interrupt numbers. 19~1023 is reserved number for user. Maxmum interrupt supported
+ could get from clicinfo.NUM_INTERRUPT. According the interrupt handlers defined in startup_Device.s
+ eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */
+ SOC_INT19_IRQn = 19, /*!< Device Interrupt */
+ SOC_INT20_IRQn = 20, /*!< Device Interrupt */
+ SOC_INT21_IRQn = 21, /*!< Device Interrupt */
+ SOC_INT22_IRQn = 22, /*!< Device Interrupt */
+ SOC_INT23_IRQn = 23, /*!< Device Interrupt */
+ SOC_INT24_IRQn = 24, /*!< Device Interrupt */
+ SOC_INT25_IRQn = 25, /*!< Device Interrupt */
+ SOC_INT26_IRQn = 26, /*!< Device Interrupt */
+ SOC_INT27_IRQn = 27, /*!< Device Interrupt */
+ SOC_INT28_IRQn = 28, /*!< Device Interrupt */
+ SOC_INT29_IRQn = 29, /*!< Device Interrupt */
+ SOC_INT30_IRQn = 30, /*!< Device Interrupt */
+ SOC_INT31_IRQn = 31, /*!< Device Interrupt */
+ SOC_INT32_IRQn = 32, /*!< Device Interrupt */
+ SOC_INT33_IRQn = 33, /*!< Device Interrupt */
+ SOC_INT34_IRQn = 34, /*!< Device Interrupt */
+ SOC_INT35_IRQn = 35, /*!< Device Interrupt */
+ SOC_INT36_IRQn = 36, /*!< Device Interrupt */
+ SOC_INT37_IRQn = 37, /*!< Device Interrupt */
+ SOC_INT38_IRQn = 38, /*!< Device Interrupt */
+ SOC_INT39_IRQn = 39, /*!< Device Interrupt */
+ SOC_INT40_IRQn = 40, /*!< Device Interrupt */
+ SOC_INT41_IRQn = 41, /*!< Device Interrupt */
+ SOC_INT42_IRQn = 42, /*!< Device Interrupt */
+ SOC_INT43_IRQn = 43, /*!< Device Interrupt */
+ SOC_INT44_IRQn = 44, /*!< Device Interrupt */
+ SOC_INT45_IRQn = 45, /*!< Device Interrupt */
+ SOC_INT46_IRQn = 46, /*!< Device Interrupt */
+ SOC_INT47_IRQn = 47, /*!< Device Interrupt */
+ SOC_INT48_IRQn = 48, /*!< Device Interrupt */
+ SOC_INT49_IRQn = 49, /*!< Device Interrupt */
+ SOC_INT50_IRQn = 50, /*!< Device Interrupt */
+ SOC_INT_MAX,
+} IRQn_Type;
+
+/* =========================================================================================================================== */
+/* ================ Exception Code Definition ================ */
+/* =========================================================================================================================== */
+
+typedef enum EXCn {
+/* ======================================= Nuclei N/NX Specific Exception Code ======================================== */
+ InsUnalign_EXCn = 0, /*!< Instruction address misaligned */
+ InsAccFault_EXCn = 1, /*!< Instruction access fault */
+ IlleIns_EXCn = 2, /*!< Illegal instruction */
+ Break_EXCn = 3, /*!< Beakpoint */
+ LdAddrUnalign_EXCn = 4, /*!< Load address misaligned */
+ LdFault_EXCn = 5, /*!< Load access fault */
+ StAddrUnalign_EXCn = 6, /*!< Store or AMO address misaligned */
+ StAccessFault_EXCn = 7, /*!< Store or AMO access fault */
+ UmodeEcall_EXCn = 8, /*!< Environment call from User mode */
+ MmodeEcall_EXCn = 11, /*!< Environment call from Machine mode */
+ NMI_EXCn = 0xfff, /*!< NMI interrupt */
+} EXCn_Type;
+
+/* =========================================================================================================================== */
+/* ================ Processor and Core Peripheral Section ================ */
+/* =========================================================================================================================== */
+
+/* ToDo: set the defines according your Device */
+/* ToDo: define the correct core revision */
+#if __riscv_xlen == 32
+
+#ifndef __NUCLEI_CORE_REV
+#define __NUCLEI_N_REV 0x0104 /*!< Core Revision r1p4 */
+#else
+#define __NUCLEI_N_REV __NUCLEI_CORE_REV
+#endif
+
+#elif __riscv_xlen == 64
+
+#ifndef __NUCLEI_CORE_REV
+#define __NUCLEI_NX_REV 0x0100 /*!< Core Revision r1p0 */
+#else
+#define __NUCLEI_NX_REV __NUCLEI_CORE_REV
+#endif
+
+#endif /* __riscv_xlen == 64 */
+
+/* ToDo: define the correct core features for the hbird */
+#define __ECLIC_PRESENT 1 /*!< Set to 1 if ECLIC is present */
+#define __ECLIC_BASEADDR 0x0C000000UL /*!< Set to ECLIC baseaddr of your device */
+
+//#define __ECLIC_INTCTLBITS 3 /*!< Set to 1 - 8, the number of hardware bits are actually implemented in the clicintctl registers. */
+#define __ECLIC_INTNUM 51 /*!< Set to 1 - 1024, total interrupt number of ECLIC Unit */
+#define __SYSTIMER_PRESENT 1 /*!< Set to 1 if System Timer is present */
+#define __SYSTIMER_BASEADDR 0x02000000UL /*!< Set to SysTimer baseaddr of your device */
+
+/*!< Set to 0, 1, or 2, 0 not present, 1 single floating point unit present, 2 double floating point unit present */
+#if !defined(__riscv_flen)
+#define __FPU_PRESENT 0
+#elif __riscv_flen == 32
+#define __FPU_PRESENT 1
+#else
+#define __FPU_PRESENT 2
+#endif
+
+#define __DSP_PRESENT 1 /*!< Set to 1 if DSP is present */
+#define __PMP_PRESENT 1 /*!< Set to 1 if PMP is present */
+#define __PMP_ENTRY_NUM 16 /*!< Set to 8 or 16, the number of PMP entries */
+#define __ICACHE_PRESENT 0 /*!< Set to 1 if I-Cache is present */
+#define __DCACHE_PRESENT 0 /*!< Set to 1 if D-Cache is present */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+#define __Vendor_EXCEPTION 0 /*!< Set to 1 if vendor exception hander is present */
+
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+
+#include /*!< Nuclei N/NX class processor and core peripherals */
+/* ToDo: include your system_hbird.h file
+ replace 'Device' with your device name */
+#include "system_hbird.h" /*!< hbird System */
+
+
+/* ======================================== Start of section using anonymous unions ======================================== */
+#if defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#else
+ #warning Not supported compiler type
+#endif
+
+#define RTC_FREQ 32768
+// The TIMER frequency is just the RTC frequency
+#define SOC_TIMER_FREQ RTC_FREQ
+/* =========================================================================================================================== */
+/* ================ Device Specific Peripheral Section ================ */
+/* =========================================================================================================================== */
+
+
+/** @addtogroup Device_Peripheral_peripherals
+ * @{
+ */
+
+/****************************************************************************
+ * Platform definitions
+ *****************************************************************************/
+// IOF Mappings
+#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
+#define SPI11_NUM_SS (4)
+#define IOF_SPI1_SS0 (2u)
+#define IOF_SPI1_SS1 (8u)
+#define IOF_SPI1_SS2 (9u)
+#define IOF_SPI1_SS3 (10u)
+#define IOF_SPI1_MOSI (3u)
+#define IOF_SPI1_MISO (4u)
+#define IOF_SPI1_SCK (5u)
+#define IOF_SPI1_DQ0 (3u)
+#define IOF_SPI1_DQ1 (4u)
+#define IOF_SPI1_DQ2 (6u)
+#define IOF_SPI1_DQ3 (7u)
+
+#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
+#define SPI2_NUM_SS (1)
+#define IOF_SPI2_SS0 (26u)
+#define IOF_SPI2_MOSI (27u)
+#define IOF_SPI2_MISO (28u)
+#define IOF_SPI2_SCK (29u)
+#define IOF_SPI2_DQ0 (27u)
+#define IOF_SPI2_DQ1 (28u)
+#define IOF_SPI2_DQ2 (30u)
+#define IOF_SPI2_DQ3 (31u)
+
+#define IOF0_UART0_MASK _AC(0x00030000, UL)
+#define IOF_UART0_RX (16u)
+#define IOF_UART0_TX (17u)
+
+#define IOF0_UART1_MASK _AC(0x03000000, UL)
+#define IOF_UART1_RX (24u)
+#define IOF_UART1_TX (25u)
+
+#define IOF0_I2C_MASK _AC(0x00003000, UL)
+#define IOF_I2C_SDA (12u)
+#define IOF_I2C_SCL (13u)
+
+#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
+#define IOF1_PWM1_MASK _AC(0x00780000, UL)
+#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
+
+// Interrupt Numbers
+#define SOC_ECLIC_NUM_INTERRUPTS 32
+#define SOC_ECLIC_INT_GPIO_BASE 19
+
+// Interrupt Handler Definitions
+#define SOC_MTIMER_HANDLER eclic_mtip_handler
+#define SOC_SOFTINT_HANDLER eclic_msip_handler
+
+#define GPIO_BIT_ALL_ZERO (0x0)
+#define GPIO_BIT_ALL_ONE (0xFFFFFFFF)
+
+/**
+ * @brief GPIO
+ */
+typedef struct { /*!< GPIO Structure */
+ __IOM uint32_t INPUT_VAL;
+ __IOM uint32_t INPUT_EN;
+ __IOM uint32_t OUTPUT_EN;
+ __IOM uint32_t OUTPUT_VAL;
+ __IOM uint32_t PULLUP_EN;
+ __IOM uint32_t DRIVE;
+ __IOM uint32_t RISE_IE;
+ __IOM uint32_t RISE_IP;
+ __IOM uint32_t FALL_IE;
+ __IOM uint32_t FALL_IP;
+ __IOM uint32_t HIGH_IE;
+ __IOM uint32_t HIGH_IP;
+ __IOM uint32_t LOW_IE;
+ __IOM uint32_t LOW_IP;
+ __IOM uint32_t IOF_EN;
+ __IOM uint32_t IOF_SEL;
+ __IOM uint32_t OUTPUT_XOR;
+} GPIO_TypeDef;
+
+/**
+ * @brief UART
+ */
+typedef struct {
+ __IOM uint32_t TXFIFO;
+ __IOM uint32_t RXFIFO;
+ __IOM uint32_t TXCTRL;
+ __IOM uint32_t RXCTRL;
+ __IOM uint32_t IE;
+ __IOM uint32_t IP;
+ __IOM uint32_t DIV;
+} UART_TypeDef;
+
+/**
+ * @brief PWM
+ */
+typedef struct {
+ __IOM uint32_t CFG;
+ uint32_t RESERVED0;
+ __IOM uint32_t COUNT;
+ uint32_t RESERVED1;
+ __IOM uint32_t S;
+ uint32_t RESERVED2[3];
+ __IOM uint32_t CMP0;
+ __IOM uint32_t CMP1;
+ __IOM uint32_t CMP2;
+ __IOM uint32_t CMP3;
+} PWM_TypeDef;
+
+/**
+ * @brief QSPI
+ */
+typedef struct {
+ __IOM uint32_t SCKDIV;
+ __IOM uint32_t SCKMODE;
+ __IOM uint32_t RESERVED0[2];
+ __IOM uint32_t CSID;
+ __IOM uint32_t CSDEF;
+ __IOM uint32_t CSMODE;
+ __IOM uint32_t RESERVED1[3];
+ __IOM uint32_t DELAY0;
+ __IOM uint32_t DELAY1;
+ __IOM uint32_t RESERVED2[4];
+ __IOM uint32_t FMT;
+ __IOM uint32_t RESERVED3;
+ __IOM uint32_t TXDATA;
+ __IOM uint32_t RXDATA;
+ __IOM uint32_t TXMARK;
+ __IOM uint32_t RXMARK;
+ __IOM uint32_t RESERVED4[2];
+ __IOM uint32_t FCTRL;
+ __IOM uint32_t FFMT;
+ __IOM uint32_t RESERVED5[2];
+ __IOM uint32_t IE;
+ __IOM uint32_t IP;
+} QSPI_TypeDef;
+
+/**
+ * @brief I2C
+ */
+typedef struct {
+ __IOM uint8_t PRERlo;
+ __IOM uint8_t PRERhi;
+ __IOM uint8_t CTR;
+ __IOM uint8_t TXRXR; /* TXR and RXR in same address */
+ __IOM uint8_t CSR; /* CR and SR in same address */
+} I2C_TypeDef;
+
+/*@}*/ /* end of group hbird_Peripherals */
+
+
+/* ========================================= End of section using anonymous unions ========================================= */
+#if defined (__GNUC__)
+ /* anonymous unions are enabled by default */
+#else
+ #warning Not supported compiler type
+#endif
+
+
+/* =========================================================================================================================== */
+/* ================ Device Specific Peripheral Address Map ================ */
+/* =========================================================================================================================== */
+
+
+/* ToDo: add here your device peripherals base addresses
+ following is an example for timer */
+/** @addtogroup Device_Peripheral_peripheralAddr
+ * @{
+ */
+/* Peripheral and SRAM base address */
+#define QSPI_FLASH_BASE (0x20000000UL) /*!< (FLASH ) Base Address */
+#define ONCHIP_ROM_BASE (0x00001000UL) /*!< (ROM ) Base Address */
+#define ONCHIP_ILM_BASE (0x80000000UL) /*!< (ILM ) Base Address */
+#define ONCHIP_DLM_BASE (0x90000000UL) /*!< (DLM ) Base Address */
+#define HBIRD_PERIPH_BASE (0x10000000UL) /*!< (Peripheral) Base Address */
+
+/* Peripheral memory map */
+/* Fast-IO Interfaced IP */
+#define GPIO_BASE (HBIRD_PERIPH_BASE + 0x12000) /*!< (GPIO) Base Address */
+/* PPI Interfaced IP */
+#define UART0_BASE (HBIRD_PERIPH_BASE + 0x13000) /*!< (UART0) Base Address */
+#define QSPI0_BASE (HBIRD_PERIPH_BASE + 0x14000) /*!< (QSPI0) Base Address */
+#define PWM0_BASE (HBIRD_PERIPH_BASE + 0x15000) /*!< (PWM0) Base Address */
+#define UART1_BASE (HBIRD_PERIPH_BASE + 0x23000) /*!< (UART1) Base Address */
+#define QSPI1_BASE (HBIRD_PERIPH_BASE + 0x24000) /*!< (QSPI1) Base Address */
+#define PWM1_BASE (HBIRD_PERIPH_BASE + 0x25000) /*!< (PWM1) Base Address */
+#define QSPI2_BASE (HBIRD_PERIPH_BASE + 0x34000) /*!< (QSPI2) Base Address */
+#define PWM2_BASE (HBIRD_PERIPH_BASE + 0x35000) /*!< (PWM2) Base Address */
+#define I2C_BASE (HBIRD_PERIPH_BASE + 0x42000) /*!< (I2C Master) Base Address */
+
+/** @} */ /* End of group Device_Peripheral_peripheralAddr */
+
+
+/* =========================================================================================================================== */
+/* ================ Peripheral declaration ================ */
+/* =========================================================================================================================== */
+
+
+/* ToDo: add here your device peripherals pointer definitions
+ following is an example for timer */
+/** @addtogroup Device_Peripheral_declaration
+ * @{
+ */
+#define GPIO ((GPIO_TypeDef *) GPIO_BASE)
+#define UART0 ((UART_TypeDef *) UART0_BASE)
+#define QSPI0 ((QSPI_TypeDef *) QSPI0_BASE)
+#define PWM0 ((PWM_TypeDef *) PWM0_BASE)
+#define UART1 ((UART_TypeDef *) UART1_BASE)
+#define QSPI1 ((QSPI_TypeDef *) QSPI1_BASE)
+#define PWM1 ((PWM_TypeDef *) PWM1_BASE)
+#define QSPI2 ((QSPI_TypeDef *) QSPI2_BASE)
+#define PWM2 ((PWM_TypeDef *) PWM2_BASE)
+#define I2C ((I2C_TypeDef *) I2C_BASE)
+
+// Helper functions
+#define _REG8(p, i) (*(volatile uint8_t *) ((p) + (i)))
+#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
+#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
+
+#define GPIO_REG(offset) _REG32(GPIO_BASE, offset)
+#define PWM0_REG(offset) _REG32(PWM0_BASE, offset)
+#define PWM1_REG(offset) _REG32(PWM1_BASE, offset)
+#define PWM2_REG(offset) _REG32(PWM2_BASE, offset)
+#define SPI0_REG(offset) _REG32(QSPI0_BASE, offset)
+#define SPI1_REG(offset) _REG32(QSPI1_BASE, offset)
+#define SPI2_REG(offset) _REG32(QSPI2_BASE, offset)
+#define UART0_REG(offset) _REG32(UART0_BASE, offset)
+#define UART1_REG(offset) _REG32(UART1_BASE, offset)
+#define I2C_REG(offset) _REG8(I2C_BASE, offset)
+
+// Misc
+
+#define NUM_GPIO 32
+
+uint32_t get_cpu_freq();
+void delay_1ms(uint32_t count);
+
+/** @} */ /* End of group hbird */
+
+/** @} */ /* End of group Nuclei */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HBIRD_H__ */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_gpio.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_gpio.h
new file mode 100644
index 00000000..f6c88096
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_gpio.h
@@ -0,0 +1,56 @@
+// See LICENSE for license details.
+#ifndef _HBIRD_GPIO_H
+#define _HBIRD_GPIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define GPIO_INPUT_VAL (0x00)
+#define GPIO_INPUT_EN (0x04)
+#define GPIO_OUTPUT_EN (0x08)
+#define GPIO_OUTPUT_VAL (0x0C)
+#define GPIO_PULLUP_EN (0x10)
+#define GPIO_DRIVE (0x14)
+#define GPIO_RISE_IE (0x18)
+#define GPIO_RISE_IP (0x1C)
+#define GPIO_FALL_IE (0x20)
+#define GPIO_FALL_IP (0x24)
+#define GPIO_HIGH_IE (0x28)
+#define GPIO_HIGH_IP (0x2C)
+#define GPIO_LOW_IE (0x30)
+#define GPIO_LOW_IP (0x34)
+#define GPIO_IOF_EN (0x38)
+#define GPIO_IOF_SEL (0x3C)
+#define GPIO_OUTPUT_XOR (0x40)
+
+typedef enum iof_func {
+ IOF_SEL_GPIO = 0,
+ IOF_SEL_0 = 1,
+ IOF_SEL_1 = 2
+} IOF_FUNC;
+
+typedef enum gpio_int_type {
+ GPIO_INT_RISE = 0,
+ GPIO_INT_FALL = 1,
+ GPIO_INT_HIGH = 2,
+ GPIO_INT_LOW = 3
+} GPIO_INT_TYPE;
+
+int32_t gpio_iof_config(GPIO_TypeDef *gpio, uint32_t mask, IOF_FUNC func);
+int32_t gpio_enable_output(GPIO_TypeDef *gpio, uint32_t mask);
+int32_t gpio_enable_input(GPIO_TypeDef *gpio, uint32_t mask);
+int32_t gpio_write(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
+int32_t gpio_toggle(GPIO_TypeDef *gpio, uint32_t mask);
+int32_t gpio_read(GPIO_TypeDef *gpio, uint32_t mask);
+int32_t gpio_set_pue(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
+int32_t gpio_set_ds(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
+int32_t gpio_set_outxor(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value);
+int32_t gpio_enable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
+int32_t gpio_disable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
+int32_t gpio_clear_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HBIRD_GPIO_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_i2c.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_i2c.h
new file mode 100644
index 00000000..2e905d56
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_i2c.h
@@ -0,0 +1,56 @@
+//See LICENSE for license details
+
+#ifndef _HBIRD_I2C_H
+#define _HBIRD_I2C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* register offsets */
+//all registers are 8 bits width
+#define I2C_REG_PRERlo 0x00
+#define I2C_REG_PRERhi 0x01
+#define I2C_REG_CTR 0X02
+#define I2C_REG_TXR 0x03
+#define I2C_REG_RXR 0X03
+#define I2C_REG_CR 0X04
+#define I2C_REG_SR 0X04
+
+#define I2C_CTR_EN (1 << 7)
+#define I2C_CTR_IE (1 << 6)
+
+#define I2C_CR_STA (1 << 7)
+#define I2C_CR_STO (1 << 6)
+#define I2C_CR_RD (1 << 5)
+#define I2C_CR_WR (1 << 4)
+#define I2C_CR_ACK (1 << 3)
+#define I2C_CR_IACK (1 << 0)
+
+#define I2C_TXR_WRRD (1 << 0)//0:write to slave; 1:read from slave;
+
+#define I2C_SR_RXACK (1 << 7)//0:received; 1:no ack resceived
+#define I2C_SR_BUSY (1 << 6)//0:after 'STOP' detected; 1:after 'START' detected
+#define I2C_SR_AL (1 << 5)
+#define I2C_SR_TIP (1 << 1)//0:transfer complete; 1:transfering
+#define I2C_SR_IF (1 << 0)
+#if 0
+/*fileds*/
+
+#define I2C_CTR_ENABLE 1
+#define I2C_CTR_DISABLE 0
+
+#define I2C_CTR_INTEN 1
+#define I2C_CTR_INTDIS 0
+
+#define I2C_TXR_RFS 1 //read from slave
+#define I2C_TXR_WTS 0 //write to slave
+
+#define I2C
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HBIRD_I2C_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_pwm.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_pwm.h
new file mode 100644
index 00000000..c557f4c1
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_pwm.h
@@ -0,0 +1,44 @@
+// See LICENSE for license details.
+
+#ifndef _HBIRD_PWM_H
+#define _HBIRD_PWM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Register offsets */
+
+#define PWM_CFG 0x00
+#define PWM_COUNT 0x08
+#define PWM_S 0x10
+#define PWM_CMP0 0x20
+#define PWM_CMP1 0x24
+#define PWM_CMP2 0x28
+#define PWM_CMP3 0x2C
+
+/* Constants */
+
+#define PWM_CFG_SCALE 0x0000000F
+#define PWM_CFG_STICKY 0x00000100
+#define PWM_CFG_ZEROCMP 0x00000200
+#define PWM_CFG_DEGLITCH 0x00000400
+#define PWM_CFG_ENALWAYS 0x00001000
+#define PWM_CFG_ONESHOT 0x00002000
+#define PWM_CFG_CMP0CENTER 0x00010000
+#define PWM_CFG_CMP1CENTER 0x00020000
+#define PWM_CFG_CMP2CENTER 0x00040000
+#define PWM_CFG_CMP3CENTER 0x00080000
+#define PWM_CFG_CMP0GANG 0x01000000
+#define PWM_CFG_CMP1GANG 0x02000000
+#define PWM_CFG_CMP2GANG 0x04000000
+#define PWM_CFG_CMP3GANG 0x08000000
+#define PWM_CFG_CMP0IP 0x10000000
+#define PWM_CFG_CMP1IP 0x20000000
+#define PWM_CFG_CMP2IP 0x40000000
+#define PWM_CFG_CMP3IP 0x80000000
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HBIRD_PWM_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_spi.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_spi.h
new file mode 100644
index 00000000..6ca6e66f
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_spi.h
@@ -0,0 +1,86 @@
+// See LICENSE for license details.
+
+#ifndef _HBIRD_SPI_H
+#define _HBIRD_SPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Register offsets */
+
+#define SPI_REG_SCKDIV 0x00
+#define SPI_REG_SCKMODE 0x04
+#define SPI_REG_CSID 0x10
+#define SPI_REG_CSDEF 0x14
+#define SPI_REG_CSMODE 0x18
+
+#define SPI_REG_DCSSCK 0x28
+#define SPI_REG_DSCKCS 0x2a
+#define SPI_REG_DINTERCS 0x2c
+#define SPI_REG_DINTERXFR 0x2e
+
+#define SPI_REG_FMT 0x40
+#define SPI_REG_TXFIFO 0x48
+#define SPI_REG_RXFIFO 0x4c
+#define SPI_REG_TXCTRL 0x50
+#define SPI_REG_RXCTRL 0x54
+
+#define SPI_REG_FCTRL 0x60
+#define SPI_REG_FFMT 0x64
+
+#define SPI_REG_IE 0x70
+#define SPI_REG_IP 0x74
+
+/* Fields */
+
+#define SPI_SCK_POL 0x1
+#define SPI_SCK_PHA 0x2
+
+#define SPI_FMT_PROTO(x) ((x) & 0x3)
+#define SPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
+#define SPI_FMT_DIR(x) (((x) & 0x1) << 3)
+#define SPI_FMT_LEN(x) (((x) & 0xf) << 16)
+
+/* TXCTRL register */
+#define SPI_TXWM(x) ((x) & 0xffff)
+/* RXCTRL register */
+#define SPI_RXWM(x) ((x) & 0xffff)
+
+#define SPI_IP_TXWM 0x1
+#define SPI_IP_RXWM 0x2
+
+#define SPI_FCTRL_EN 0x1
+
+#define SPI_INSN_CMD_EN 0x1
+#define SPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
+#define SPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
+#define SPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
+#define SPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
+#define SPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
+#define SPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
+#define SPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
+
+#define SPI_TXFIFO_FULL (1 << 31)
+#define SPI_RXFIFO_EMPTY (1 << 31)
+
+/* Values */
+
+#define SPI_CSMODE_AUTO 0
+#define SPI_CSMODE_HOLD 2
+#define SPI_CSMODE_OFF 3
+
+#define SPI_DIR_RX 0
+#define SPI_DIR_TX 1
+
+#define SPI_PROTO_S 0
+#define SPI_PROTO_D 1
+#define SPI_PROTO_Q 2
+
+#define SPI_ENDIAN_MSB 0
+#define SPI_ENDIAN_LSB 1
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HBIRD_SPI_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_uart.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_uart.h
new file mode 100644
index 00000000..4af314cb
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/hbird_uart.h
@@ -0,0 +1,75 @@
+// See LICENSE for license details.
+
+#ifndef _HBIRD_UART_H
+#define _HBIRD_UART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Register offsets */
+#define UART_REG_TXFIFO 0x00
+#define UART_REG_RXFIFO 0x04
+#define UART_REG_TXCTRL 0x08
+#define UART_REG_RXCTRL 0x0c
+#define UART_REG_IE 0x10
+#define UART_REG_IP 0x14
+#define UART_REG_DIV 0x18
+
+/* TXCTRL register */
+#define UART_TXEN 0x1
+#define UART_TXWM(x) (((x) & 0xffff) << 16)
+
+/* RXCTRL register */
+#define UART_RXEN 0x1
+#define UART_RXWM(x) (((x) & 0xffff) << 16)
+
+/* IP register */
+#define UART_IP_TXWM 0x1
+#define UART_IP_RXWM 0x2
+
+#define UART_TXFIFO_FULL (1<<31)
+#define UART_RXFIFO_EMPTY (1<<31)
+
+#define UART_TXCTRL_TXCNT_OFS (16)
+#define UART_TXCTRL_TXCNT_MASK (0x7 << UART_TXCTRL_TXCNT_OFS)
+#define UART_TXCTRL_TXEN_OFS (0)
+#define UART_TXCTRL_TXEN_MASK (0x1 << UART_TXCTRL_TXEN_OFS)
+#define UART_TXCTRL_NSTOP_OFS (1)
+#define UART_TXCTRL_NSTOP_MASK (0x1 << UART_TXCTRL_TXEN_OFS)
+
+#define UART_RXCTRL_RXCNT_OFS (16)
+#define UART_RXCTRL_RXCNT_MASK (0x7 << UART_RXCTRL_RXCNT_OFS)
+#define UART_RXCTRL_RXEN_OFS (0)
+#define UART_RXCTRL_RXEN_MASK (0x1 << UART_RXCTRL_RXEN_OFS)
+
+#define UART_IE_TXIE_OFS (0)
+#define UART_IE_TXIE_MASK (0x1 << UART_IE_TXIE_OFS)
+#define UART_IE_RXIE_OFS (1)
+#define UART_IE_RXIE_MASK (0x1 << UART_IE_RXIE_OFS)
+
+#define UART_IP_TXIP_OFS (0)
+#define UART_IP_TXIP_MASK (0x1 << UART_IP_TXIP_OFS)
+#define UART_IP_RXIP_OFS (1)
+#define UART_IP_RXIP_MASK (0x1 << UART_IP_RXIP_OFS)
+
+typedef enum uart_stop_bit {
+ UART_STOP_BIT_1 = 0,
+ UART_STOP_BIT_2 = 1
+} UART_STOP_BIT;
+
+int32_t uart_init(UART_TypeDef *uart, uint32_t baudrate);
+int32_t uart_config_stopbit(UART_TypeDef *uart, UART_STOP_BIT stopbit);
+int32_t uart_write(UART_TypeDef *uart, uint8_t val);
+uint8_t uart_read(UART_TypeDef *uart);
+int32_t uart_set_tx_watermark(UART_TypeDef *uart, uint32_t watermark);
+int32_t uart_enable_txint(UART_TypeDef *uart);
+int32_t uart_disable_txint(UART_TypeDef *uart);
+int32_t uart_set_rx_watermark(UART_TypeDef *uart, uint32_t watermark);
+int32_t uart_enable_rxint(UART_TypeDef *uart);
+int32_t uart_disable_rxint(UART_TypeDef *uart);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HBIRD_UART_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/nuclei_sdk_soc.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/nuclei_sdk_soc.h
new file mode 100644
index 00000000..3098dde1
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/nuclei_sdk_soc.h
@@ -0,0 +1,19 @@
+// See LICENSE for license details.
+#ifndef _NUCLEI_SDK_SOC_H
+#define _NUCLEI_SDK_SOC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "hbird.h"
+#include "hbird_uart.h"
+#include "hbird_gpio.h"
+#include "hbird_i2c.h"
+#include "hbird_spi.h"
+#include "hbird_pwm.h"
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/system_hbird.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/system_hbird.h
new file mode 100644
index 00000000..0c81afba
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Include/system_hbird.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/*******************************************************************************
+ * @file system_hbird.h
+ * @brief NMSIS Nuclei N/NX Device Peripheral Access Layer Header File for
+ * Device
+ * @version V1.00
+ * @date 17. Dec 2019
+ ******************************************************************************/
+
+#ifndef __SYSTEM_HBIRD_H__ /* ToDo: replace '' with your device name */
+#define __SYSTEM_HBIRD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
+
+/**
+ * \brief Setup the microcontroller system.
+ * \details
+ * Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+/**
+ * \brief Update SystemCoreClock variable.
+ * \details
+ * Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+
+/**
+ * \brief Register an exception handler for exception code EXCn
+ */
+extern void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler);
+
+/**
+ * \brief Get current exception handler for exception code EXCn
+ */
+extern unsigned long Exception_Get_EXC(uint32_t EXCn);
+
+/**
+ * \brief Initialize eclic config
+ */
+extern void ECLIC_Init(void);
+
+/**
+ * \brief Initialize a specific IRQ and register the handler
+ * \details
+ * This function set vector mode, trigger mode and polarity, interrupt level and priority,
+ * assign handler for specific IRQn.
+ */
+extern int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void *handler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_HBIRD_H__ */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_gpio.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_gpio.c
new file mode 100644
index 00000000..17ba49ce
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_gpio.c
@@ -0,0 +1,177 @@
+#include "hbird.h"
+#include "hbird_gpio.h"
+
+int32_t gpio_iof_config(GPIO_TypeDef *gpio, uint32_t mask, IOF_FUNC func)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ switch (func) {
+ case IOF_SEL_GPIO:
+ gpio->IOF_EN &= ~mask;
+ break;
+ case IOF_SEL_0:
+ gpio->IOF_SEL &= ~mask;
+ gpio->IOF_EN |= mask;
+ break;
+ case IOF_SEL_1:
+ gpio->IOF_SEL |= mask;
+ gpio->IOF_EN |= mask;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int32_t gpio_enable_output(GPIO_TypeDef *gpio, uint32_t mask)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->OUTPUT_EN |= mask;
+ gpio->INPUT_EN &= ~mask;
+ return 0;
+}
+
+int32_t gpio_enable_input(GPIO_TypeDef *gpio, uint32_t mask)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->INPUT_EN |= mask;
+ gpio->OUTPUT_EN &= ~mask;
+ return 0;
+}
+
+int32_t gpio_write(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ // If value != 0, mean set gpio pin high, otherwise set pin low
+ if (value) {
+ gpio->OUTPUT_VAL |= (mask);
+ } else {
+ gpio->OUTPUT_VAL &= ~(mask);
+ }
+ return 0;
+}
+
+int32_t gpio_toggle(GPIO_TypeDef *gpio, uint32_t mask)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->OUTPUT_VAL = (mask ^ gpio->OUTPUT_VAL);
+ return 0;
+}
+
+
+int32_t gpio_read(GPIO_TypeDef *gpio, uint32_t mask)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ return gpio->INPUT_VAL & mask;
+}
+
+int32_t gpio_set_pue(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->PULLUP_EN |= (mask & value);
+ return 0;
+}
+
+int32_t gpio_set_ds(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->DRIVE |= (mask & value);
+ return 0;
+}
+
+int32_t gpio_set_outxor(GPIO_TypeDef *gpio, uint32_t mask, uint32_t value)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ gpio->OUTPUT_XOR |= (mask & value);
+ return 0;
+}
+
+int32_t gpio_enable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ switch (type) {
+ case GPIO_INT_RISE:
+ gpio->RISE_IE |= mask;
+ break;
+ case GPIO_INT_FALL:
+ gpio->FALL_IE |= mask;
+ break;
+ case GPIO_INT_HIGH:
+ gpio->HIGH_IE |= mask;
+ break;
+ case GPIO_INT_LOW:
+ gpio->LOW_IE |= mask;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int32_t gpio_disable_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ switch (type) {
+ case GPIO_INT_RISE:
+ gpio->RISE_IE &= ~mask;
+ break;
+ case GPIO_INT_FALL:
+ gpio->FALL_IE &= ~mask;
+ break;
+ case GPIO_INT_HIGH:
+ gpio->HIGH_IE &= ~mask;
+ break;
+ case GPIO_INT_LOW:
+ gpio->LOW_IE &= ~mask;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int32_t gpio_clear_interrupt(GPIO_TypeDef *gpio, uint32_t mask, GPIO_INT_TYPE type)
+{
+ if (__RARELY(gpio == NULL)) {
+ return -1;
+ }
+ switch (type) {
+ case GPIO_INT_RISE:
+ gpio->RISE_IP |= mask;
+ break;
+ case GPIO_INT_FALL:
+ gpio->FALL_IP |= mask;
+ break;
+ case GPIO_INT_HIGH:
+ gpio->HIGH_IP |= mask;
+ break;
+ case GPIO_INT_LOW:
+ gpio->LOW_IP |= mask;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_uart.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_uart.c
new file mode 100644
index 00000000..d2ba6840
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Drivers/hbird_uart.c
@@ -0,0 +1,105 @@
+#include "hbird.h"
+#include "hbird_uart.h"
+
+int32_t uart_init(UART_TypeDef *uart, uint32_t baudrate)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uart->DIV = SystemCoreClock / baudrate - 1;
+ uart->TXCTRL |= UART_TXEN;
+ uart->RXCTRL |= UART_RXEN;
+ return 0;
+}
+
+int32_t uart_config_stopbit(UART_TypeDef *uart, UART_STOP_BIT stopbit)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uint32_t stopval = stopbit;
+ stopval = (stopbit << UART_TXCTRL_NSTOP_OFS) & UART_TXCTRL_TXCNT_MASK;
+ uart->TXCTRL &= stopval | (~UART_TXCTRL_TXCNT_MASK);
+ return 0;
+}
+
+int32_t uart_write(UART_TypeDef *uart, uint8_t val)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+#ifndef SIMULATION_XLSPIKE
+ while (uart->TXFIFO & UART_TXFIFO_FULL);
+#endif
+ uart->TXFIFO = val;
+ return 0;
+}
+
+uint8_t uart_read(UART_TypeDef *uart)
+{
+ uint32_t reg;
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ do {
+ reg = uart->RXFIFO;
+ }
+ while (reg & UART_RXFIFO_EMPTY);
+ return (uint8_t)(reg & 0xFF);
+}
+
+int32_t uart_set_tx_watermark(UART_TypeDef *uart, uint32_t watermark)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ watermark = (watermark << UART_TXCTRL_TXCNT_OFS) & UART_TXCTRL_TXCNT_MASK;
+ uart->TXCTRL &= watermark | (~UART_TXCTRL_TXCNT_MASK);
+ return 0;
+}
+
+int32_t uart_enable_txint(UART_TypeDef *uart)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uart->IE |= UART_IE_TXIE_MASK;
+ return 0;
+}
+
+int32_t uart_disable_txint(UART_TypeDef *uart)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uart->IE &= ~UART_IE_TXIE_MASK;
+ return 0;
+}
+
+int32_t uart_set_rx_watermark(UART_TypeDef *uart, uint32_t watermark)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ watermark = (watermark << UART_RXCTRL_RXCNT_OFS) & UART_RXCTRL_RXCNT_MASK;
+ uart->RXCTRL &= watermark | (~UART_RXCTRL_RXCNT_MASK);
+ return 0;
+}
+
+int32_t uart_enable_rxint(UART_TypeDef *uart)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uart->IE |= UART_IE_RXIE_MASK;
+ return 0;
+}
+
+int32_t uart_disable_rxint(UART_TypeDef *uart)
+{
+ if (__RARELY(uart == NULL)) {
+ return -1;
+ }
+ uart->IE &= ~UART_IE_RXIE_MASK;
+ return 0;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/intexc_hbird.S b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/intexc_hbird.S
new file mode 100644
index 00000000..701795f3
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/intexc_hbird.S
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * \file intexc_hbird.S
+ * \brief NMSIS Interrupt and Exception Handling Template File
+ * for Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
+ * \version V1.00
+ * \date 17 Dec 2019
+ *
+ ******************************************************************************/
+
+#include "riscv_encoding.h"
+
+/**
+ * \brief Global interrupt disabled
+ * \details
+ * This function disable global interrupt.
+ * \remarks
+ * - All the interrupt requests will be ignored by CPU.
+ */
+.macro DISABLE_MIE
+ csrc CSR_MSTATUS, MSTATUS_MIE
+.endm
+
+/**
+ * \brief Macro for context save
+ * \details
+ * This macro save ABI defined caller saved registers in the stack.
+ * \remarks
+ * - This Macro could use to save context when you enter to interrupt
+ * or exception
+*/
+/* Save caller registers */
+.macro SAVE_CONTEXT
+ /* Allocate stack space for context saving */
+#ifndef __riscv_32e
+ addi sp, sp, -20*REGBYTES
+#else
+ addi sp, sp, -14*REGBYTES
+#endif /* __riscv_32e */
+
+ STORE x1, 0*REGBYTES(sp)
+ STORE x4, 1*REGBYTES(sp)
+ STORE x5, 2*REGBYTES(sp)
+ STORE x6, 3*REGBYTES(sp)
+ STORE x7, 4*REGBYTES(sp)
+ STORE x10, 5*REGBYTES(sp)
+ STORE x11, 6*REGBYTES(sp)
+ STORE x12, 7*REGBYTES(sp)
+ STORE x13, 8*REGBYTES(sp)
+ STORE x14, 9*REGBYTES(sp)
+ STORE x15, 10*REGBYTES(sp)
+#ifndef __riscv_32e
+ STORE x16, 14*REGBYTES(sp)
+ STORE x17, 15*REGBYTES(sp)
+ STORE x28, 16*REGBYTES(sp)
+ STORE x29, 17*REGBYTES(sp)
+ STORE x30, 18*REGBYTES(sp)
+ STORE x31, 19*REGBYTES(sp)
+#endif /* __riscv_32e */
+.endm
+
+/**
+ * \brief Macro for restore caller registers
+ * \details
+ * This macro restore ABI defined caller saved registers from stack.
+ * \remarks
+ * - You could use this macro to restore context before you want return
+ * from interrupt or exeception
+ */
+/* Restore caller registers */
+.macro RESTORE_CONTEXT
+ LOAD x1, 0*REGBYTES(sp)
+ LOAD x4, 1*REGBYTES(sp)
+ LOAD x5, 2*REGBYTES(sp)
+ LOAD x6, 3*REGBYTES(sp)
+ LOAD x7, 4*REGBYTES(sp)
+ LOAD x10, 5*REGBYTES(sp)
+ LOAD x11, 6*REGBYTES(sp)
+ LOAD x12, 7*REGBYTES(sp)
+ LOAD x13, 8*REGBYTES(sp)
+ LOAD x14, 9*REGBYTES(sp)
+ LOAD x15, 10*REGBYTES(sp)
+#ifndef __riscv_32e
+ LOAD x16, 14*REGBYTES(sp)
+ LOAD x17, 15*REGBYTES(sp)
+ LOAD x28, 16*REGBYTES(sp)
+ LOAD x29, 17*REGBYTES(sp)
+ LOAD x30, 18*REGBYTES(sp)
+ LOAD x31, 19*REGBYTES(sp)
+
+ /* De-allocate the stack space */
+ addi sp, sp, 20*REGBYTES
+#else
+ /* De-allocate the stack space */
+ addi sp, sp, 14*REGBYTES
+#endif /* __riscv_32e */
+
+.endm
+
+/**
+ * \brief Macro for save necessary CSRs to stack
+ * \details
+ * This macro store MCAUSE, MEPC, MSUBM to stack.
+ */
+.macro SAVE_CSR_CONTEXT
+ /* Store CSR mcause to stack using pushmcause */
+ csrrwi x0, CSR_PUSHMCAUSE, 11
+ /* Store CSR mepc to stack using pushmepc */
+ csrrwi x0, CSR_PUSHMEPC, 12
+ /* Store CSR msub to stack using pushmsub */
+ csrrwi x0, CSR_PUSHMSUBM, 13
+.endm
+
+/**
+ * \brief Macro for restore necessary CSRs from stack
+ * \details
+ * This macro restore MSUBM, MEPC, MCAUSE from stack.
+ */
+.macro RESTORE_CSR_CONTEXT
+ LOAD x5, 13*REGBYTES(sp)
+ csrw CSR_MSUBM, x5
+ LOAD x5, 12*REGBYTES(sp)
+ csrw CSR_MEPC, x5
+ LOAD x5, 11*REGBYTES(sp)
+ csrw CSR_MCAUSE, x5
+.endm
+
+/**
+ * \brief Exception/NMI Entry
+ * \details
+ * This function provide common entry functions for exception/nmi.
+ * \remarks
+ * This function provide a default exception/nmi entry.
+ * ABI defined caller save register and some CSR registers
+ * to be saved before enter interrupt handler and be restored before return.
+ */
+.section .text.trap
+/* In CLIC mode, the exeception entry must be 64bytes aligned */
+.align 6
+.global exc_entry
+.weak exc_entry
+exc_entry:
+ /* Save the caller saving registers (context) */
+ SAVE_CONTEXT
+ /* Save the necessary CSR registers */
+ SAVE_CSR_CONTEXT
+
+ /*
+ * Set the exception handler function arguments
+ * argument 1: mcause value
+ * argument 2: current stack point(SP) value
+ */
+ csrr a0, mcause
+ mv a1, sp
+ /*
+ * TODO: Call the exception handler function
+ * By default, the function template is provided in
+ * system_Device.c, you can adjust it as you want
+ */
+ call core_exception_handler
+ /* Restore the necessary CSR registers */
+ RESTORE_CSR_CONTEXT
+ /* Restore the caller saving registers (context) */
+ RESTORE_CONTEXT
+
+ /* Return to regular code */
+ mret
+
+/**
+ * \brief Non-Vector Interrupt Entry
+ * \details
+ * This function provide common entry functions for handling
+ * non-vector interrupts
+ * \remarks
+ * This function provide a default non-vector interrupt entry.
+ * ABI defined caller save register and some CSR registers need
+ * to be saved before enter interrupt handler and be restored before return.
+ */
+.section .text.irq
+/* In CLIC mode, the interrupt entry must be 4bytes aligned */
+.align 2
+.global irq_entry
+.weak irq_entry
+/* This label will be set to MTVT2 register */
+irq_entry:
+ /* Save the caller saving registers (context) */
+ SAVE_CONTEXT
+ /* Save the necessary CSR registers */
+ SAVE_CSR_CONTEXT
+
+ /* This special CSR read/write operation, which is actually
+ * claim the CLIC to find its pending highest ID, if the ID
+ * is not 0, then automatically enable the mstatus.MIE, and
+ * jump to its vector-entry-label, and update the link register
+ */
+ csrrw ra, CSR_JALMNXTI, ra
+
+ /* Critical section with interrupts disabled */
+ DISABLE_MIE
+
+ /* Restore the necessary CSR registers */
+ RESTORE_CSR_CONTEXT
+ /* Restore the caller saving registers (context) */
+ RESTORE_CONTEXT
+
+ /* Return to regular code */
+ mret
+
+/* Default Handler for Exceptions / Interrupts */
+.global default_intexc_handler
+.weak default_intexc_handler
+Undef_Handler:
+default_intexc_handler:
+1:
+ j 1b
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/startup_hbird.S b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/startup_hbird.S
new file mode 100644
index 00000000..ba09151a
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/GCC/startup_hbird.S
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * \file startup_hbird.S
+ * \brief NMSIS Nuclei N/NX Class Core based Core Device Startup File for
+ * Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
+ * \version V1.00
+ * \date 17. Dec 2019
+ *
+ ******************************************************************************/
+
+#include "riscv_encoding.h"
+
+.macro DECLARE_INT_HANDLER INT_HDL_NAME
+#if defined(__riscv_xlen) && (__riscv_xlen == 32)
+ .word \INT_HDL_NAME
+#else
+ .dword \INT_HDL_NAME
+#endif
+.endm
+
+/*
+ * === Different Download and Running Mode ===
+ * flashxip: Program will to be download into flash and run directly in Flash
+ * flash: Program will be download into flash, when running, program will be copied to ilm/ram and run in ilm/ram
+ * ilm: Program will be download into ilm/ram and run directly in ilm/ram, program lost when poweroff
+ */
+
+/*** Vector Table Code Section ***/
+ /*
+ * Put the interrupt vectors in this section according to the run mode:
+ * FlashXIP: .vtable
+ * ILM: .vtable
+ * Flash: .vtable_ilm
+ */
+#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE == DOWNLOAD_MODE_FLASH)
+ .section .vtable_ilm
+#else
+ .section .vtable
+#endif
+
+ .weak eclic_msip_handler
+ .weak eclic_mtip_handler
+ .weak eclic_irq19_handler
+ .weak eclic_irq20_handler
+ .weak eclic_irq21_handler
+ .weak eclic_irq22_handler
+ .weak eclic_irq23_handler
+ .weak eclic_irq24_handler
+ .weak eclic_irq25_handler
+ .weak eclic_irq26_handler
+ .weak eclic_irq27_handler
+ .weak eclic_irq28_handler
+ .weak eclic_irq29_handler
+ .weak eclic_irq30_handler
+ .weak eclic_irq31_handler
+ .weak eclic_irq32_handler
+ .weak eclic_irq33_handler
+ .weak eclic_irq34_handler
+ .weak eclic_irq35_handler
+ .weak eclic_irq36_handler
+ .weak eclic_irq37_handler
+ .weak eclic_irq38_handler
+ .weak eclic_irq39_handler
+ .weak eclic_irq40_handler
+ .weak eclic_irq41_handler
+ .weak eclic_irq42_handler
+ .weak eclic_irq43_handler
+ .weak eclic_irq44_handler
+ .weak eclic_irq45_handler
+ .weak eclic_irq46_handler
+ .weak eclic_irq47_handler
+ .weak eclic_irq48_handler
+ .weak eclic_irq49_handler
+ .weak eclic_irq50_handler
+
+ .globl vector_base
+vector_base:
+#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE != DOWNLOAD_MODE_FLASH)
+ j _start /* 0: Reserved, Jump to _start when reset for ILM/FlashXIP mode.*/
+ .align LOG_REGBYTES /* Need to align 4 byte for RV32, 8 Byte for RV64 */
+#else
+ DECLARE_INT_HANDLER default_intexc_handler /* 0: Reserved, default handler for Flash download mode */
+#endif
+ DECLARE_INT_HANDLER default_intexc_handler /* 1: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 2: Reserved */
+ DECLARE_INT_HANDLER eclic_msip_handler /* 3: Machine software interrupt */
+
+ DECLARE_INT_HANDLER default_intexc_handler /* 4: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 5: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 6: Reserved */
+ DECLARE_INT_HANDLER eclic_mtip_handler /* 7: Machine timer interrupt */
+
+ DECLARE_INT_HANDLER default_intexc_handler /* 8: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 9: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 10: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 11: Reserved */
+
+ DECLARE_INT_HANDLER default_intexc_handler /* 12: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 13: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 14: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 15: Reserved */
+
+ DECLARE_INT_HANDLER default_intexc_handler /* 16: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 17: Reserved */
+ DECLARE_INT_HANDLER default_intexc_handler /* 18: Reserved */
+ DECLARE_INT_HANDLER eclic_irq19_handler /* 19: Interrupt 19 */
+
+ DECLARE_INT_HANDLER eclic_irq20_handler /* 20: Interrupt 20 */
+ DECLARE_INT_HANDLER eclic_irq21_handler /* 21: Interrupt 21 */
+ DECLARE_INT_HANDLER eclic_irq22_handler /* 22: Interrupt 22 */
+ DECLARE_INT_HANDLER eclic_irq23_handler /* 23: Interrupt 23 */
+
+ DECLARE_INT_HANDLER eclic_irq24_handler /* 24: Interrupt 24 */
+ DECLARE_INT_HANDLER eclic_irq25_handler /* 25: Interrupt 25 */
+ DECLARE_INT_HANDLER eclic_irq26_handler /* 26: Interrupt 26 */
+ DECLARE_INT_HANDLER eclic_irq27_handler /* 27: Interrupt 27 */
+
+ DECLARE_INT_HANDLER eclic_irq28_handler /* 28: Interrupt 28 */
+ DECLARE_INT_HANDLER eclic_irq29_handler /* 29: Interrupt 29 */
+ DECLARE_INT_HANDLER eclic_irq30_handler /* 30: Interrupt 30 */
+ DECLARE_INT_HANDLER eclic_irq31_handler /* 31: Interrupt 31 */
+
+ DECLARE_INT_HANDLER eclic_irq32_handler /* 32: Interrupt 32 */
+ DECLARE_INT_HANDLER eclic_irq33_handler /* 33: Interrupt 33 */
+ DECLARE_INT_HANDLER eclic_irq34_handler /* 34: Interrupt 34 */
+ DECLARE_INT_HANDLER eclic_irq35_handler /* 35: Interrupt 35 */
+
+ DECLARE_INT_HANDLER eclic_irq36_handler /* 36: Interrupt 36 */
+ DECLARE_INT_HANDLER eclic_irq37_handler /* 37: Interrupt 37 */
+ DECLARE_INT_HANDLER eclic_irq38_handler /* 38: Interrupt 38 */
+ DECLARE_INT_HANDLER eclic_irq39_handler /* 39: Interrupt 39 */
+
+ DECLARE_INT_HANDLER eclic_irq40_handler /* 40: Interrupt 40 */
+ DECLARE_INT_HANDLER eclic_irq41_handler /* 41: Interrupt 41 */
+ DECLARE_INT_HANDLER eclic_irq42_handler /* 42: Interrupt 42 */
+ DECLARE_INT_HANDLER eclic_irq43_handler /* 43: Interrupt 43 */
+
+ DECLARE_INT_HANDLER eclic_irq44_handler /* 44: Interrupt 44 */
+ DECLARE_INT_HANDLER eclic_irq45_handler /* 45: Interrupt 45 */
+ DECLARE_INT_HANDLER eclic_irq46_handler /* 46: Interrupt 46 */
+ DECLARE_INT_HANDLER eclic_irq47_handler /* 47: Interrupt 47 */
+
+ DECLARE_INT_HANDLER eclic_irq48_handler /* 48: Interrupt 48 */
+ DECLARE_INT_HANDLER eclic_irq49_handler /* 49: Interrupt 49 */
+ DECLARE_INT_HANDLER eclic_irq50_handler /* 50: Interrupt 50 */
+
+
+ .section .init
+
+ .globl _start
+ .type _start,@function
+
+/**
+ * Reset Handler called on controller reset
+ */
+_start:
+ /* ===== Startup Stage 1 ===== */
+ /* Disable Global Interrupt */
+ csrc CSR_MSTATUS, MSTATUS_MIE
+
+ /* Initialize GP and Stack Pointer SP */
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+ la sp, _sp
+
+ /*
+ * Set the the NMI base mnvec to share
+ * with mtvec by setting CSR_MMISC_CTL
+ * bit 9 NMI_CAUSE_FFF to 1
+ */
+ li t0, MMISC_CTL_NMI_CAUSE_FFF
+ csrs CSR_MMISC_CTL, t0
+
+ /*
+ * Intialize ECLIC vector interrupt
+ * base address mtvt to vector_base
+ */
+ la t0, vector_base
+ csrw CSR_MTVT, t0
+
+ /*
+ * Set ECLIC non-vector entry to be controlled
+ * by mtvt2 CSR register.
+ * Intialize ECLIC non-vector interrupt
+ * base address mtvt2 to irq_entry.
+ */
+ la t0, irq_entry
+ csrw CSR_MTVT2, t0
+ csrs CSR_MTVT2, 0x1
+
+ /*
+ * Set Exception Entry MTVEC to exc_entry
+ * Due to settings above, Exception and NMI
+ * will share common entry.
+ */
+ la t0, exc_entry
+// la t0, HalTrapEntry
+ csrw CSR_MTVEC, t0
+
+ /* Set the interrupt processing mode to ECLIC mode */
+ li t0, 0x3f
+ csrc CSR_MTVEC, t0
+ csrs CSR_MTVEC, 0x3
+
+ /* ===== Startup Stage 2 ===== */
+
+#ifdef __riscv_flen
+ /* Enable FPU */
+ li t0, MSTATUS_FS
+ csrs mstatus, t0
+ csrw fcsr, x0
+#endif
+
+ /* Enable mcycle and minstret counter */
+ csrci CSR_MCOUNTINHIBIT, 0x5
+
+ /* ===== Startup Stage 3 ===== */
+ /*
+ * Load code section from FLASH to ILM
+ * when code LMA is different with VMA
+ */
+ la a0, _ilm_lma
+ la a1, _ilm
+ /* If the ILM phy-address same as the logic-address, then quit */
+ beq a0, a1, 2f
+ la a2, _eilm
+ bgeu a1, a2, 2f
+
+1:
+ /* Load code section if necessary */
+ lw t0, (a0)
+ sw t0, (a1)
+ addi a0, a0, 4
+ addi a1, a1, 4
+ bltu a1, a2, 1b
+2:
+ /* Load data section */
+ la a0, _data_lma
+ la a1, _data
+ la a2, _edata
+ bgeu a1, a2, 2f
+1:
+ lw t0, (a0)
+ sw t0, (a1)
+ addi a0, a0, 4
+ addi a1, a1, 4
+ bltu a1, a2, 1b
+2:
+ /* Clear bss section */
+ la a0, __bss_start
+ la a1, _end
+ bgeu a0, a1, 2f
+1:
+ sw zero, (a0)
+ addi a0, a0, 4
+ bltu a0, a1, 1b
+2:
+
+ /*
+ * Call vendor defined SystemInit to
+ * initialize the micro-controller system
+ */
+ call SystemInit
+
+ /* Call global constructors */
+ la a0, __libc_fini_array
+ call atexit
+ /* Call C/C++ constructor start up code */
+ call __libc_init_array
+
+ /* do pre-init steps before main */
+ call _premain_init
+ /* ===== Call Main Function ===== */
+ /* argc = argv = 0 */
+ li a0, 0
+ li a1, 0
+
+#ifdef RTOS_RTTHREAD
+ // Call entry function when using RT-Thread
+ call entry
+#else
+ call main
+#endif
+ /* do post-main steps after main */
+ call _postmain_fini
+
+1:
+ j 1b
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_getres.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_getres.c
new file mode 100644
index 00000000..820f5146
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_getres.c
@@ -0,0 +1,14 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+#include
+
+/* Get resolution of clock. */
+__WEAK int clock_getres(clockid_t clock_id, struct timespec *res)
+{
+ res->tv_sec = 0;
+ res->tv_nsec = 1000000000 / SystemCoreClock;
+
+ return 0;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_gettime.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_gettime.c
new file mode 100644
index 00000000..8f4ca46b
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_gettime.c
@@ -0,0 +1,21 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+#include
+
+extern int _gettimeofday(struct timeval *tp, void *tzp);
+
+/* Get current value of CLOCK and store it in tp. */
+__WEAK int clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+ struct timeval tv;
+ int retval = -1;
+
+ retval = _gettimeofday(&tv, NULL);
+ if (retval == 0) {
+ TIMEVAL_TO_TIMESPEC(&tv, tp);
+ }
+
+ return retval;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_settime.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_settime.c
new file mode 100644
index 00000000..caa2936d
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/clock_settime.c
@@ -0,0 +1,10 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+
+/* Set CLOCK to value TP. */
+__WEAK int clock_settime(clockid_t clock_id, const struct timespec *tp)
+{
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/close.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/close.c
new file mode 100644
index 00000000..ac2fae9f
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/close.c
@@ -0,0 +1,12 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _close(int fd)
+{
+ errno = EBADF;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/execve.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/execve.c
new file mode 100644
index 00000000..b4386247
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/execve.c
@@ -0,0 +1,12 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _execve(char *name, char **argv, char **env)
+{
+ errno = ENOMEM;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/exit.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/exit.c
new file mode 100644
index 00000000..0e33d9f2
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/exit.c
@@ -0,0 +1,9 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+
+__WEAK void _exit(int fd)
+{
+ while(1) {
+ __WFI();
+ }
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fork.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fork.c
new file mode 100644
index 00000000..fddb47be
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fork.c
@@ -0,0 +1,12 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fstat.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fstat.c
new file mode 100644
index 00000000..2cffbb47
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/fstat.c
@@ -0,0 +1,19 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _fstat(int file, struct stat *st)
+{
+ if ((STDOUT_FILENO == file) || (STDERR_FILENO == file)) {
+ st->st_mode = S_IFCHR;
+ return 0;
+ } else {
+ errno = EBADF;
+ return -1;
+ }
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/getpid.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/getpid.c
new file mode 100644
index 00000000..362f5cfe
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/getpid.c
@@ -0,0 +1,8 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+__WEAK int _getpid(void)
+{
+ return 1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/gettimeofday.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/gettimeofday.c
new file mode 100644
index 00000000..ec60a655
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/gettimeofday.c
@@ -0,0 +1,15 @@
+/* See LICENSE of license details. */
+#include
+#include
+#include "nuclei_sdk_soc.h"
+
+__WEAK int _gettimeofday(struct timeval *tp, void *tzp)
+{
+ uint64_t cycles;
+
+ cycles = __get_rv_cycle();
+
+ tp->tv_sec = cycles / SystemCoreClock;
+ tp->tv_usec = (cycles % SystemCoreClock) * 1000000 / SystemCoreClock;
+ return 0;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/isatty.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/isatty.c
new file mode 100644
index 00000000..d7f29b31
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/isatty.c
@@ -0,0 +1,8 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+__WEAK int _isatty(int fd)
+{
+ return 1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/kill.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/kill.c
new file mode 100644
index 00000000..ffad3493
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/kill.c
@@ -0,0 +1,11 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#undef errno
+extern int errno;
+
+__WEAK int _kill(int pid, int sig)
+{
+ errno = EINVAL;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/link.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/link.c
new file mode 100644
index 00000000..59cdd3d9
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/link.c
@@ -0,0 +1,12 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+int _link(char *old, char *new)
+{
+ errno = EMLINK;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/lseek.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/lseek.c
new file mode 100644
index 00000000..90e4d13a
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/lseek.c
@@ -0,0 +1,11 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _lseek(int file, int offset, int whence)
+{
+ return 0;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/open.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/open.c
new file mode 100644
index 00000000..d41d2770
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/open.c
@@ -0,0 +1,12 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _open(const char *name, int flags, int mode)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/read.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/read.c
new file mode 100644
index 00000000..6919a8c7
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/read.c
@@ -0,0 +1,22 @@
+/* See LICENSE of license details. */
+#include
+#include
+#include
+#include
+#include "nuclei_sdk_hal.h"
+
+// #define UART_AUTO_ECHO
+
+__WEAK ssize_t _read(int fd, void* ptr, size_t len)
+{
+ if (fd != STDIN_FILENO) {
+ return -1;
+ }
+
+ uint8_t *readbuf = (uint8_t *)ptr;
+ readbuf[0] = uart_read(SOC_DEBUG_UART);
+#ifdef UART_AUTO_ECHO
+ uart_write(SOC_DEBUG_UART, readbuf[0]);
+#endif
+ return 1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/sbrk.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/sbrk.c
new file mode 100644
index 00000000..301ef4d2
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/sbrk.c
@@ -0,0 +1,19 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+#include
+
+__WEAK void *_sbrk(ptrdiff_t incr)
+{
+ extern char _end[];
+ extern char _heap_end[];
+ static char *curbrk = _end;
+
+ if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) {
+ return (void *)(-1);
+ }
+
+ curbrk += incr;
+ return (void *)(curbrk - incr);
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stat.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stat.c
new file mode 100644
index 00000000..e07c335e
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stat.c
@@ -0,0 +1,9 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+
+__WEAK int _stat(char *file, struct stat *st)
+{
+ st->st_mode = S_IFCHR;
+ return 0;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stub.h b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stub.h
new file mode 100644
index 00000000..ca369446
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/stub.h
@@ -0,0 +1,5 @@
+
+static inline int _stub(int err)
+{
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/times.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/times.c
new file mode 100644
index 00000000..745be651
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/times.c
@@ -0,0 +1,27 @@
+/* See LICENSE of license details. */
+#include
+#include
+#include
+#include "nuclei_sdk_soc.h"
+
+extern int _gettimeofday(struct timeval *, void *);
+
+__WEAK clock_t _times(struct tms *buf)
+{
+ static struct timeval t0;
+ struct timeval t;
+ long long utime;
+
+ /* When called for the first time, initialize t0. */
+ if (t0.tv_sec == 0 && t0.tv_usec == 0) {
+ _gettimeofday(&t0, 0);
+ }
+
+ _gettimeofday(&t, 0);
+
+ utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec);
+ buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000;
+ buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0;
+
+ return buf->tms_utime;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/unlink.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/unlink.c
new file mode 100644
index 00000000..3662c546
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/unlink.c
@@ -0,0 +1,12 @@
+
+/* See LICENSE of license details. */
+#include
+#include "nuclei_sdk_hal.h"
+
+#undef errno
+extern int errno;
+
+__WEAK int _unlink(const char *name)
+{
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/wait.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/wait.c
new file mode 100644
index 00000000..49e1e933
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/wait.c
@@ -0,0 +1,13 @@
+/* See LICENSE of license details. */
+#include "nuclei_sdk_soc.h"
+#include
+#include
+
+#undef errno
+extern int errno;
+
+__WEAK int _wait(int *status)
+{
+ errno = ECHILD;
+ return -1;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/write.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/write.c
new file mode 100644
index 00000000..e681e183
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/Stubs/write.c
@@ -0,0 +1,22 @@
+/* See LICENSE of license details. */
+#include
+#include
+#include
+#include
+#include "nuclei_sdk_hal.h"
+
+__WEAK ssize_t _write(int fd, const void* ptr, size_t len)
+{
+ if (!isatty(fd)) {
+ return -1;
+ }
+
+ const uint8_t *writebuf = (const uint8_t *)ptr;
+ for (size_t i = 0; i < len; i++) {
+ if (writebuf[i] == '\n') {
+ uart_write(SOC_DEBUG_UART, '\r');
+ }
+ uart_write(SOC_DEBUG_UART, writebuf[i]);
+ }
+ return len;
+}
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/hbird_common.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/hbird_common.c
new file mode 100644
index 00000000..b32a74b3
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/hbird_common.c
@@ -0,0 +1,69 @@
+#include "nuclei_sdk_soc.h"
+
+static uint32_t get_timer_freq()
+{
+ return SOC_TIMER_FREQ;
+}
+
+uint32_t measure_cpu_freq(uint32_t n)
+{
+ uint32_t start_mcycle, delta_mcycle;
+ uint32_t start_mtime, delta_mtime;
+ uint32_t mtime_freq = get_timer_freq();
+
+ // Don't start measuruing until we see an mtime tick
+ uint32_t tmp = (uint32_t)SysTimer_GetLoadValue();
+ do {
+ start_mtime = (uint32_t)SysTimer_GetLoadValue();
+ start_mcycle = __RV_CSR_READ(CSR_MCYCLE);
+ } while (start_mtime == tmp);
+
+ do {
+ delta_mtime = (uint32_t)SysTimer_GetLoadValue() - start_mtime;
+ delta_mcycle = __RV_CSR_READ(CSR_MCYCLE) - start_mcycle;
+ } while (delta_mtime < n);
+
+ return (delta_mcycle / delta_mtime) * mtime_freq
+ + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
+}
+
+uint32_t get_cpu_freq()
+{
+ uint32_t cpu_freq;
+
+ // warm up
+ measure_cpu_freq(1);
+ // measure for real
+ cpu_freq = measure_cpu_freq(100);
+
+ return cpu_freq;
+}
+
+/**
+ * \brief delay a time in milliseconds
+ * \details
+ * provide API for delay
+ * \param[in] count: count in milliseconds
+ * \remarks
+ */
+void delay_1ms(uint32_t count)
+{
+ uint64_t start_mtime, delta_mtime;
+ uint64_t delay_ticks = (SOC_TIMER_FREQ * (uint64_t)count) / 1000;
+
+ start_mtime = SysTimer_GetLoadValue();
+
+ do {
+ delta_mtime = SysTimer_GetLoadValue() - start_mtime;
+ } while (delta_mtime < delay_ticks);
+}
+
+#ifdef SIMULATION_XLSPIKE
+// never return for xlspike
+void xlspike_exit(int status)
+{
+ // pass exit status via rxfifo register
+ UART0->RXFIFO = status;
+ uart_write(UART0, 4);
+}
+#endif
diff --git a/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/system_hbird.c b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/system_hbird.c
new file mode 100644
index 00000000..d6e59b48
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/SoC/hbird/Common/Source/system_hbird.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
+ * Copyright (c) 2019 Nuclei 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.
+ */
+/******************************************************************************
+ * @file system_hbird.c
+ * @brief NMSIS Nuclei Core Device Peripheral Access Layer Source File for
+ * Nuclei HummingBird evaluation SoC which support Nuclei N/NX class cores
+ * @version V1.00
+ * @date 22. Nov 2019
+ ******************************************************************************/
+#include
+#include
+#include "nuclei_sdk_hal.h"
+#include "los_arch_interrupt.h"
+#include "los_debug.h"
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+/* ToDo: add here your necessary defines for device initialization
+ following is an example for different system frequencies */
+#ifndef SYSTEM_CLOCK
+#define SYSTEM_CLOCK (80000000UL)
+#endif
+
+/**
+ * \defgroup NMSIS_Core_SystemConfig System Device Configuration
+ * \brief Functions for system and clock setup available in system_.c.
+ * \details
+ * Nuclei provides a template file **system_Device.c** that must be adapted by
+ * the silicon vendor to match their actual device. As a minimum requirement,
+ * this file must provide:
+ * - A device-specific system configuration function, \ref SystemInit.
+ * - A global variable that contains the system frequency, \ref SystemCoreClock.
+ * - A global eclic configuration initialization, \ref ECLIC_Init.
+ * - Global c library \ref _init and \ref _fini functions called right before calling main function.
+ * - Vendor customized interrupt, exception and nmi handling code, see \ref NMSIS_Core_IntExcNMI_Handling
+ *
+ * The file configures the device and, typically, initializes the oscillator (PLL) that is part
+ * of the microcontroller device. This file might export other functions or variables that provide
+ * a more flexible configuration of the microcontroller system.
+ *
+ * And this file also provided common interrupt, exception and NMI exception handling framework template,
+ * Silicon vendor can customize these template code as they want.
+ *
+ * \note Please pay special attention to the static variable \c SystemCoreClock. This variable might be
+ * used throughout the whole system initialization and runtime to calculate frequency/time related values.
+ * Thus one must assure that the variable always reflects the actual system clock speed.
+ *
+ * \attention
+ * Be aware that a value stored to \c SystemCoreClock during low level initializaton (i.e. \c SystemInit()) might get
+ * overwritten by C libray startup code and/or .bss section initialization.
+ * Thus its highly recommended to call \ref SystemCoreClockUpdate at the beginning of the user \c main() routine.
+ *
+ * @{
+ */
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+/* ToDo: initialize SystemCoreClock with the system core clock frequency value
+ achieved after system intitialization.
+ This means system core clock frequency after call to SystemInit() */
+/**
+ * \brief Variable to hold the system core clock value
+ * \details
+ * Holds the system core clock, which is the system clock frequency supplied to the SysTick
+ * timer and the processor core clock. This variable can be used by debuggers to query the
+ * frequency of the debug timer or to configure the trace clock speed.
+ *
+ * \attention
+ * Compilers must be configured to avoid removing this variable in case the application
+ * program is not using it. Debugging systems require the variable to be physically
+ * present in memory so that it can be examined to configure the debugger.
+ */
+uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock) */
+
+/*----------------------------------------------------------------------------
+ Clock functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Function to update the variable \ref SystemCoreClock
+ * \details
+ * Updates the variable \ref SystemCoreClock and must be called whenever the core clock is changed
+ * during program execution. The function evaluates the clock register settings and calculates
+ * the current core clock.
+ */
+void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
+{
+ /* ToDo: add code to calculate the system frequency based upon the current
+ * register settings.
+ * Note: This function can be used to retrieve the system core clock frequeny
+ * after user changed register settings.
+ */
+ SystemCoreClock = SYSTEM_CLOCK;
+}
+
+/**
+ * \brief Function to Initialize the system.
+ * \details
+ * Initializes the microcontroller system. Typically, this function configures the
+ * oscillator (PLL) that is part of the microcontroller device. For systems
+ * with a variable clock speed, it updates the variable \ref SystemCoreClock.
+ * SystemInit is called from the file startup_device.
+ */
+void SystemInit (void)
+{
+ /* ToDo: add code to initialize the system
+ * Warn: do not use global variables because this function is called before
+ * reaching pre-main. RW section maybe overwritten afterwards.
+ */
+ SystemCoreClock = SYSTEM_CLOCK;
+}
+
+/**
+ * \defgroup NMSIS_Core_IntExcNMI_Handling Interrupt and Exception and NMI Handling
+ * \brief Functions for interrupt, exception and nmi handle available in system_.c.
+ * \details
+ * Nuclei provide a template for interrupt, exception and NMI handling. Silicon Vendor could adapat according
+ * to their requirement. Silicon vendor could implement interface for different exception code and
+ * replace current implementation.
+ *
+ * @{
+ */
+/** \brief Max exception handler number, don't include the NMI(0xFFF) one */
+#define MAX_SYSTEM_EXCEPTION_NUM 12
+/**
+ * \brief Store the exception handlers for each exception ID
+ * \note
+ * - This SystemExceptionHandlers are used to store all the handlers for all
+ * the exception codes Nuclei N/NX core provided.
+ * - Exception code 0 - 11, totally 12 exceptions are mapped to SystemExceptionHandlers[0:11]
+ * - Exception for NMI is also re-routed to exception handling(exception code 0xFFF) in startup code configuration, the handler itself is mapped to SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]
+ */
+static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM+1];
+
+/**
+ * \brief Exception Handler Function Typedef
+ * \note
+ * This typedef is only used internal in this system_.c file.
+ * It is used to do type conversion for registered exception handler before calling it.
+ */
+typedef void (*EXC_HANDLER) (unsigned long mcause, unsigned long sp);
+
+/**
+ * \brief System Default Exception Handler
+ * \details
+ * This function provided a default exception and NMI handling code for all exception ids.
+ * By default, It will just print some information for debug, Vendor can customize it according to its requirements.
+ */
+static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
+{
+ /* TODO: Uncomment this if you have implement printf function */
+ printf("MCAUSE: 0x%lx\r\n", mcause);
+ printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
+ printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));
+ while(1);
+}
+
+/**
+ * \brief Initialize all the default core exception handlers
+ * \details
+ * The core exception handler for each exception id will be initialized to \ref system_default_exception_handler.
+ * \note
+ * Called in \ref _init function, used to initialize default exception handlers for all exception IDs
+ */
+static void Exception_Init(void)
+{
+ for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM+1; i++) {
+ SystemExceptionHandlers[i] = (unsigned long)system_default_exception_handler;
+ }
+}
+
+/**
+ * \brief Register an exception handler for exception code EXCn
+ * \details
+ * * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will be registered into SystemExceptionHandlers[EXCn-1].
+ * * For EXCn == NMI_EXCn, it will be registered into SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].
+ * \param EXCn See \ref EXCn_Type
+ * \param exc_handler The exception handler for this exception code EXCn
+ */
+void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
+{
+ if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
+ SystemExceptionHandlers[EXCn] = exc_handler;
+ } else if (EXCn == NMI_EXCn) {
+ SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] = exc_handler;
+ }
+}
+
+/**
+ * \brief Get current exception handler for exception code EXCn
+ * \details
+ * * For EXCn < \ref MAX_SYSTEM_EXCEPTION_NUM, it will return SystemExceptionHandlers[EXCn-1].
+ * * For EXCn == NMI_EXCn, it will return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].
+ * \param EXCn See \ref EXCn_Type
+ * \return Current exception handler for exception code EXCn, if not found, return 0.
+ */
+unsigned long Exception_Get_EXC(uint32_t EXCn)
+{
+ if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
+ return SystemExceptionHandlers[EXCn];
+ } else if (EXCn == NMI_EXCn) {
+ return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * \brief Common NMI and Exception handler entry
+ * \details
+ * This function provided a command entry for NMI and exception. Silicon Vendor could modify
+ * this template implementation according to requirement.
+ * \remarks
+ * - RISCV provided common entry for all types of exception. This is proposed code template
+ * for exception entry function, Silicon Vendor could modify the implementation.
+ * - For the core_exception_handler template, we provided exception register function \ref Exception_Register_EXC
+ * which can help developer to register your exception handler for specific exception number.
+ */
+uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
+{
+ uint32_t EXCn = (uint32_t)(mcause & 0X00000fff);
+ EXC_HANDLER exc_handler;
+
+ PRINTK("----------------All Task infomation ------------\r\n");
+ HalDisplayTaskInfo();
+ PRINTK("---------------exc handler infomation -----------\r\n");
+
+ if ((EXCn < MAX_SYSTEM_EXCEPTION_NUM) && (EXCn >= 0)) {
+ exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn];
+ } else if (EXCn == NMI_EXCn) {
+ exc_handler = (EXC_HANDLER)SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
+ } else {
+ exc_handler = (EXC_HANDLER)system_default_exception_handler;
+ }
+ if (exc_handler != NULL) {
+ exc_handler(mcause, sp);
+ }
+ return 0;
+}
+/** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
+
+/** Banner Print for Nuclei SDK */
+void SystemBannerPrint(void)
+{
+#if defined(NUCLEI_BANNER) && (NUCLEI_BANNER == 1)
+#ifndef DOWNLOAD_MODE
+#error DOWNLOAD_MODE is not defined via build system, please check!
+#endif
+ const char* download_modes[] = {"FLASHXIP", "FLASH", "ILM", "DDR"};
+ printf("Nuclei SDK Build Time: %s, %s\r\n", __DATE__, __TIME__);
+ printf("Download Mode: %s\r\n", download_modes[DOWNLOAD_MODE]);
+ printf("CPU Frequency %lu Hz\r\n", SystemCoreClock);
+#endif
+}
+
+/**
+ * \brief initialize eclic config
+ * \details
+ * ECLIC needs be initialized after boot up,
+ * Vendor could also change the initialization
+ * configuration.
+ */
+void ECLIC_Init(void)
+{
+ /* Global Configuration about MTH and NLBits.
+ * TODO: Please adapt it according to your system requirement.
+ * This function is called in _init function */
+ ECLIC_SetMth(0);
+ ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS);
+}
+
+/**
+ * \brief Initialize a specific IRQ and register the handler
+ * \details
+ * This function set vector mode, trigger mode and polarity, interrupt level and priority,
+ * assign handler for specific IRQn.
+ * \param [in] IRQn NMI interrupt handler address
+ * \param [in] shv \ref ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and \ref ECLIC_VECTOR_INTERRUPT is vector mode
+ * \param [in] trig_mode see \ref ECLIC_TRIGGER_Type
+ * \param [in] lvl interupt level
+ * \param [in] priority interrupt priority
+ * \param [in] handler interrupt handler, if NULL, handler will not be installed
+ * \return -1 means invalid input parameter. 0 means successful.
+ * \remarks
+ * - This function use to configure specific eclic interrupt and register its interrupt handler and enable its interrupt.
+ * - If the vector table is placed in read-only section(FLASHXIP mode), handler could not be installed
+ */
+int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void *handler)
+{
+ if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
+ || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER )) {
+ return -1;
+ }
+
+ /* set interrupt vector mode */
+ ECLIC_SetShvIRQ(IRQn, shv);
+ /* set interrupt trigger mode and polarity */
+ ECLIC_SetTrigIRQ(IRQn, trig_mode);
+ /* set interrupt level */
+ ECLIC_SetLevelIRQ(IRQn, lvl);
+ /* set interrupt priority */
+ ECLIC_SetPriorityIRQ(IRQn, priority);
+ if (handler != NULL) {
+ /* set interrupt handler entry to vector table */
+ ECLIC_SetVector(IRQn, (rv_csr_t)handler);
+ }
+ /* enable interrupt */
+ ECLIC_EnableIRQ(IRQn);
+ return 0;
+}
+/** @} */ /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
+
+/**
+ * \brief early init function before main
+ * \details
+ * This function is executed right before main function.
+ * For RISC-V gnu toolchain, _init function might not be called
+ * by __libc_init_array function, so we defined a new function
+ * to do initialization
+ */
+void _premain_init(void)
+{
+ /* TODO: Add your own initialization code here, called before main */
+ /* __ICACHE_PRESENT and __DCACHE_PRESENT are defined in hbird.h */
+#if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT == 1
+ EnableICache();
+#endif
+#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT == 1
+ EnableDCache();
+#endif
+ SystemCoreClock = get_cpu_freq();
+ gpio_iof_config(GPIO, IOF0_UART0_MASK, IOF_SEL_0);
+ uart_init(SOC_DEBUG_UART, 115200);
+ /* Display banner after UART initialized */
+ SystemBannerPrint();
+ /* Initialize exception default handlers */
+ Exception_Init();
+ /* ECLIC initilization, mainly MTH and NLBIT */
+ ECLIC_Init();
+}
+
+/**
+ * \brief finish function after main
+ * \param [in] status status code return from main
+ * \details
+ * This function is executed right after main function.
+ * For RISC-V gnu toolchain, _fini function might not be called
+ * by __libc_fini_array function, so we defined a new function
+ * to do initialization
+ */
+void _postmain_fini(int status)
+{
+ /* TODO: Add your own finishing code here, called after main */
+#ifdef SIMULATION_XLSPIKE
+extern void xlspike_exit(int status);
+ xlspike_exit(status);
+#endif
+}
+
+/**
+ * \brief _init function called in __libc_init_array()
+ * \details
+ * This `__libc_init_array()` function is called during startup code,
+ * user need to implement this function, otherwise when link it will
+ * error init.c:(.text.__libc_init_array+0x26): undefined reference to `_init'
+ * \note
+ * Please use \ref _premain_init function now
+ */
+void _init(void)
+{
+ /* Don't put any code here, please use _premain_init now */
+}
+
+/**
+ * \brief _fini function called in __libc_fini_array()
+ * \details
+ * This `__libc_fini_array()` function is called when exit main.
+ * user need to implement this function, otherwise when link it will
+ * error fini.c:(.text.__libc_fini_array+0x28): undefined reference to `_fini'
+ * \note
+ * Please use \ref _postmain_fini function now
+ */
+void _fini(void)
+{
+ /* Don't put any code here, please use _postmain_fini now */
+}
+
+/** @} */ /* End of Doxygen Group NMSIS_Core_SystemAndClock */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/Src/main.c b/targets/riscv_nuclei_demo_soc_gcc/Src/main.c
new file mode 100644
index 00000000..9eae05c2
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/Src/main.c
@@ -0,0 +1,35 @@
+/**
+ ******************************************************************************
+ * @file : main.c
+ * @brief : Main program body
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2021 Nuclei Limited. All rights reserved.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include
+#include "nuclei_sdk_hal.h"
+#include "task_sample.h"
+#include "target_config.h"
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* USER CODE BEGIN Init */
+ RunTaskSample();
+ while (1)
+ {
+ }
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.c b/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.c
new file mode 100644
index 00000000..6a279c47
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 Nuclei Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Description: Provide a task example.
+ */
+
+#include "task_sample.h"
+
+#include "los_config.h"
+#include "los_debug.h"
+#include "los_interrupt.h"
+#include "los_task.h"
+#include "los_tick.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+#endif /* __cpluscplus */
+
+UINT8 __attribute__ ((aligned (8))) g_memStart[OS_SYS_MEM_SIZE];
+
+VOID TaskSampleEntry2(VOID)
+{
+ while (1) {
+ LOS_TaskDelay(10000); /* 10 Seconds */
+ printf("TaskSampleEntry2 running...\n");
+ }
+}
+
+VOID TaskSampleEntry1(VOID)
+{
+ while (1) {
+ LOS_TaskDelay(2000); /* 2 Seconds */
+ printf("TaskSampleEntry1 running...\n");
+ }
+}
+
+VOID TaskSample(VOID)
+{
+ UINT32 uwRet;
+ UINT32 taskID1;
+ UINT32 taskID2;
+ TSK_INIT_PARAM_S stTask = {0};
+
+ stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1;
+ stTask.uwStackSize = 0x1000;
+ stTask.pcName = "TaskSampleEntry1";
+ stTask.usTaskPrio = 6; /* Os task priority is 6 */
+ uwRet = LOS_TaskCreate(&taskID1, &stTask);
+ if (uwRet != LOS_OK) {
+ printf("Task1 create failed\n");
+ }
+
+ stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2;
+ stTask.uwStackSize = 0x1000;
+ stTask.pcName = "TaskSampleEntry2";
+ stTask.usTaskPrio = 7; /* Os task priority is 7 */
+ uwRet = LOS_TaskCreate(&taskID2, &stTask);
+ if (uwRet != LOS_OK) {
+ printf("Task2 create failed\n");
+ }
+}
+
+VOID RunTaskSample(VOID)
+{
+ UINT32 ret;
+ ret = LOS_KernelInit();
+ if (ret == LOS_OK) {
+ TaskSample();
+ LOS_Start();
+ }
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cpluscplus */
+#endif /* __cpluscplus */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.h b/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.h
new file mode 100644
index 00000000..adcb79b5
--- /dev/null
+++ b/targets/riscv_nuclei_demo_soc_gcc/Src/task_sample.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 Nuclei Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * Description: Provide a task example.
+ */
+
+#ifndef _TASKSAMPLE_H
+#define _TASKSAMPLE_H
+
+#include "los_compiler.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+#endif /* __cpluscplus */
+
+VOID RunTaskSample(VOID);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cpluscplus */
+#endif /* __cpluscplus */
+
+#endif /* _TASKSAMPLE_H */
diff --git a/targets/riscv_nuclei_demo_soc_gcc/doc/image/nuclei_tools_download_linux.png b/targets/riscv_nuclei_demo_soc_gcc/doc/image/nuclei_tools_download_linux.png
new file mode 100644
index 00000000..18eac287
Binary files /dev/null and b/targets/riscv_nuclei_demo_soc_gcc/doc/image/nuclei_tools_download_linux.png differ