rework structure
This commit is contained in:
1
bare-metal-bsp/env/.gitignore
vendored
Normal file
1
bare-metal-bsp/env/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*.o
|
72
bare-metal-bsp/env/common-clang.mk
vendored
Normal file
72
bare-metal-bsp/env/common-clang.mk
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# See LICENSE for license details.
|
||||
|
||||
ifndef _SIFIVE_MK_COMMON
|
||||
_SIFIVE_MK_COMMON := # defined
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET)
|
||||
|
||||
include $(BSP_BASE)/libwrap/libwrap.mk
|
||||
|
||||
ENV_DIR = $(BSP_BASE)/env
|
||||
PLATFORM_DIR = $(ENV_DIR)/$(BOARD)
|
||||
|
||||
ASM_SRCS += $(ENV_DIR)/start.S
|
||||
ASM_SRCS += $(ENV_DIR)/entry.S
|
||||
C_SRCS += $(PLATFORM_DIR)/init.c
|
||||
|
||||
LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds
|
||||
|
||||
INCLUDES += -I$(BSP_BASE)/include
|
||||
INCLUDES += -I$(BSP_BASE)/drivers/
|
||||
INCLUDES += -I$(ENV_DIR)
|
||||
INCLUDES += -I$(PLATFORM_DIR)
|
||||
|
||||
TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/
|
||||
|
||||
LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles
|
||||
LDFLAGS += -L$(ENV_DIR) --specs=nano.specs
|
||||
|
||||
ASM_OBJS := $(ASM_SRCS:.S=.o)
|
||||
C_OBJS := $(C_SRCS:.c=.o)
|
||||
CXX_OBJS := $(CXX_SRCS:.cpp=.o)
|
||||
|
||||
LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS)
|
||||
LINK_DEPS += $(LINKER_SCRIPT)
|
||||
|
||||
CLEAN_OBJS += $(TARGET) $(LINK_OBJS)
|
||||
|
||||
CFLAGS += -march=$(RISCV_ARCH)
|
||||
CFLAGS += -mabi=$(RISCV_ABI)
|
||||
CFLAGS += -mcmodel=medany
|
||||
|
||||
TRIPLET?=riscv32
|
||||
CXX=$(LLVM_TOOL_DIR)clang++ --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include
|
||||
CC=$(LLVM_TOOL_DIR)clang --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include
|
||||
LD=$(TOOL_DIR)$(TRIPLET)-gcc
|
||||
AR=$(TOOL_DIR)$(TRIPLET)-ar
|
||||
OBJDUMP := $(TOOL_DIR)/$(TRIPLET)-objdump
|
||||
|
||||
|
||||
$(TARGET): $(LINK_OBJS) $(LINK_DEPS)
|
||||
$(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@
|
||||
$(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis
|
||||
|
||||
$(ASM_OBJS): %.o: %.S $(HEADERS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(C_OBJS): %.o: %.c $(HEADERS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $<
|
||||
|
||||
$(CXX_OBJS): %.o: %.cpp $(HEADERS)
|
||||
$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARGET) $(LINK_OBJS)
|
||||
|
||||
.PHONY: clean-all
|
||||
clean-all:
|
||||
rm -f $(CLEAN_OBJS) $(LIBWRAP)
|
||||
|
||||
endif
|
74
bare-metal-bsp/env/common-gcc.mk
vendored
Normal file
74
bare-metal-bsp/env/common-gcc.mk
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
ifndef _MK_COMMON
|
||||
_MK_COMMON := # defined
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET)
|
||||
|
||||
include $(BSP_BASE)/libwrap/libwrap.mk
|
||||
|
||||
BOARD?=iss
|
||||
ENV_DIR = $(BSP_BASE)/env
|
||||
PLATFORM_DIR = $(ENV_DIR)/$(BOARD)
|
||||
|
||||
ASM_SRCS += $(ENV_DIR)/start.S
|
||||
ASM_SRCS += $(ENV_DIR)/entry.S
|
||||
C_SRCS += $(PLATFORM_DIR)/init.c
|
||||
|
||||
LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds
|
||||
|
||||
INCLUDES += -I$(BSP_BASE)/include
|
||||
INCLUDES += -I$(BSP_BASE)/drivers/
|
||||
INCLUDES += -I$(ENV_DIR)
|
||||
INCLUDES += -I$(PLATFORM_DIR)
|
||||
|
||||
TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/
|
||||
|
||||
LDFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI)
|
||||
LDFLAGS += -T $(LINKER_SCRIPT) -Wl,-Map=$(TARGET).map -nostartfiles
|
||||
LDFLAGS += -L$(ENV_DIR)
|
||||
# --specs=nano.specs
|
||||
|
||||
ASM_OBJS := $(ASM_SRCS:.S=.o)
|
||||
C_OBJS := $(C_SRCS:.c=.o)
|
||||
CXX_OBJS := $(CXX_SRCS:.cpp=.o)
|
||||
|
||||
LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS)
|
||||
LINK_DEPS += $(LINKER_SCRIPT)
|
||||
|
||||
CLEAN_OBJS += $(TARGET) $(LINK_OBJS)
|
||||
|
||||
GCCVERSION = $(shell $(CC) --version | grep gcc | awk '{print($NF);}')
|
||||
ifeq ($(GCCVERSION),9.2)
|
||||
CFLAGS += -march=$(RISCV_ARCH)
|
||||
else
|
||||
CFLAGS += -march=$(RISCV_ARCH)_zicsr_zifencei
|
||||
endif
|
||||
CFLAGS += -mabi=$(RISCV_ABI)
|
||||
CFLAGS += -mcmodel=medany
|
||||
|
||||
TRIPLET?=riscv64-unknown-elf
|
||||
CXX=$(TOOL_DIR)$(TRIPLET)-c++
|
||||
CC=$(TOOL_DIR)$(TRIPLET)-gcc
|
||||
LD=$(TOOL_DIR)$(TRIPLET)-gcc
|
||||
AR=$(TOOL_DIR)$(TRIPLET)-ar
|
||||
OBJDUMP := $(TOOL_DIR)$(TRIPLET)-objdump
|
||||
|
||||
|
||||
$(TARGET): $(LINK_OBJS) $(LINK_DEPS)
|
||||
$(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@
|
||||
$(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis
|
||||
|
||||
$(ASM_OBJS): %.o: %.S $(HEADERS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(C_OBJS): %.o: %.c $(HEADERS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $<
|
||||
|
||||
$(CXX_OBJS): %.o: %.cpp $(HEADERS)
|
||||
$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(CLEAN_OBJS) $(LIBWRAP)
|
||||
|
||||
endif
|
1313
bare-metal-bsp/env/encoding.h
vendored
Normal file
1313
bare-metal-bsp/env/encoding.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
99
bare-metal-bsp/env/entry.S
vendored
Normal file
99
bare-metal-bsp/env/entry.S
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
// See LICENSE for license details
|
||||
|
||||
#ifndef ENTRY_S
|
||||
#define ENTRY_S
|
||||
|
||||
#include "encoding.h"
|
||||
#include "rtl/bits.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 2
|
||||
.global trap_entry
|
||||
trap_entry:
|
||||
addi sp, sp, -32*REGBYTES
|
||||
|
||||
STORE x1, 1*REGBYTES(sp)
|
||||
STORE x2, 2*REGBYTES(sp)
|
||||
STORE x3, 3*REGBYTES(sp)
|
||||
STORE x4, 4*REGBYTES(sp)
|
||||
STORE x5, 5*REGBYTES(sp)
|
||||
STORE x6, 6*REGBYTES(sp)
|
||||
STORE x7, 7*REGBYTES(sp)
|
||||
STORE x8, 8*REGBYTES(sp)
|
||||
STORE x9, 9*REGBYTES(sp)
|
||||
STORE x10, 10*REGBYTES(sp)
|
||||
STORE x11, 11*REGBYTES(sp)
|
||||
STORE x12, 12*REGBYTES(sp)
|
||||
STORE x13, 13*REGBYTES(sp)
|
||||
STORE x14, 14*REGBYTES(sp)
|
||||
STORE x15, 15*REGBYTES(sp)
|
||||
#ifndef __riscv_abi_rve
|
||||
STORE x16, 16*REGBYTES(sp)
|
||||
STORE x17, 17*REGBYTES(sp)
|
||||
STORE x18, 18*REGBYTES(sp)
|
||||
STORE x19, 19*REGBYTES(sp)
|
||||
STORE x20, 20*REGBYTES(sp)
|
||||
STORE x21, 21*REGBYTES(sp)
|
||||
STORE x22, 22*REGBYTES(sp)
|
||||
STORE x23, 23*REGBYTES(sp)
|
||||
STORE x24, 24*REGBYTES(sp)
|
||||
STORE x25, 25*REGBYTES(sp)
|
||||
STORE x26, 26*REGBYTES(sp)
|
||||
STORE x27, 27*REGBYTES(sp)
|
||||
STORE x28, 28*REGBYTES(sp)
|
||||
STORE x29, 29*REGBYTES(sp)
|
||||
STORE x30, 30*REGBYTES(sp)
|
||||
STORE x31, 31*REGBYTES(sp)
|
||||
#endif
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
call handle_trap
|
||||
csrw mepc, a0
|
||||
|
||||
# Remain in M-mode after mret
|
||||
li t0, MSTATUS_MPP
|
||||
csrs mstatus, t0
|
||||
|
||||
LOAD x1, 1*REGBYTES(sp)
|
||||
LOAD x2, 2*REGBYTES(sp)
|
||||
LOAD x3, 3*REGBYTES(sp)
|
||||
LOAD x4, 4*REGBYTES(sp)
|
||||
LOAD x5, 5*REGBYTES(sp)
|
||||
LOAD x6, 6*REGBYTES(sp)
|
||||
LOAD x7, 7*REGBYTES(sp)
|
||||
LOAD x8, 8*REGBYTES(sp)
|
||||
LOAD x9, 9*REGBYTES(sp)
|
||||
LOAD x10, 10*REGBYTES(sp)
|
||||
LOAD x11, 11*REGBYTES(sp)
|
||||
LOAD x12, 12*REGBYTES(sp)
|
||||
LOAD x13, 13*REGBYTES(sp)
|
||||
LOAD x14, 14*REGBYTES(sp)
|
||||
LOAD x15, 15*REGBYTES(sp)
|
||||
#ifndef __riscv_abi_rve
|
||||
LOAD x16, 16*REGBYTES(sp)
|
||||
LOAD x17, 17*REGBYTES(sp)
|
||||
LOAD x18, 18*REGBYTES(sp)
|
||||
LOAD x19, 19*REGBYTES(sp)
|
||||
LOAD x20, 20*REGBYTES(sp)
|
||||
LOAD x21, 21*REGBYTES(sp)
|
||||
LOAD x22, 22*REGBYTES(sp)
|
||||
LOAD x23, 23*REGBYTES(sp)
|
||||
LOAD x24, 24*REGBYTES(sp)
|
||||
LOAD x25, 25*REGBYTES(sp)
|
||||
LOAD x26, 26*REGBYTES(sp)
|
||||
LOAD x27, 27*REGBYTES(sp)
|
||||
LOAD x28, 28*REGBYTES(sp)
|
||||
LOAD x29, 29*REGBYTES(sp)
|
||||
LOAD x30, 30*REGBYTES(sp)
|
||||
LOAD x31, 31*REGBYTES(sp)
|
||||
#endif
|
||||
addi sp, sp, 32*REGBYTES
|
||||
mret
|
||||
|
||||
.weak handle_trap
|
||||
handle_trap:
|
||||
1:
|
||||
j 1b
|
||||
|
||||
#endif
|
1
bare-metal-bsp/env/iss/.gitignore
vendored
Normal file
1
bare-metal-bsp/env/iss/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*.o
|
107
bare-metal-bsp/env/iss/init.c
vendored
Normal file
107
bare-metal-bsp/env/iss/init.c
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "encoding.h"
|
||||
|
||||
extern int main(int argc, char** argv);
|
||||
extern void trap_entry();
|
||||
|
||||
static unsigned long mtime_lo(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
__asm volatile("rdtime %0":"=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if __riscv_xlen==32
|
||||
|
||||
static uint32_t mtime_hi(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
__asm volatile("rdtimeh %0":"=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t get_timer_value()
|
||||
{
|
||||
while (1) {
|
||||
uint32_t hi = mtime_hi();
|
||||
uint32_t lo = mtime_lo();
|
||||
if (hi == mtime_hi())
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
}
|
||||
|
||||
#elif __riscv_xlen==64
|
||||
|
||||
uint64_t get_timer_value()
|
||||
{
|
||||
return mtime_lo();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
unsigned long get_timer_freq()
|
||||
{
|
||||
return 32768;
|
||||
}
|
||||
|
||||
unsigned long get_cpu_freq()
|
||||
{
|
||||
return 10000000;
|
||||
}
|
||||
|
||||
void init_pll(void){
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PLIC
|
||||
extern void handle_m_ext_interrupt();
|
||||
#endif
|
||||
|
||||
#ifdef USE_M_TIME
|
||||
extern void handle_m_time_interrupt();
|
||||
#endif
|
||||
|
||||
uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
|
||||
{
|
||||
if (0){
|
||||
#ifdef USE_PLIC
|
||||
// External Machine-Level interrupt from PLIC
|
||||
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
|
||||
handle_m_ext_interrupt();
|
||||
#endif
|
||||
#ifdef USE_M_TIME
|
||||
// External Machine-Level interrupt from PLIC
|
||||
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
|
||||
handle_m_time_interrupt();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
write(1, "trap\n", 5);
|
||||
_exit(1 + mcause);
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
|
||||
void _init()
|
||||
{
|
||||
|
||||
#ifndef NO_INIT
|
||||
init_pll();
|
||||
printf("core freq at %d Hz\n", get_cpu_freq());
|
||||
write_csr(mtvec, &trap_entry);
|
||||
if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present
|
||||
write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping
|
||||
write_csr(fcsr, 0); // initialize rounding mode, undefined at reset
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void _fini()
|
||||
{
|
||||
}
|
174
bare-metal-bsp/env/iss/link.lds
vendored
Normal file
174
bare-metal-bsp/env/iss/link.lds
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
ENTRY( _start )
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rxai!w) : ORIGIN = 0x00000020, LENGTH = 1M
|
||||
ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
flash PT_LOAD;
|
||||
ram_init PT_LOAD;
|
||||
ram PT_NULL;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||
|
||||
.init ORIGIN(flash) :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.unlikely.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text .text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} >flash AT>flash :flash
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rdata)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
} >flash AT>flash :flash
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >flash AT>flash :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 :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 :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 :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 :flash
|
||||
|
||||
.lalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _data_lma = . );
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.dalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _data = . );
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.data :
|
||||
{
|
||||
__DATA_BEGIN__ = .;
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.srodata :
|
||||
{
|
||||
PROVIDE( _gp = . + 0x800 );
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.sdata :
|
||||
{
|
||||
__SDATA_BEGIN__ = .;
|
||||
*(.sdata .sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
. = 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 :ram
|
||||
|
||||
. = ALIGN(8);
|
||||
__BSS_END__ = .;
|
||||
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
|
||||
PROVIDE( _end = . );
|
||||
PROVIDE( end = . );
|
||||
|
||||
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||
{
|
||||
PROVIDE( _heap_end = . );
|
||||
. = __stack_size;
|
||||
PROVIDE( _sp = . );
|
||||
} >ram AT>ram :ram
|
||||
|
||||
PROVIDE( tohost = 0xfffffff0 );
|
||||
PROVIDE( fromhost = 0xfffffff8 );
|
||||
}
|
30
bare-metal-bsp/env/iss/platform.h
vendored
Normal file
30
bare-metal-bsp/env/iss/platform.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
#ifndef _ISS_PLATFORM_H
|
||||
#define _ISS_PLATFORM_H
|
||||
|
||||
// Some things missing from the official encoding.h
|
||||
#define MCAUSE_INT 0x80000000
|
||||
#define MCAUSE_CAUSE 0x7FFFFFFF
|
||||
|
||||
#include "rtl/const.h"
|
||||
/****************************************************************************
|
||||
* Platform definitions
|
||||
*****************************************************************************/
|
||||
|
||||
#define MEM_BASE_ADDR _AC(0x00000000,UL)
|
||||
|
||||
// Helper functions
|
||||
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
|
||||
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
|
||||
|
||||
// Misc
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void init_pll(void);
|
||||
unsigned long get_cpu_freq(void);
|
||||
unsigned long get_timer_freq(void);
|
||||
uint64_t get_timer_value(void);
|
||||
|
||||
#endif /* _ISS_PLATFORM_H */
|
1
bare-metal-bsp/env/rtl/.gitignore
vendored
Normal file
1
bare-metal-bsp/env/rtl/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*.o
|
107
bare-metal-bsp/env/rtl/init.c
vendored
Normal file
107
bare-metal-bsp/env/rtl/init.c
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "encoding.h"
|
||||
|
||||
extern int main(int argc, char** argv);
|
||||
extern void trap_entry();
|
||||
|
||||
static unsigned long mtime_lo(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
__asm volatile("rdtime %0":"=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if __riscv_xlen==32
|
||||
|
||||
static uint32_t mtime_hi(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
__asm volatile("rdtimeh %0":"=r"(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t get_timer_value()
|
||||
{
|
||||
while (1) {
|
||||
uint32_t hi = mtime_hi();
|
||||
uint32_t lo = mtime_lo();
|
||||
if (hi == mtime_hi())
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
}
|
||||
|
||||
#elif __riscv_xlen==64
|
||||
|
||||
uint64_t get_timer_value()
|
||||
{
|
||||
return mtime_lo();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
unsigned long get_timer_freq()
|
||||
{
|
||||
return 32768;
|
||||
}
|
||||
|
||||
unsigned long get_cpu_freq()
|
||||
{
|
||||
return 10000000;
|
||||
}
|
||||
|
||||
void init_pll(void){
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PLIC
|
||||
extern void handle_m_ext_interrupt();
|
||||
#endif
|
||||
|
||||
#ifdef USE_M_TIME
|
||||
extern void handle_m_time_interrupt();
|
||||
#endif
|
||||
|
||||
uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
|
||||
{
|
||||
if (0){
|
||||
#ifdef USE_PLIC
|
||||
// External Machine-Level interrupt from PLIC
|
||||
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
|
||||
handle_m_ext_interrupt();
|
||||
#endif
|
||||
#ifdef USE_M_TIME
|
||||
// External Machine-Level interrupt from PLIC
|
||||
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
|
||||
handle_m_time_interrupt();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
write(1, "trap\n", 5);
|
||||
_exit(1 + mcause);
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
|
||||
void _init()
|
||||
{
|
||||
|
||||
#ifndef NO_INIT
|
||||
init_pll();
|
||||
printf("core freq at %d Hz\n", get_cpu_freq());
|
||||
write_csr(mtvec, &trap_entry);
|
||||
if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present
|
||||
write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping
|
||||
write_csr(fcsr, 0); // initialize rounding mode, undefined at reset
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void _fini()
|
||||
{
|
||||
}
|
170
bare-metal-bsp/env/rtl/link.lds
vendored
Normal file
170
bare-metal-bsp/env/rtl/link.lds
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
ENTRY( _start )
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M
|
||||
ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
flash PT_LOAD;
|
||||
ram_init PT_LOAD;
|
||||
ram PT_NULL;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||
|
||||
.init ORIGIN(flash) :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.unlikely.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text .text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} >flash AT>flash :flash
|
||||
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rdata)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
} >flash AT>flash :flash
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >flash AT>flash :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 :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 :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 :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 :flash
|
||||
|
||||
.lalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _data_lma = . );
|
||||
} >flash AT>flash :flash
|
||||
|
||||
.dalign :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE( _data = . );
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.srodata :
|
||||
{
|
||||
PROVIDE( _gp = . + 0x800 );
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata .sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
} >ram AT>flash :ram_init
|
||||
|
||||
. = 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 :ram
|
||||
|
||||
. = ALIGN(8);
|
||||
PROVIDE( _end = . );
|
||||
PROVIDE( end = . );
|
||||
|
||||
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||
{
|
||||
PROVIDE( _heap_end = . );
|
||||
. = __stack_size;
|
||||
PROVIDE( _sp = . );
|
||||
} >ram AT>ram :ram
|
||||
|
||||
PROVIDE( tohost = 0x00018000 );
|
||||
PROVIDE( fromhost = 0xfffffff8 );
|
||||
}
|
30
bare-metal-bsp/env/rtl/platform.h
vendored
Normal file
30
bare-metal-bsp/env/rtl/platform.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
#ifndef _ISS_PLATFORM_H
|
||||
#define _ISS_PLATFORM_H
|
||||
|
||||
// Some things missing from the official encoding.h
|
||||
#define MCAUSE_INT 0x80000000
|
||||
#define MCAUSE_CAUSE 0x7FFFFFFF
|
||||
|
||||
#include "rtl/const.h"
|
||||
/****************************************************************************
|
||||
* Platform definitions
|
||||
*****************************************************************************/
|
||||
|
||||
#define MEM_BASE_ADDR _AC(0x00000000,UL)
|
||||
|
||||
// Helper functions
|
||||
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
|
||||
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
|
||||
|
||||
// Misc
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void init_pll(void);
|
||||
unsigned long get_cpu_freq(void);
|
||||
unsigned long get_timer_freq(void);
|
||||
uint64_t get_timer_value(void);
|
||||
|
||||
#endif /* _ISS_PLATFORM_H */
|
58
bare-metal-bsp/env/start.S
vendored
Normal file
58
bare-metal-bsp/env/start.S
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
.section .init
|
||||
.globl _start
|
||||
.type _start,@function
|
||||
|
||||
_start:
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
la sp, _sp
|
||||
|
||||
/* 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 global constructors */
|
||||
#ifdef HAVE_INIT_FINI
|
||||
la a0, __libc_fini_array
|
||||
call atexit
|
||||
call __libc_init_array
|
||||
#endif
|
||||
#ifndef __riscv_float_abi_soft
|
||||
/* Enable FPU */
|
||||
li t0, MSTATUS_FS
|
||||
csrs mstatus, t0
|
||||
csrr t1, mstatus
|
||||
and t1, t1, t0
|
||||
beqz t1, 1f
|
||||
fssr x0
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* argc = argv = 0 */
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
call main
|
||||
tail _exit
|
Reference in New Issue
Block a user