Merge branch 'riscv-gnu-toolchain-update'
This commit is contained in:
commit
6f866fc1c8
52
Makefile
52
Makefile
|
@ -1,13 +1,13 @@
|
|||
|
||||
RISCV_GNU_TOOLCHAIN_REV = 7e48594
|
||||
NEWLIB_URL = ftp://sourceware.org/pub/newlib/newlib-2.2.0.tar.gz
|
||||
RISCV_GNU_TOOLCHAIN_GIT_REVISION = 914224e
|
||||
RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX = /opt/riscv32
|
||||
|
||||
SHELL = bash
|
||||
TEST_OBJS = $(addsuffix .o,$(basename $(wildcard tests/*.S)))
|
||||
FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/sieve.o firmware/multest.o firmware/stats.o
|
||||
GCC_WARNS = -Werror -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
|
||||
GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion
|
||||
TOOLCHAIN_PREFIX = /opt/riscv32i/bin/riscv32-unknown-elf-
|
||||
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)i/bin/riscv32-unknown-elf-
|
||||
COMPRESSED_ISA = C
|
||||
|
||||
test: testbench.vvp firmware/firmware.hex
|
||||
|
@ -63,26 +63,24 @@ firmware/firmware.bin: firmware/firmware.elf
|
|||
chmod -x $@
|
||||
|
||||
firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds
|
||||
$(TOOLCHAIN_PREFIX)gcc -Os -m32 -ffreestanding -nostdlib -o $@ \
|
||||
$(TOOLCHAIN_PREFIX)gcc -Os -ffreestanding -nostdlib -o $@ \
|
||||
-Wl,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \
|
||||
$(FIRMWARE_OBJS) $(TEST_OBJS) -lgcc
|
||||
chmod -x $@
|
||||
|
||||
firmware/start.o: firmware/start.S
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -m32 -march=RV32IM$(COMPRESSED_ISA)Xcustom -o $@ $<
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -march=rv32im$(subst C,c,$(COMPRESSED_ISA)) -o $@ $<
|
||||
|
||||
firmware/%.o: firmware/%.c
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -m32 -march=RV32I$(COMPRESSED_ISA) -Os --std=c99 $(GCC_WARNS) -ffreestanding -nostdlib -o $@ $<
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -march=rv32i$(subst C,c,$(COMPRESSED_ISA)) -Os --std=c99 $(GCC_WARNS) -ffreestanding -nostdlib -o $@ $<
|
||||
|
||||
tests/%.o: tests/%.S tests/riscv_test.h tests/test_macros.h
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -m32 -march=RV32IM -o $@ -DTEST_FUNC_NAME=$(notdir $(basename $<)) \
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -march=rv32im -o $@ -DTEST_FUNC_NAME=$(notdir $(basename $<)) \
|
||||
-DTEST_FUNC_TXT='"$(notdir $(basename $<))"' -DTEST_FUNC_RET=$(notdir $(basename $<))_ret $<
|
||||
|
||||
download-tools:
|
||||
sudo bash -c 'set -ex; mkdir -p /var/cache/distfiles; $(foreach URL,$(NEWLIB_URL), \
|
||||
if ! test -f /var/cache/distfiles/$(notdir $(URL)); then wget -O /var/cache/distfiles/$(notdir $(URL)).part $(URL); \
|
||||
mv /var/cache/distfiles/$(notdir $(URL)).part /var/cache/distfiles/$(notdir $(URL)); fi;) \
|
||||
$(foreach REPO,riscv-gnu-toolchain riscv-binutils-gdb riscv-dejagnu riscv-gcc riscv-glibc, \
|
||||
sudo bash -c 'set -ex; mkdir -p /var/cache/distfiles; \
|
||||
$(foreach REPO,riscv-gnu-toolchain riscv-binutils-gdb riscv-dejagnu riscv-gcc riscv-glibc riscv-newlib, \
|
||||
if ! test -d /var/cache/distfiles/$(REPO).git; then rm -rf /var/cache/distfiles/$(REPO).git.part; \
|
||||
git clone --bare https://github.com/riscv/$(REPO) /var/cache/distfiles/$(REPO).git.part; \
|
||||
mv /var/cache/distfiles/$(REPO).git.part /var/cache/distfiles/$(REPO).git; else \
|
||||
|
@ -90,9 +88,9 @@ download-tools:
|
|||
|
||||
define build_tools_template
|
||||
build-$(1)-tools:
|
||||
@read -p "This will remove all existing data from /opt/$(1). Type YES to continue: " reply && [[ "$$$$reply" == [Yy][Ee][Ss] || "$$$$reply" == [Yy] ]]
|
||||
sudo bash -c "set -ex; rm -rf /opt/$(1); mkdir -p /opt/$(1); chown $$$${USER}. /opt/$(1)"
|
||||
$(MAKE) build-$(1)-tools-bh
|
||||
@read -p "This will remove all existing data from $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)$(subst riscv32,,$(1)). Type YES to continue: " reply && [[ "$$$$reply" == [Yy][Ee][Ss] || "$$$$reply" == [Yy] ]]
|
||||
sudo bash -c "set -ex; rm -rf $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)$(subst riscv32,,$(1)); mkdir -p $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)$(subst riscv32,,$(1)); chown $$$${USER}. $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)$(subst riscv32,,$(1))"
|
||||
+$(MAKE) build-$(1)-tools-bh
|
||||
|
||||
build-$(1)-tools-bh:
|
||||
+set -ex; \
|
||||
|
@ -101,30 +99,32 @@ build-$(1)-tools-bh:
|
|||
if [ -d /var/cache/distfiles/riscv-dejagnu.git ]; then reference_riscv_dejagnu="--reference /var/cache/distfiles/riscv-dejagnu.git"; else reference_riscv_dejagnu=""; fi; \
|
||||
if [ -d /var/cache/distfiles/riscv-gcc.git ]; then reference_riscv_gcc="--reference /var/cache/distfiles/riscv-gcc.git"; else reference_riscv_gcc=""; fi; \
|
||||
if [ -d /var/cache/distfiles/riscv-glibc.git ]; then reference_riscv_glibc="--reference /var/cache/distfiles/riscv-glibc.git"; else reference_riscv_glibc=""; fi; \
|
||||
if [ -d /var/cache/distfiles/riscv-newlib.git ]; then reference_riscv_newlib="--reference /var/cache/distfiles/riscv-newlib.git"; else reference_riscv_newlib=""; fi; \
|
||||
rm -rf riscv-gnu-toolchain-$(1); git clone $$$$reference_riscv_gnu_toolchain https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain-$(1); \
|
||||
cd riscv-gnu-toolchain-$(1); git checkout $(RISCV_GNU_TOOLCHAIN_REV); \
|
||||
cd riscv-gnu-toolchain-$(1); git checkout $(RISCV_GNU_TOOLCHAIN_GIT_REVISION); \
|
||||
git submodule update --init $$$$reference_riscv_binutils_gdb riscv-binutils-gdb; \
|
||||
git submodule update --init $$$$reference_riscv_dejagnu riscv-dejagnu; \
|
||||
git submodule update --init $$$$reference_riscv_gcc riscv-gcc; \
|
||||
git submodule update --init $$$$reference_riscv_glibc riscv-glibc; \
|
||||
mkdir build; cd build; ../configure --with-arch=$(2) --prefix=/opt/$(1); make
|
||||
git submodule update --init $$$$reference_riscv_newlib riscv-newlib; \
|
||||
mkdir build; cd build; ../configure --with-arch=$(2) --prefix=$(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)$(subst riscv32,,$(1)); make
|
||||
|
||||
.PHONY: build-$(1)-tools
|
||||
endef
|
||||
|
||||
$(eval $(call build_tools_template,riscv32i,RV32I))
|
||||
$(eval $(call build_tools_template,riscv32ic,RV32IC))
|
||||
$(eval $(call build_tools_template,riscv32im,RV32IM))
|
||||
$(eval $(call build_tools_template,riscv32imc,RV32IMC))
|
||||
$(eval $(call build_tools_template,riscv32i,rv32i))
|
||||
$(eval $(call build_tools_template,riscv32ic,rv32ic))
|
||||
$(eval $(call build_tools_template,riscv32im,rv32im))
|
||||
$(eval $(call build_tools_template,riscv32imc,rv32imc))
|
||||
|
||||
build-tools:
|
||||
@echo "This will remove all existing data from /opt/riscv32i, /opt/riscv32ic, /opt/riscv32im, and /opt/riscv32imc."
|
||||
@echo "This will remove all existing data from $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)i, $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)ic, $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)im, and $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)imc."
|
||||
@read -p "Type YES to continue: " reply && [[ "$$reply" == [Yy][Ee][Ss] || "$$reply" == [Yy] ]]
|
||||
sudo bash -c "set -ex; rm -rf /opt/riscv32{i,ic,im,imc}; mkdir -p /opt/riscv32{i,ic,im,imc}; chown $${USER}. /opt/riscv32{i,ic,im,imc}"
|
||||
$(MAKE) build-riscv32i-tools-bh
|
||||
$(MAKE) build-riscv32ic-tools-bh
|
||||
$(MAKE) build-riscv32im-tools-bh
|
||||
$(MAKE) build-riscv32imc-tools-bh
|
||||
sudo bash -c "set -ex; rm -rf $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX){i,ic,im,imc}; mkdir -p $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX){i,ic,im,imc}; chown $${USER}. $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX){i,ic,im,imc}"
|
||||
+$(MAKE) build-riscv32i-tools-bh
|
||||
+$(MAKE) build-riscv32ic-tools-bh
|
||||
+$(MAKE) build-riscv32im-tools-bh
|
||||
+$(MAKE) build-riscv32imc-tools-bh
|
||||
|
||||
toc:
|
||||
gawk '/^-+$$/ { y=tolower(x); gsub("[^a-z0-9]+", "-", y); gsub("-$$", "", y); printf("- [%s](#%s)\n", x, y); } { x=$$0; }' README.md
|
||||
|
|
30
README.md
30
README.md
|
@ -23,6 +23,7 @@ PicoRV32 is free and open hardware licensed under the [ISC license](http://en.wi
|
|||
- [Pico Co-Processor Interface (PCPI)](#pico-co-processor-interface-pcpi)
|
||||
- [Custom Instructions for IRQ Handling](#custom-instructions-for-irq-handling)
|
||||
- [Building a pure RV32I Toolchain](#building-a-pure-rv32i-toolchain)
|
||||
- [Linking binaries with newlib for PicoRV32](#linking-binaries-with-newlib-for-picorv32)
|
||||
- [Evaluation: Timing and Utilization on Xilinx 7-Series FPGAs](#evaluation-timing-and-utilization-on-xilinx-7-series-fpgas)
|
||||
|
||||
|
||||
|
@ -596,13 +597,18 @@ Example:
|
|||
Building a pure RV32I Toolchain
|
||||
-------------------------------
|
||||
|
||||
TL;DR: Run the following commands to build the complete toolchain:
|
||||
|
||||
make download-tools
|
||||
make -j$(nproc) build-tools
|
||||
|
||||
The default settings in the [riscv-tools](https://github.com/riscv/riscv-tools) build
|
||||
scripts will build a compiler, assembler and linker that can target any RISC-V ISA,
|
||||
but the libraries are built for RV32G and RV64G targets. Follow the instructions
|
||||
below to build a complete toolchain (including libraries) that target a pure RV32I
|
||||
CPU.
|
||||
|
||||
The following commands will build the RISC-V gnu toolchain and libraries for a
|
||||
The following commands will build the RISC-V GNU toolchain and libraries for a
|
||||
pure RV32I target, and install it in `/opt/riscv32i`:
|
||||
|
||||
# Ubuntu packages needed:
|
||||
|
@ -614,7 +620,7 @@ pure RV32I target, and install it in `/opt/riscv32i`:
|
|||
|
||||
git clone https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain-rv32i
|
||||
cd riscv-gnu-toolchain-rv32i
|
||||
git checkout 7e48594
|
||||
git checkout 914224e
|
||||
git submodule update --init --recursive
|
||||
|
||||
mkdir build; cd build
|
||||
|
@ -643,7 +649,25 @@ By default calling any of those make targets will (re-)download the toolchain
|
|||
sources. Run `make download-tools` to download the sources to `/var/cache/distfiles/`
|
||||
once in advance.
|
||||
|
||||
*Note: This instructions are for git rev 7e48594 (2016-08-16) of riscv-gnu-toolchain.*
|
||||
*Note: This instructions are for git rev 914224e (2017-01-06) of riscv-gnu-toolchain.*
|
||||
|
||||
|
||||
Linking binaries with newlib for PicoRV32
|
||||
-----------------------------------------
|
||||
|
||||
The tool chains (see last section for install instructions) come with a version of
|
||||
the newlib C standard library.
|
||||
|
||||
Use the linker script [firmware/riscv.ld](firmware/riscv.ld) for linking binaries
|
||||
against the newlib library. Using this linker script will create a binary that
|
||||
has its entry point at 0x10000. (The default linker script does not have a static
|
||||
entry point, thus a proper ELF loader would be needed that can determine the
|
||||
entry point at runtime while loading the program.)
|
||||
|
||||
Newlib comes with a few syscall stubs. You need to provide your own implementation
|
||||
of those syscalls and link your program with this implementation, overwriting the
|
||||
default stubs from newlib. See `syscalls.c` in [scripts/cxxdemo/](scripts/cxxdemo/)
|
||||
for an example of how to do that.
|
||||
|
||||
|
||||
Evaluation: Timing and Utilization on Xilinx 7-Series FPGAs
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
USE_MYSTDLIB = 0
|
||||
OBJS = dhry_1.o dhry_2.o stdlib.o
|
||||
CFLAGS = -MD -O3 -m32 -march=RV32IM -DTIME -DRISCV
|
||||
CFLAGS = -MD -O3 -march=rv32im -DTIME -DRISCV
|
||||
TOOLCHAIN_PREFIX = /opt/riscv32im/bin/riscv32-unknown-elf-
|
||||
|
||||
ifeq ($(USE_MYSTDLIB),1)
|
||||
|
@ -44,7 +44,7 @@ dhry.elf: $(OBJS) sections.lds
|
|||
chmod -x $@
|
||||
else
|
||||
dhry.elf: $(OBJS)
|
||||
$(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -Wl,-Bstatic,-Map,dhry.map,--strip-debug -o $@ $(OBJS) -lgcc -lc
|
||||
$(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -Wl,-Bstatic,-T,../firmware/riscv.ld,-Map,dhry.map,--strip-debug -o $@ $(OBJS) -lgcc -lc
|
||||
chmod -x $@
|
||||
endif
|
||||
|
||||
|
|
|
@ -5,32 +5,98 @@
|
|||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#define q0 0
|
||||
#define q1 1
|
||||
#define q2 2
|
||||
#define q3 3
|
||||
#define regnum_q0 0
|
||||
#define regnum_q1 1
|
||||
#define regnum_q2 2
|
||||
#define regnum_q3 3
|
||||
|
||||
.macro getq rd qs
|
||||
custom0 \rd,\qs,0,0
|
||||
.endm
|
||||
#define regnum_x0 0
|
||||
#define regnum_x1 1
|
||||
#define regnum_x2 2
|
||||
#define regnum_x3 3
|
||||
#define regnum_x4 4
|
||||
#define regnum_x5 5
|
||||
#define regnum_x6 6
|
||||
#define regnum_x7 7
|
||||
#define regnum_x8 8
|
||||
#define regnum_x9 9
|
||||
#define regnum_x10 10
|
||||
#define regnum_x11 11
|
||||
#define regnum_x12 12
|
||||
#define regnum_x13 13
|
||||
#define regnum_x14 14
|
||||
#define regnum_x15 15
|
||||
#define regnum_x16 16
|
||||
#define regnum_x17 17
|
||||
#define regnum_x18 18
|
||||
#define regnum_x19 19
|
||||
#define regnum_x20 20
|
||||
#define regnum_x21 21
|
||||
#define regnum_x22 22
|
||||
#define regnum_x23 23
|
||||
#define regnum_x24 24
|
||||
#define regnum_x25 25
|
||||
#define regnum_x26 26
|
||||
#define regnum_x27 27
|
||||
#define regnum_x28 28
|
||||
#define regnum_x29 29
|
||||
#define regnum_x30 30
|
||||
#define regnum_x31 31
|
||||
|
||||
.macro setq qd rs
|
||||
custom0 \qd,\rs,0,1
|
||||
.endm
|
||||
#define regnum_zero 0
|
||||
#define regnum_ra 1
|
||||
#define regnum_sp 2
|
||||
#define regnum_gp 3
|
||||
#define regnum_tp 4
|
||||
#define regnum_t0 5
|
||||
#define regnum_t1 6
|
||||
#define regnum_t2 7
|
||||
#define regnum_s0 8
|
||||
#define regnum_s1 9
|
||||
#define regnum_a0 10
|
||||
#define regnum_a1 11
|
||||
#define regnum_a2 12
|
||||
#define regnum_a3 13
|
||||
#define regnum_a4 14
|
||||
#define regnum_a5 15
|
||||
#define regnum_a6 16
|
||||
#define regnum_a7 17
|
||||
#define regnum_s2 18
|
||||
#define regnum_s3 19
|
||||
#define regnum_s4 20
|
||||
#define regnum_s5 21
|
||||
#define regnum_s6 22
|
||||
#define regnum_s7 23
|
||||
#define regnum_s8 24
|
||||
#define regnum_s9 25
|
||||
#define regnum_s10 26
|
||||
#define regnum_s11 27
|
||||
#define regnum_t3 28
|
||||
#define regnum_t4 29
|
||||
#define regnum_t5 30
|
||||
#define regnum_t6 31
|
||||
|
||||
.macro retirq
|
||||
custom0 0,0,0,2
|
||||
.endm
|
||||
// x8 is s0 and also fp
|
||||
#define regnum_fp 8
|
||||
|
||||
.macro maskirq rd rs
|
||||
custom0 \rd,\rs,0,3
|
||||
.endm
|
||||
#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \
|
||||
.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0))
|
||||
|
||||
.macro waitirq rd
|
||||
custom0 \rd,0,0,4
|
||||
.endm
|
||||
#define picorv32_getq_insn(_rd, _qs) \
|
||||
r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
.macro timer rd rs
|
||||
custom0 \rd,\rs,0,5
|
||||
.endm
|
||||
#define picorv32_setq_insn(_qd, _rs) \
|
||||
r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011)
|
||||
|
||||
#define picorv32_retirq_insn() \
|
||||
r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011)
|
||||
|
||||
#define picorv32_maskirq_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_waitirq_insn(_rd) \
|
||||
r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_timer_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/* Default linker script, for normal executables */
|
||||
/* Copyright (C) 2014-2016 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. */
|
||||
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
|
||||
"elf32-littleriscv")
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00010000;
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
}
|
||||
.plt : { *(.plt) }
|
||||
.iplt : { *(.iplt) }
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 :
|
||||
{
|
||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
||||
}
|
||||
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.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 = .);
|
||||
}
|
||||
.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 = .);
|
||||
}
|
||||
.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))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = DATA_SEGMENT_RELRO_END (0, .);
|
||||
.data :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
|
||||
/* 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. */
|
||||
.sdata :
|
||||
{
|
||||
_gp = . + 0x800;
|
||||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
|
||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||
}
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.sbss :
|
||||
{
|
||||
*(.dynsbss)
|
||||
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
}
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(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 don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 32 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(32 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(32 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* 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) }
|
||||
/* 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_*) }
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
--- <(riscv32-unknown-elf-ld -z nocombreloc -verbose) 2017-01-13 16:55:07.569030165 +0100
|
||||
+++ riscv.ld 2017-01-13 16:56:47.796761642 +0100
|
||||
@@ -1,9 +1,3 @@
|
||||
-GNU ld (GNU Binutils) 2.28.51.20170101
|
||||
- Supported emulations:
|
||||
- elf32lriscv
|
||||
- elf64lriscv
|
||||
-using internal linker script:
|
||||
-==================================================
|
||||
/* Default linker script, for normal executables */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
@@ -13,62 +7,26 @@
|
||||
"elf32-littleriscv")
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
-SEARCH_DIR("/opt/new_riscv32i/riscv32-unknown-elf/lib");
|
||||
SECTIONS
|
||||
{
|
||||
- /* Read-only sections, merged into text segment: */
|
||||
- PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x10000)); . = SEGMENT_START("text-segment", 0x10000) + SIZEOF_HEADERS;
|
||||
- .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.*) }
|
||||
- .rela.iplt :
|
||||
- {
|
||||
- PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
- *(.rela.iplt)
|
||||
- PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
- }
|
||||
- .rela.plt :
|
||||
- {
|
||||
- *(.rela.plt)
|
||||
- }
|
||||
- .init :
|
||||
- {
|
||||
- KEEP (*(SORT_NONE(.init)))
|
||||
- }
|
||||
- .plt : { *(.plt) }
|
||||
- .iplt : { *(.iplt) }
|
||||
+ . = 0x00010000;
|
||||
.text :
|
||||
{
|
||||
+ *(.text)
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
- *(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
+ *(.stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
+ .init :
|
||||
+ {
|
||||
+ KEEP (*(SORT_NONE(.init)))
|
||||
+ }
|
||||
+ .plt : { *(.plt) }
|
||||
+ .iplt : { *(.iplt) }
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
@@ -240,5 +198,3 @@
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
-
|
||||
-==================================================
|
|
@ -34,8 +34,8 @@
|
|||
|
||||
reset_vec:
|
||||
// no more than 16 bytes here !
|
||||
waitirq zero
|
||||
maskirq zero, zero
|
||||
picorv32_waitirq_insn(zero)
|
||||
picorv32_maskirq_insn(zero, zero)
|
||||
j start
|
||||
|
||||
|
||||
|
@ -48,19 +48,19 @@ irq_vec:
|
|||
|
||||
#ifdef ENABLE_QREGS
|
||||
|
||||
setq q2, x1
|
||||
setq q3, x2
|
||||
picorv32_setq_insn(q2, x1)
|
||||
picorv32_setq_insn(q3, x2)
|
||||
|
||||
lui x1, %hi(irq_regs)
|
||||
addi x1, x1, %lo(irq_regs)
|
||||
|
||||
getq x2, q0
|
||||
picorv32_getq_insn(x2, q0)
|
||||
sw x2, 0*4(x1)
|
||||
|
||||
getq x2, q2
|
||||
picorv32_getq_insn(x2, q2)
|
||||
sw x2, 1*4(x1)
|
||||
|
||||
getq x2, q3
|
||||
picorv32_getq_insn(x2, q3)
|
||||
sw x2, 2*4(x1)
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
|
@ -180,7 +180,7 @@ irq_vec:
|
|||
|
||||
// arg1 = interrupt type
|
||||
#ifdef ENABLE_QREGS
|
||||
getq a1, q1
|
||||
picorv32_getq_insn(a1, q1)
|
||||
#else
|
||||
addi a1, tp, 0
|
||||
#endif
|
||||
|
@ -196,13 +196,13 @@ irq_vec:
|
|||
addi x1, a0, 0
|
||||
|
||||
lw x2, 0*4(x1)
|
||||
setq q0, x2
|
||||
picorv32_setq_insn(q0, x2)
|
||||
|
||||
lw x2, 1*4(x1)
|
||||
setq q1, x2
|
||||
picorv32_setq_insn(q1, x2)
|
||||
|
||||
lw x2, 2*4(x1)
|
||||
setq q2, x2
|
||||
picorv32_setq_insn(q2, x2)
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
lw x5, 5*4(x1)
|
||||
|
@ -252,8 +252,8 @@ irq_vec:
|
|||
lw x31, 31*4(x1)
|
||||
#endif
|
||||
|
||||
getq x1, q1
|
||||
getq x2, q2
|
||||
picorv32_getq_insn(x1, q1)
|
||||
picorv32_getq_insn(x2, q2)
|
||||
|
||||
#else // ENABLE_QREGS
|
||||
|
||||
|
@ -319,7 +319,7 @@ irq_vec:
|
|||
|
||||
#endif // ENABLE_QREGS
|
||||
|
||||
retirq
|
||||
picorv32_retirq_insn()
|
||||
|
||||
#ifndef ENABLE_QREGS
|
||||
.balign 0x200
|
||||
|
@ -378,7 +378,7 @@ start:
|
|||
# define TEST(n) \
|
||||
.global n; \
|
||||
addi x1, zero, 1000; \
|
||||
timer zero, x1; \
|
||||
picorv32_timer_insn(zero, x1); \
|
||||
jal zero,n; \
|
||||
.global n ## _ret; \
|
||||
n ## _ret:
|
||||
|
|
|
@ -22,7 +22,7 @@ firmware32.hex: firmware.elf start.elf hex8tohex32.py
|
|||
rm -f start.tmp firmware.tmp
|
||||
|
||||
firmware.elf: firmware.o syscalls.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ -T ../../firmware/riscv.ld $(LDLIBS)
|
||||
chmod -x firmware.elf
|
||||
|
||||
start.elf: start.S start.ld
|
||||
|
|
|
@ -22,10 +22,10 @@ RVTEST_CODE_BEGIN
|
|||
TEST_RR_OP( 4, div, -3, 20, -6 );
|
||||
TEST_RR_OP( 5, div, 3, -20, -6 );
|
||||
|
||||
TEST_RR_OP( 6, div, -1<<63, -1<<63, 1 );
|
||||
TEST_RR_OP( 7, div, -1<<63, -1<<63, -1 );
|
||||
TEST_RR_OP( 6, div, -1<<31, -1<<31, 1 );
|
||||
TEST_RR_OP( 7, div, -1<<31, -1<<31, -1 );
|
||||
|
||||
TEST_RR_OP( 8, div, -1, -1<<63, 0 );
|
||||
TEST_RR_OP( 8, div, -1, -1<<31, 0 );
|
||||
TEST_RR_OP( 9, div, -1, 1, 0 );
|
||||
TEST_RR_OP(10, div, -1, 0, 0 );
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ RVTEST_CODE_BEGIN
|
|||
TEST_RR_OP( 4, rem, 2, 20, -6 );
|
||||
TEST_RR_OP( 5, rem, -2, -20, -6 );
|
||||
|
||||
TEST_RR_OP( 6, rem, 0, -1<<63, 1 );
|
||||
TEST_RR_OP( 7, rem, 0, -1<<63, -1 );
|
||||
TEST_RR_OP( 6, rem, 0, -1<<31, 1 );
|
||||
TEST_RR_OP( 7, rem, 0, -1<<31, -1 );
|
||||
|
||||
TEST_RR_OP( 8, rem, -1<<63, -1<<63, 0 );
|
||||
TEST_RR_OP( 8, rem, -1<<31, -1<<31, 0 );
|
||||
TEST_RR_OP( 9, rem, 1, 1, 0 );
|
||||
TEST_RR_OP(10, rem, 0, 0, 0 );
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ RVTEST_CODE_BEGIN
|
|||
TEST_RR_OP( 4, remu, 20, 20, -6 );
|
||||
TEST_RR_OP( 5, remu, -20, -20, -6 );
|
||||
|
||||
TEST_RR_OP( 6, remu, 0, -1<<63, 1 );
|
||||
TEST_RR_OP( 7, remu, -1<<63, -1<<63, -1 );
|
||||
TEST_RR_OP( 6, remu, 0, -1<<31, 1 );
|
||||
TEST_RR_OP( 7, remu, -1<<31, -1<<31, -1 );
|
||||
|
||||
TEST_RR_OP( 8, remu, -1<<63, -1<<63, 0 );
|
||||
TEST_RR_OP( 8, remu, -1<<31, -1<<31, 0 );
|
||||
TEST_RR_OP( 9, remu, 1, 1, 0 );
|
||||
TEST_RR_OP(10, remu, 0, 0, 0 );
|
||||
|
||||
|
|
|
@ -19,13 +19,7 @@ RVTEST_CODE_BEGIN
|
|||
|
||||
TEST_ST_OP( 2, lb, sb, 0xffffffaa, 0, tdat );
|
||||
TEST_ST_OP( 3, lb, sb, 0x00000000, 1, tdat );
|
||||
#ifdef __RISCVEL
|
||||
TEST_ST_OP( 4, lh, sb, 0xffffefa0, 2, tdat );
|
||||
#elif defined(__RISCVEB)
|
||||
#else
|
||||
TEST_ST_OP( 4, lh, sb, 0xffffa0ef, 2, tdat );
|
||||
#error unknown endianness!
|
||||
#endif
|
||||
TEST_ST_OP( 5, lb, sb, 0x0000000a, 3, tdat );
|
||||
|
||||
# Test with negative offset
|
||||
|
|
|
@ -19,13 +19,7 @@ RVTEST_CODE_BEGIN
|
|||
|
||||
TEST_ST_OP( 2, lh, sh, 0x000000aa, 0, tdat );
|
||||
TEST_ST_OP( 3, lh, sh, 0xffffaa00, 2, tdat );
|
||||
#ifdef __RISCVEL
|
||||
TEST_ST_OP( 4, lw, sh, 0xbeef0aa0, 4, tdat );
|
||||
#elif defined(__RISCVEB)
|
||||
#else
|
||||
TEST_ST_OP( 4, lw, sh, 0x0aa0beef, 4, tdat );
|
||||
#error unknown endianness!
|
||||
#endif
|
||||
TEST_ST_OP( 5, lh, sh, 0xffffa00a, 6, tdat );
|
||||
|
||||
# Test with negative offset
|
||||
|
|
Loading…
Reference in New Issue