Archived
1
0

Initial commit

This commit is contained in:
github-classroom[bot]
2024-02-23 13:01:05 +00:00
committed by GitHub
commit d212040c30
1914 changed files with 1290006 additions and 0 deletions

View File

@ -0,0 +1,368 @@
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# Make sure to add the RISC-V GCC compiler's bin folder to your PATH environment variable. #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# Copyright (c) 2021, Stephan Nolting. 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. #
# ********************************************************************************************* #
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
# -----------------------------------------------------------------------------
# USER CONFIGURATION
# -----------------------------------------------------------------------------
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
# Optimization
EFFORT ?= -Os
# Compiler toolchain
RISCV_PREFIX ?= riscv32-unknown-elf-
# CPU architecture and ABI
MARCH ?= rv32i
MABI ?= ilp32
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
NEORV32_LOCAL_RTL ?= $(NEORV32_HOME)/rtl
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_LOCAL_RTL)/core
# Path to NEORV32 sim folder
NEORV32_SIM_PATH = $(NEORV32_HOME)/sim
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
# Main output files
APP_EXE = neorv32_exe.bin
APP_HEX = neorv32_exe.hex
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
# Define all object files
OBJ = $(SRC:%=%.o)
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_PREFIX)gcc
OBJDUMP = $(RISCV_PREFIX)objdump
OBJCOPY = $(RISCV_PREFIX)objcopy
SIZE = $(RISCV_PREFIX)size
# Host native compiler
CC_X86 = g++ -Wall -O -g
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
# Compiler & linker flags
CC_OPTS = -march=$(MARCH) -mabi=$(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
hex: $(APP_ASM) $(APP_HEX)
compile: $(APP_ASM) $(APP_EXE)
image: $(APP_ASM) $(APP_IMG)
install: image install-$(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG) $(APP_HEX) install
# Check if making bootloader
# Use different base address and length for instruction memory/"rom" (BOOTROM instead of IMEM)
# Also define "make_bootloader" symbol for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
target bl_image: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.c
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
install-$(APP_IMG): $(APP_IMG)
@set -e
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
# Generate NEORV32 executable image in plain hex format
$(APP_HEX): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_hex $< $@ $(shell basename $(CURDIR))
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
install-$(BOOT_IMG): $(BOOT_IMG)
@set -e
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
# Just an alias
bl_image: $(BOOT_IMG)
bootloader: bl_image install-$(BOOT_IMG)
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Configuration ----------------"
@$(CC) -v
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
# -----------------------------------------------------------------------------
# In-console simulation using default/simple testbench and GHDL
# -----------------------------------------------------------------------------
sim: $(APP_IMG) install
@echo "Simulating $(APP_IMG)..."
@sh $(NEORV32_SIM_PATH)/simple/ghdl.sh
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 SW Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo ""
@echo "== Targets =="
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " hex - compile and generate <neorv32_exe.hex> executable raw file"
@echo " image - compile and generate VHDL IMEM boot image (for application) in local folder"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " sim - in-console simulation using default/simple testbench and GHDL"
@echo " all - exe + hex + install"
@echo " elf_info - show ELF layout info"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bl_image - compile and generate VHDL BOOTROM boot image (for bootloader only!) in local folder"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo ""
@echo "== Variables =="
@echo " USER_FLAGS - Custom toolchain flags [append only], default \"$(USER_FLAGS)\""
@echo " EFFORT - Optimization level, default \"$(EFFORT)\""
@echo " MARCH - Machine architecture, default \"$(MARCH)\""
@echo " MABI - Machine binary interface, default \"$(MABI)\""
@echo " APP_INC - C include folder(s) [append only], default \"$(APP_INC)\""
@echo " ASM_INC - ASM include folder(s) [append only], default \"$(ASM_INC)\""
@echo " RISCV_PREFIX - Toolchain prefix, default \"$(RISCV_PREFIX)\""
@echo " NEORV32_HOME - NEORV32 home folder, default \"$(NEORV32_HOME)\""
@echo ""
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd *.hex
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)

View File

