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 + +![Nuclei Tools need to be downloaded for Linux](doc/image/nuclei_tools_download_linux.png) + + + +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