@ -0,0 +1,261 @@
/* ################################################################################################# */
/* # << NEORV32 - crt0.S - Start-Up Code >> # */
/* # ********************************************************************************************* # */
/* # BSD 3-Clause License # */
/* # # */
/* # Copyright (c) 2021, Stephan Nolting. 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. # */
/* # ********************************************************************************************* # */
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # */
/* ################################################################################################# */
.file "crt0.S"
.section .text.boot
.balign 4
.global _start
_start:
.cfi_startproc
.cfi_undefined ra
// ************************************************************************************************
// This is the very first instruction that is executed after hardware reset. It ensures that x0 is
// written at least once - the CPU HW will ensure it is always set to zero on any write access.
// ************************************************************************************************
lui zero, 0 // "dummy" instruction that uses no reg-file input operands at all
// ************************************************************************************************
// Setup pointers using linker script symbols
// ************************************************************************************************
__crt0_pointer_init:
.option push
.option norelax
la sp, __crt0_stack_begin // stack pointer
la gp, __global_pointer$ // global pointer
.option pop
// ************************************************************************************************
// Setup CPU core CSRs (some of them DO NOT have a dedicated
// reset and need to be explicitly initialized)
// ************************************************************************************************
__crt0_cpu_csr_init:
la x10, __crt0_dummy_trap_handler // configure early trap handler
csrw mtvec, x10
csrw mepc, x10 // just to init mepc
csrw mstatus, zero // disable global IRQ
csrw mie, zero // absolutely no interrupts sources, thanks
csrw mcounteren, zero // no access from less-privileged modes to counter CSRs
li x11, ~5 // stop all counters except for [m]cycle[h] and [m]instret[h]
csrw 0x320, x11 // = mcountinhibit (literal address for lagacy toolchain compatibility)
csrw mcycle, zero // reset cycle counters
csrw mcycleh, zero
csrw minstret, zero // reset instruction counters
csrw minstreth, zero
// ************************************************************************************************
// Initialize integer register file (lower half)
// ************************************************************************************************
__crt0_reg_file_clear:
//addi x0, x0, 0 // hardwired to zero
addi x1, x0, 0
//addi x2, x0, 0 // stack pointer sp
//addi x3, x0, 0 // global pointer gp
addi x4, x0, 0
addi x5, x0, 0
addi x6, x0, 0
addi x7, x0, 0
//addi x8, x0, 0 // implicitly initialized within crt0
//addi x9, x0, 0 // implicitly initialized within crt0
//addi x10, x0, 0 // implicitly initialized within crt0
//addi x11, x0, 0 // implicitly initialized within crt0
//addi x12, x0, 0 // implicitly initialized within crt0
//addi x13, x0, 0 // implicitly initialized within crt0
addi x14, x0, 0
addi x15, x0, 0
// ************************************************************************************************
// Initialize integer register file (upper half, if no E extension)
// ************************************************************************************************
#ifndef __riscv_32e
// do not do this if compiling bootloader (to save some program space)
#ifndef make_bootloader
addi x16, x0, 0
addi x17, x0, 0
addi x18, x0, 0
addi x19, x0, 0
addi x20, x0, 0
addi x21, x0, 0
addi x22, x0, 0
addi x23, x0, 0
addi x24, x0, 0
addi x25, x0, 0
addi x26, x0, 0
addi x27, x0, 0
addi x28, x0, 0
addi x29, x0, 0
addi x30, x0, 0
addi x31, x0, 0
#endif
#endif
// ************************************************************************************************
// Reset/deactivate IO/peripheral devices
// Devices, that are not implemented, will cause a store bus access fault
// which is captured (but actually ignored) by the dummy trap handler.
// ************************************************************************************************
__crt0_reset_io:
la x8, __ctr0_io_space_begin // start of processor-internal IO region
la x9, __ctr0_io_space_end // end of processor-internal IO region
__crt0_reset_io_loop:
sw zero, 0(x8)
addi x8, x8, 4
bne x8, x9, __crt0_reset_io_loop
// ************************************************************************************************
// Clear .bss section (byte-wise) using linker script symbols
// ************************************************************************************************
__crt0_clear_bss:
la x11, __crt0_bss_start
la x12, __crt0_bss_end
__crt0_clear_bss_loop:
bge x11, x12, __crt0_clear_bss_loop_end
sb zero, 0(x11)
addi x11, x11, 1
j __crt0_clear_bss_loop
__crt0_clear_bss_loop_end:
// ************************************************************************************************
// Copy initialized .data section from ROM to RAM (byte-wise) using linker script symbols
// ************************************************************************************************
__crt0_copy_data:
la x11, __crt0_copy_data_src_begin // start of data area (copy source)
la x12, __crt0_copy_data_dst_begin // start of data area (copy destination)
la x13, __crt0_copy_data_dst_end // last address of destination data area
__crt0_copy_data_loop:
bge x12, x13, __crt0_copy_data_loop_end
lb x14, 0(x11)
sb x14, 0(x12)
addi x11, x11, 1
addi x12, x12, 1
j __crt0_copy_data_loop
__crt0_copy_data_loop_end:
// ************************************************************************************************
// Setup arguments and call main function
// ************************************************************************************************
__crt0_main_entry:
addi x10, zero, 0 // a0 = argc = 0
addi x11, zero, 0 // a1 = argv = 0
jal ra, main // call actual app's main function, this "should" not return
// ************************************************************************************************
// call "after main" handler (if there is any) if main really returns
// ************************************************************************************************
__crt0_main_aftermath:
csrw mscratch, a0 // copy main's return code in mscratch for debugger
#ifndef make_bootloader // after_main handler not supported for bootloader
.weak __neorv32_crt0_after_main
la ra, __neorv32_crt0_after_main
beqz ra, __crt0_main_aftermath_end // check if an aftermath handler has been specified
jalr ra // execute handler, main's return code in a0
#endif
// ************************************************************************************************
// go to endless sleep mode
// ************************************************************************************************
__crt0_main_aftermath_end:
csrci mstatus, 8 // mstatus: disable global IRQs (mstatus.mie)
__crt0_main_aftermath_end_loop:
wfi // try to go to sleep mode
j __crt0_main_aftermath_end_loop // endless loop
// ************************************************************************************************
// dummy trap handler (for exceptions & IRQs during very early boot stage)
// does nothing but tries to move on to next instruction
// ************************************************************************************************
.balign 4
__crt0_dummy_trap_handler:
addi sp, sp, -8
sw x8, 0(sp)
sw x9, 4(sp)
csrr x8, mcause
blt x8, zero, __crt0_dummy_trap_handler_irq // skip mepc modification if interrupt
csrr x8, mepc
__crt0_dummy_trap_handler_exc_c_check: // is compressed instruction?
lh x9, 0(x8) // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
andi x9, x9, 3 // mask: isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
addi x8, x8, +2 // only this for compressed instructions
csrw mepc, x8 // set return address when compressed instruction
addi x8, zero, 3
bne x8, x9, __crt0_dummy_trap_handler_irq // jump if compressed instruction
__crt0_dummy_trap_handler_exc_uncrompressed: // is uncompressed instruction!
csrr x8, mepc
addi x8, x8, +2 // add another 2 (making +4) for uncompressed instructions
csrw mepc, x8
__crt0_dummy_trap_handler_irq:
lw x8, 0(sp)
lw x9, 4(sp)
addi sp, sp, +8
mret
.cfi_endproc
.end

View File

@ -0,0 +1,309 @@
/* ################################################################################################# */
/* # << NEORV32 - RISC-V GCC Linker Script >> # */
/* # ********************************************************************************************* # */
/* # BSD 3-Clause License # */
/* # # */
/* # Copyright (c) 2021, Stephan Nolting. 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. # */
/* # ********************************************************************************************* # */
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # */
/* ################################################################################################# */
/* Default linker script, for normal executables */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
/* modified for the NEORV32 processor by Stephan Nolting */
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
SEARCH_DIR("/opt/riscv/riscv32-unknown-elf/lib"); SEARCH_DIR("=/opt/riscv/riscv64-unknown-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
/* ************************************************************************** */
/* NEORV32 memory section configuration. */
/* ************************************************************************** */
/* "ram" : data memory (int/ext DMEM) - make sure this is sync with the HW! */
/* "rom" : instruction memory (int/ext IMEM or bootloader ROM) */
/* "iodev" : peripheral/IO devices */
/* ************************************************************************** */
MEMORY
{
/* section base addresses and sizes have to be a multiple of 4 bytes */
/* ram section: first value of LENGTH => data memory used by bootloader (fixed!); second value of LENGTH => *physical* size of data memory */
/* adapt the right-most value to match the *total physical data memory size* of your setup */
ram (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024
/* rom and iodev sections should NOT be modified by the user at all! */
/* rom section: first value of ORIGIN/LENGTH => bootloader ROM; second value of ORIGIN/LENGTH => maximum *logical* size of instruction memory */
rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 32K : 2048M
iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512
}
/* ************************************************************************* */
SECTIONS
{
/* start section on WORD boundary */
. = ALIGN(4);
/* Actual instructions */
.text :
{
PROVIDE(__text_start = .);
PROVIDE(__textstart = .);
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
*(.rela.plt)
KEEP(*(.text.boot)); /* keep start-up code at the beginning of rom */
KEEP (*(SORT_NONE(.init)))
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
KEEP (*(SORT_NONE(.fini)))
/* 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))
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* finish section on WORD boundary */
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
} > rom
/* read-only data, appended to .text */
.rodata :
{
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 = .);
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 = .);
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
/* finish section on WORD boundary */
. = ALIGN(4);
} > rom
/* initialized read/write data, accessed in RAM, placed in ROM, copied during boot */
.data :
{
__DATA_BEGIN__ = .;
__SDATA_BEGIN__ = .;
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
*(.data1)
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
*(.dynamic)
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* finish section on WORD boundary */
. = ALIGN(4);
_edata = .; PROVIDE (edata = .);
. = .;
} > ram AT > rom
/* zero/non-initialized read/write data placed in RAM */
.bss (NOLOAD):
{
__bss_start = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 32 / 8 : 1);
. = ALIGN(32 / 8);
__BSS_END__ = .;
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
_end = .; PROVIDE (end = .);
} > ram
/* Yet unused */
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } .interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
/* Provide symbols for neorv32 crt0 start-up code */
PROVIDE(__ctr0_imem_begin = ORIGIN(rom));
PROVIDE(__ctr0_dmem_begin = ORIGIN(ram));
PROVIDE(__crt0_stack_begin = (ORIGIN(ram) + LENGTH(ram)) - 4);
PROVIDE(__crt0_bss_start = __bss_start);
PROVIDE(__crt0_bss_end = __BSS_END__);
PROVIDE(__crt0_copy_data_src_begin = __etext + SIZEOF(.rodata));
PROVIDE(__crt0_copy_data_dst_begin = __DATA_BEGIN__);
PROVIDE(__crt0_copy_data_dst_end = __DATA_BEGIN__ + SIZEOF(.data));
PROVIDE(__ctr0_io_space_begin = ORIGIN(iodev));
PROVIDE(__ctr0_io_space_end = ORIGIN(iodev) + LENGTH(iodev));
}