rework structure

This commit is contained in:
2023-08-20 15:00:51 +02:00
parent 4c2208c1ac
commit 314ceeb072
381 changed files with 10697 additions and 14653 deletions

62
hifive1-vp/hello/bsp/env/common.mk vendored Normal file
View File

@ -0,0 +1,62 @@
# See LICENSE for license details.
ifndef _SIFIVE_MK_COMMON
_SIFIVE_MK_COMMON := # defined
.PHONY: all
all: $(TARGET)
include $(BSP_BASE)/libwrap/libwrap.mk
BOARD ?= freedom-e300-hifive1
ENV_DIR = $(BSP_BASE)/env
PLATFORM_DIR = $(ENV_DIR)/$(BOARD)
#TARGET_FLAVOR := -march=rv32imac -mabi=ilp32 -mcmodel=medany -msmall-data-limit=8 -x assembler-with-cpp
TARGET_FLAVOR := -march=rv32i -mabi=ilp32
ASM_SRCS += $(ENV_DIR)/start.S
ASM_SRCS += $(ENV_DIR)/entry.S
C_SRCS += $(PLATFORM_DIR)/init.c
LINKER_SCRIPT := $(PLATFORM_DIR)/link.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
CC := $(TOOL_DIR)/riscv64-unknown-elf-gcc ${TARGET_FLAVOR}
AR := $(TOOL_DIR)/riscv64-unknown-elf-ar
OBJDUMP := $(TOOL_DIR)/riscv64-unknown-elf-objdump
LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles
LDFLAGS += -L$(ENV_DIR)
ASM_OBJS := $(ASM_SRCS:.S=.o)
C_OBJS := $(C_SRCS:.c=.o)
LINK_OBJS += $(ASM_OBJS) $(C_OBJS)
LINK_DEPS += $(LINKER_SCRIPT)
CLEAN_OBJS += $(TARGET) $(LINK_OBJS)
CFLAGS += -g
$(TARGET): $(LINK_OBJS) $(LINK_DEPS)
$(CC) $(CFLAGS) $(INCLUDES) $(LINK_OBJS) -o $@ $(LDFLAGS)
$(OBJDUMP) -d $(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 $@ $<
.PHONY: clean
clean:
rm -f $(CLEAN_OBJS)
endif # _SIFIVE_MK_COMMON

1313
hifive1-vp/hello/bsp/env/encoding.h vendored Normal file

File diff suppressed because it is too large Load Diff

97
hifive1-vp/hello/bsp/env/entry.S vendored Normal file
View File

@ -0,0 +1,97 @@
// See LICENSE for license details
#ifndef ENTRY_S
#define ENTRY_S
#include "encoding.h"
#include "sifive/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)
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)
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)
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)
addi sp, sp, 32*REGBYTES
mret
.weak handle_trap
handle_trap:
1:
j 1b
#endif

View File

@ -0,0 +1,87 @@
//See LICENSE for license details.
#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 get_cpu_freq()
{
return 65000000;
}
unsigned long get_timer_freq()
{
return get_cpu_freq();
}
uint64_t get_timer_value()
{
#if __riscv_xlen == 32
while (1) {
uint32_t hi = read_csr(mcycleh);
uint32_t lo = read_csr(mcycle);
if (hi == read_csr(mcycleh))
return ((uint64_t)hi << 32) | lo;
}
#else
return read_csr(mcycle);
#endif
}
static void uart_init(size_t baud_rate)
{
GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK;
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1;
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
}
#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, "Unhandled Trap:\n", 16);
_exit(1 + mcause);
}
return epc;
}
void _init()
{
#ifndef NO_INIT
uart_init(115200);
printf("core freq at %d Hz\n", get_cpu_freq());
write_csr(mtvec, &trap_entry);
#endif
}
void _fini()
{
}

View File

@ -0,0 +1,167 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K
}
PHDRS
{
flash PT_LOAD;
ram_init PT_LOAD;
ram PT_NULL;
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
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
}

View File

@ -0,0 +1,30 @@
adapter_khz 10000
#source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
interface ftdi
ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
ftdi_vid_pid 0x15ba 0x002a
ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800
#
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
flash bank my_first_flash fespi 0x20000000 0 0 0 $_TARGETNAME
init
#reset
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
}
halt
#flash protect 0 64 last off

View File

@ -0,0 +1,125 @@
// See LICENSE for license details.
#ifndef _SIFIVE_PLATFORM_H
#define _SIFIVE_PLATFORM_H
// Some things missing from the official encoding.h
#define MCAUSE_INT 0x80000000
#define MCAUSE_CAUSE 0x7FFFFFFF
#include "sifive/const.h"
#include "sifive/devices/aon.h"
#include "sifive/devices/clint.h"
#include "sifive/devices/gpio.h"
#include "sifive/devices/plic.h"
#include "sifive/devices/pwm.h"
#include "sifive/devices/spi.h"
#include "sifive/devices/uart.h"
/****************************************************************************
* Platform definitions
*****************************************************************************/
#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL)
#define CLINT_BASE_ADDR _AC(0x02000000,UL)
#define PLIC_BASE_ADDR _AC(0x0C000000,UL)
#define AON_BASE_ADDR _AC(0x10000000,UL)
#define GPIO_BASE_ADDR _AC(0x10012000,UL)
#define UART0_BASE_ADDR _AC(0x10013000,UL)
#define SPI0_BASE_ADDR _AC(0x10014000,UL)
#define PWM0_BASE_ADDR _AC(0x10015000,UL)
#define UART1_BASE_ADDR _AC(0x10023000,UL)
#define SPI1_BASE_ADDR _AC(0x10024000,UL)
#define PWM1_BASE_ADDR _AC(0x10025000,UL)
#define SPI2_BASE_ADDR _AC(0x10034000,UL)
#define PWM2_BASE_ADDR _AC(0x10035000,UL)
#define SPI0_MMAP_ADDR _AC(0x20000000,UL)
#define MEM_BASE_ADDR _AC(0x80000000,UL)
// IOF Mappings
#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
#define SPI11_NUM_SS (4)
#define IOF_SPI1_SS0 (2u)
#define IOF_SPI1_SS1 (8u)
#define IOF_SPI1_SS2 (9u)
#define IOF_SPI1_SS3 (10u)
#define IOF_SPI1_MOSI (3u)
#define IOF_SPI1_MISO (4u)
#define IOF_SPI1_SCK (5u)
#define IOF_SPI1_DQ0 (3u)
#define IOF_SPI1_DQ1 (4u)
#define IOF_SPI1_DQ2 (6u)
#define IOF_SPI1_DQ3 (7u)
#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
#define SPI2_NUM_SS (1)
#define IOF_SPI2_SS0 (26u)
#define IOF_SPI2_MOSI (27u)
#define IOF_SPI2_MISO (28u)
#define IOF_SPI2_SCK (29u)
#define IOF_SPI2_DQ0 (27u)
#define IOF_SPI2_DQ1 (28u)
#define IOF_SPI2_DQ2 (30u)
#define IOF_SPI2_DQ3 (31u)
#define IOF0_UART0_MASK _AC(0x00030000, UL)
#define IOF_UART0_RX (16u)
#define IOF_UART0_TX (17u)
#define IOF0_UART1_MASK _AC(0x03000000, UL)
#define IOF_UART1_RX (24u)
#define IOF_UART1_TX (25u)
#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
#define IOF1_PWM1_MASK _AC(0x00780000, UL)
#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
// Interrupt Numbers
#define INT_RESERVED 0
#define INT_WDOGCMP 1
#define INT_RTCCMP 2
#define INT_UART0_BASE 3
#define INT_UART1_BASE 4
#define INT_SPI0_BASE 5
#define INT_SPI1_BASE 6
#define INT_SPI2_BASE 7
#define INT_GPIO_BASE 8
#define INT_PWM0_BASE 40
#define INT_PWM1_BASE 44
#define INT_PWM2_BASE 48
// Helper functions
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset)
#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset)
#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset)
#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset)
#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset)
#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset)
#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset)
#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset)
#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset)
#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset)
#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset)
#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset)
#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset)
#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset)
// Misc
#include <stdint.h>
#define NUM_GPIO 32
#define PLIC_NUM_INTERRUPTS 52
#define PLIC_NUM_PRIORITIES 7
#define HAS_BOARD_BUTTONS
#include "hifive1.h"
unsigned long get_timer_freq(void);
uint64_t get_timer_value(void);
#endif /* _SIFIVE_PLATFORM_H */

View File

@ -0,0 +1,238 @@
#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)
{
return *(volatile unsigned long *)(CLINT_BASE_ADDR + CLINT_MTIME);
}
#ifdef __riscv32
static uint32_t mtime_hi(void)
{
return *(volatile uint32_t *)(CLINT_BASE_ADDR + CLINT_MTIME + 4);
}
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;
}
}
#else /* __riscv32 */
uint64_t get_timer_value()
{
return mtime_lo();
}
#endif
unsigned long get_timer_freq()
{
return 32768;
}
static void use_hfrosc(int div, int trim)
{
// Make sure the HFROSC is running at its default setting
PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1));
while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ;
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1);
}
static void use_pll(int refsel, int bypass, int r, int f, int q)
{
// Ensure that we aren't running off the PLL before we mess with it.
if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) {
// Make sure the HFROSC is running at its default setting
use_hfrosc(4, 16);
}
// Set PLL Source to be HFXOSC if available.
uint32_t config_value = 0;
config_value |= PLL_REFSEL(refsel);
if (bypass) {
// Bypass
config_value |= PLL_BYPASS(1);
PRCI_REG(PRCI_PLLCFG) = config_value;
// If we don't have an HFXTAL, this doesn't really matter.
// Set our Final output divide to divide-by-1:
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
} else {
// In case we are executing from QSPI,
// (which is quite likely) we need to
// set the QSPI clock divider appropriately
// before boosting the clock frequency.
// Div = f_sck/2
SPI0_REG(SPI_REG_SCKDIV) = 8;
// Set DIV Settings for PLL
// Both HFROSC and HFXOSC are modeled as ideal
// 16MHz sources (assuming dividers are set properly for
// HFROSC).
// (Legal values of f_REF are 6-48MHz)
// Set DIVR to divide-by-2 to get 8MHz frequency
// (legal values of f_R are 6-12 MHz)
config_value |= PLL_BYPASS(1);
config_value |= PLL_R(r);
// Set DIVF to get 512Mhz frequncy
// There is an implied multiply-by-2, 16Mhz.
// So need to write 32-1
// (legal values of f_F are 384-768 MHz)
config_value |= PLL_F(f);
// Set DIVQ to divide-by-2 to get 256 MHz frequency
// (legal values of f_Q are 50-400Mhz)
config_value |= PLL_Q(q);
// Set our Final output divide to divide-by-1:
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
PRCI_REG(PRCI_PLLCFG) = config_value;
// Un-Bypass the PLL.
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
// Wait for PLL Lock
// Note that the Lock signal can be glitchy.
// Need to wait 100 us
// RTC is running at 32kHz.
// So wait 4 ticks of RTC.
uint32_t now = mtime_lo();
while (mtime_lo() - now < 4) ;
// Now it is safe to check for PLL Lock
while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ;
}
// Switch over to PLL Clock source
PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1);
}
static void use_default_clocks()
{
// Turn off the LFROSC
AON_REG(AON_LFROSC) &= ~ROSC_EN(1);
// Use HFROSC
use_hfrosc(4, 16);
}
static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n)
{
unsigned long start_mtime, delta_mtime;
unsigned long mtime_freq = get_timer_freq();
// Don't start measuruing until we see an mtime tick
unsigned long tmp = mtime_lo();
do {
start_mtime = mtime_lo();
} while (start_mtime == tmp);
unsigned long start_mcycle = read_csr(mcycle);
do {
delta_mtime = mtime_lo() - start_mtime;
} while (delta_mtime < n);
unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle;
return (delta_mcycle / delta_mtime) * mtime_freq
+ ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
}
unsigned long get_cpu_freq()
{
static uint32_t cpu_freq;
if (!cpu_freq) {
// warm up I$
measure_cpu_freq(1);
// measure for real
cpu_freq = measure_cpu_freq(10);
}
return cpu_freq;
}
static void uart_init(size_t baud_rate)
{
GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK;
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1;
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
}
#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
use_default_clocks();
use_pll(0, 0, 1, 31, 1);
uart_init(115200);
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()
{
}

View File

@ -0,0 +1,167 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K
}
PHDRS
{
flash PT_LOAD;
ram_init PT_LOAD;
ram PT_NULL;
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
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
}

View File

@ -0,0 +1,34 @@
adapter_khz 10000
interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
#Reset Stretcher logic on FE310 is ~1 second long
#This doesn't apply if you use
# ftdi_set_signal, but still good to document
#adapter_nsrst_delay 1500
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME
init
#reset -- This type of reset is not implemented yet
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
#Wait for the reset stretcher
#It will work without this, but
#will incur lots of delays for later commands.
sleep 1500
}
halt
#flash protect 0 64 last off

View File

@ -0,0 +1,133 @@
// See LICENSE for license details.
#ifndef _SIFIVE_PLATFORM_H
#define _SIFIVE_PLATFORM_H
// Some things missing from the official encoding.h
#define MCAUSE_INT 0x80000000
#define MCAUSE_CAUSE 0x7FFFFFFF
#include "sifive/const.h"
#include "sifive/devices/aon.h"
#include "sifive/devices/clint.h"
#include "sifive/devices/gpio.h"
#include "sifive/devices/otp.h"
#include "sifive/devices/plic.h"
#include "sifive/devices/prci.h"
#include "sifive/devices/pwm.h"
#include "sifive/devices/spi.h"
#include "sifive/devices/uart.h"
/****************************************************************************
* Platform definitions
*****************************************************************************/
// Memory map
#define MASKROM_BASE_ADDR _AC(0x00001000,UL)
#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL)
#define OTP_MMAP_ADDR _AC(0x00020000,UL)
#define CLINT_BASE_ADDR _AC(0x02000000,UL)
#define PLIC_BASE_ADDR _AC(0x0C000000,UL)
#define AON_BASE_ADDR _AC(0x10000000,UL)
#define PRCI_BASE_ADDR _AC(0x10008000,UL)
#define OTP_BASE_ADDR _AC(0x10010000,UL)
#define GPIO_BASE_ADDR _AC(0x10012000,UL)
#define UART0_BASE_ADDR _AC(0x10013000,UL)
#define SPI0_BASE_ADDR _AC(0x10014000,UL)
#define PWM0_BASE_ADDR _AC(0x10015000,UL)
#define UART1_BASE_ADDR _AC(0x10023000,UL)
#define SPI1_BASE_ADDR _AC(0x10024000,UL)
#define PWM1_BASE_ADDR _AC(0x10025000,UL)
#define SPI2_BASE_ADDR _AC(0x10034000,UL)
#define PWM2_BASE_ADDR _AC(0x10035000,UL)
#define SPI0_MMAP_ADDR _AC(0x20000000,UL)
#define MEM_BASE_ADDR _AC(0x80000000,UL)
// IOF masks
#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
#define SPI11_NUM_SS (4)
#define IOF_SPI1_SS0 (2u)
#define IOF_SPI1_SS1 (8u)
#define IOF_SPI1_SS2 (9u)
#define IOF_SPI1_SS3 (10u)
#define IOF_SPI1_MOSI (3u)
#define IOF_SPI1_MISO (4u)
#define IOF_SPI1_SCK (5u)
#define IOF_SPI1_DQ0 (3u)
#define IOF_SPI1_DQ1 (4u)
#define IOF_SPI1_DQ2 (6u)
#define IOF_SPI1_DQ3 (7u)
#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
#define SPI2_NUM_SS (1)
#define IOF_SPI2_SS0 (26u)
#define IOF_SPI2_MOSI (27u)
#define IOF_SPI2_MISO (28u)
#define IOF_SPI2_SCK (29u)
#define IOF_SPI2_DQ0 (27u)
#define IOF_SPI2_DQ1 (28u)
#define IOF_SPI2_DQ2 (30u)
#define IOF_SPI2_DQ3 (31u)
//#define IOF0_I2C_MASK _AC(0x00003000,UL)
#define IOF0_UART0_MASK _AC(0x00030000, UL)
#define IOF_UART0_RX (16u)
#define IOF_UART0_TX (17u)
#define IOF0_UART1_MASK _AC(0x03000000, UL)
#define IOF_UART1_RX (24u)
#define IOF_UART1_TX (25u)
#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
#define IOF1_PWM1_MASK _AC(0x00780000, UL)
#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
// Interrupt numbers
#define INT_RESERVED 0
#define INT_WDOGCMP 1
#define INT_RTCCMP 2
#define INT_UART0_BASE 3
#define INT_UART1_BASE 4
#define INT_SPI0_BASE 5
#define INT_SPI1_BASE 6
#define INT_SPI2_BASE 7
#define INT_GPIO_BASE 8
#define INT_PWM0_BASE 40
#define INT_PWM1_BASE 44
#define INT_PWM2_BASE 48
// Helper functions
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset)
#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset)
#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset)
#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset)
#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset)
#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset)
#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset)
#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset)
#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset)
#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset)
#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset)
#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset)
#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset)
#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset)
// Misc
#include <stdint.h>
#define NUM_GPIO 32
#define PLIC_NUM_INTERRUPTS 52
#define PLIC_NUM_PRIORITIES 7
#include "hifive1.h"
unsigned long get_cpu_freq(void);
unsigned long get_timer_freq(void);
uint64_t get_timer_value(void);
#endif /* _SIFIVE_PLATFORM_H */

79
hifive1-vp/hello/bsp/env/hifive1.h vendored Normal file
View File

@ -0,0 +1,79 @@
// See LICENSE for license details.
#ifndef _SIFIVE_HIFIVE1_H
#define _SIFIVE_HIFIVE1_H
#include <stdint.h>
/****************************************************************************
* GPIO Connections
*****************************************************************************/
// These are the GPIO bit offsets for the RGB LED on HiFive1 Board.
// These are also mapped to RGB LEDs on the Freedom E300 Arty
// FPGA
// Dev Kit.
#define RED_LED_OFFSET 22
#define GREEN_LED_OFFSET 19
#define BLUE_LED_OFFSET 21
// These are the GPIO bit offsets for the differen digital pins
// on the headers for both the HiFive1 Board and the Freedom E300 Arty FPGA Dev Kit.
#define PIN_0_OFFSET 16
#define PIN_1_OFFSET 17
#define PIN_2_OFFSET 18
#define PIN_3_OFFSET 19
#define PIN_4_OFFSET 20
#define PIN_5_OFFSET 21
#define PIN_6_OFFSET 22
#define PIN_7_OFFSET 23
#define PIN_8_OFFSET 0
#define PIN_9_OFFSET 1
#define PIN_10_OFFSET 2
#define PIN_11_OFFSET 3
#define PIN_12_OFFSET 4
#define PIN_13_OFFSET 5
//#define PIN_14_OFFSET 8 //This pin is not connected on either board.
#define PIN_15_OFFSET 9
#define PIN_16_OFFSET 10
#define PIN_17_OFFSET 11
#define PIN_18_OFFSET 12
#define PIN_19_OFFSET 13
// These are *PIN* numbers, not
// GPIO Offset Numbers.
#define PIN_SPI1_SCK (13u)
#define PIN_SPI1_MISO (12u)
#define PIN_SPI1_MOSI (11u)
#define PIN_SPI1_SS0 (10u)
#define PIN_SPI1_SS1 (14u)
#define PIN_SPI1_SS2 (15u)
#define PIN_SPI1_SS3 (16u)
#define SS_PIN_TO_CS_ID(x) \
((x==PIN_SPI1_SS0 ? 0 : \
(x==PIN_SPI1_SS1 ? 1 : \
(x==PIN_SPI1_SS2 ? 2 : \
(x==PIN_SPI1_SS3 ? 3 : \
-1)))))
// These buttons are present only on the Freedom E300 Arty Dev Kit.
#ifdef HAS_BOARD_BUTTONS
#define BUTTON_0_OFFSET 15
#define BUTTON_1_OFFSET 30
#define BUTTON_2_OFFSET 31
#define INT_DEVICE_BUTTON_0 (INT_GPIO_BASE + BUTTON_0_OFFSET)
#define INT_DEVICE_BUTTON_1 (INT_GPIO_BASE + BUTTON_1_OFFSET)
#define INT_DEVICE_BUTTON_2 (INT_GPIO_BASE + BUTTON_2_OFFSET)
#endif
#define HAS_HFXOSC 1
#define HAS_LFROSC_BYPASS 1
#define RTC_FREQ 32768
#endif /* _SIFIVE_HIFIVE1_H */

238
hifive1-vp/hello/bsp/env/iss/init.c vendored Normal file
View File

@ -0,0 +1,238 @@
#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)
{
return *(volatile unsigned long *)(CLINT_BASE_ADDR + CLINT_MTIME);
}
#ifdef __riscv32
static uint32_t mtime_hi(void)
{
return *(volatile uint32_t *)(CLINT_BASE_ADDR + CLINT_MTIME + 4);
}
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;
}
}
#else /* __riscv32 */
uint64_t get_timer_value()
{
return mtime_lo();
}
#endif
unsigned long get_timer_freq()
{
return 32768;
}
static void use_hfrosc(int div, int trim)
{
// Make sure the HFROSC is running at its default setting
PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1));
while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ;
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1);
}
static void use_pll(int refsel, int bypass, int r, int f, int q)
{
// Ensure that we aren't running off the PLL before we mess with it.
if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) {
// Make sure the HFROSC is running at its default setting
use_hfrosc(4, 16);
}
// Set PLL Source to be HFXOSC if available.
uint32_t config_value = 0;
config_value |= PLL_REFSEL(refsel);
if (bypass) {
// Bypass
config_value |= PLL_BYPASS(1);
PRCI_REG(PRCI_PLLCFG) = config_value;
// If we don't have an HFXTAL, this doesn't really matter.
// Set our Final output divide to divide-by-1:
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
} else {
// In case we are executing from QSPI,
// (which is quite likely) we need to
// set the QSPI clock divider appropriately
// before boosting the clock frequency.
// Div = f_sck/2
SPI0_REG(SPI_REG_SCKDIV) = 8;
// Set DIV Settings for PLL
// Both HFROSC and HFXOSC are modeled as ideal
// 16MHz sources (assuming dividers are set properly for
// HFROSC).
// (Legal values of f_REF are 6-48MHz)
// Set DIVR to divide-by-2 to get 8MHz frequency
// (legal values of f_R are 6-12 MHz)
config_value |= PLL_BYPASS(1);
config_value |= PLL_R(r);
// Set DIVF to get 512Mhz frequncy
// There is an implied multiply-by-2, 16Mhz.
// So need to write 32-1
// (legal values of f_F are 384-768 MHz)
config_value |= PLL_F(f);
// Set DIVQ to divide-by-2 to get 256 MHz frequency
// (legal values of f_Q are 50-400Mhz)
config_value |= PLL_Q(q);
// Set our Final output divide to divide-by-1:
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
PRCI_REG(PRCI_PLLCFG) = config_value;
// Un-Bypass the PLL.
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
// Wait for PLL Lock
// Note that the Lock signal can be glitchy.
// Need to wait 100 us
// RTC is running at 32kHz.
// So wait 4 ticks of RTC.
uint32_t now = mtime_lo();
while (mtime_lo() - now < 4) ;
// Now it is safe to check for PLL Lock
while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ;
}
// Switch over to PLL Clock source
PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1);
}
static void use_default_clocks()
{
// Turn off the LFROSC
AON_REG(AON_LFROSC) &= ~ROSC_EN(1);
// Use HFROSC
use_hfrosc(4, 16);
}
static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n)
{
unsigned long start_mtime, delta_mtime;
unsigned long mtime_freq = get_timer_freq();
// Don't start measuruing until we see an mtime tick
unsigned long tmp = mtime_lo();
do {
start_mtime = mtime_lo();
} while (start_mtime == tmp);
unsigned long start_mcycle = read_csr(mcycle);
do {
delta_mtime = mtime_lo() - start_mtime;
} while (delta_mtime < n);
unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle;
return (delta_mcycle / delta_mtime) * mtime_freq
+ ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
}
unsigned long get_cpu_freq()
{
static uint32_t cpu_freq;
if (!cpu_freq) {
// warm up I$
measure_cpu_freq(1);
// measure for real
cpu_freq = measure_cpu_freq(10);
}
return cpu_freq;
}
static void uart_init(size_t baud_rate)
{
GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK;
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1;
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
}
#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
use_default_clocks();
use_pll(0, 0, 1, 31, 1);
uart_init(115200);
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()
{
}

168
hifive1-vp/hello/bsp/env/iss/link.lds vendored Normal file
View File

@ -0,0 +1,168 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
/*flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M*/
flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M
ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K
}
PHDRS
{
flash PT_LOAD;
ram_init PT_LOAD;
ram PT_NULL;
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
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
}

View File

@ -0,0 +1,34 @@
adapter_khz 10000
interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020
#Reset Stretcher logic on FE310 is ~1 second long
#This doesn't apply if you use
# ftdi_set_signal, but still good to document
#adapter_nsrst_delay 1500
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME
init
#reset -- This type of reset is not implemented yet
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
#Wait for the reset stretcher
#It will work without this, but
#will incur lots of delays for later commands.
sleep 1500
}
halt
#flash protect 0 64 last off

133
hifive1-vp/hello/bsp/env/iss/platform.h vendored Normal file
View File

@ -0,0 +1,133 @@
// See LICENSE for license details.
#ifndef _SIFIVE_PLATFORM_H
#define _SIFIVE_PLATFORM_H
// Some things missing from the official encoding.h
#define MCAUSE_INT 0x80000000
#define MCAUSE_CAUSE 0x7FFFFFFF
#include "sifive/const.h"
#include "sifive/devices/aon.h"
#include "sifive/devices/clint.h"
#include "sifive/devices/gpio.h"
#include "sifive/devices/otp.h"
#include "sifive/devices/plic.h"
#include "sifive/devices/prci.h"
#include "sifive/devices/pwm.h"
#include "sifive/devices/spi.h"
#include "sifive/devices/uart.h"
/****************************************************************************
* Platform definitions
*****************************************************************************/
// Memory map
#define MASKROM_BASE_ADDR _AC(0x00001000,UL)
#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL)
#define OTP_MMAP_ADDR _AC(0x00020000,UL)
#define CLINT_BASE_ADDR _AC(0x02000000,UL)
#define PLIC_BASE_ADDR _AC(0x0C000000,UL)
#define AON_BASE_ADDR _AC(0x10000000,UL)
#define PRCI_BASE_ADDR _AC(0x10008000,UL)
#define OTP_BASE_ADDR _AC(0x10010000,UL)
#define GPIO_BASE_ADDR _AC(0x10012000,UL)
#define UART0_BASE_ADDR _AC(0x10013000,UL)
#define SPI0_BASE_ADDR _AC(0x10014000,UL)
#define PWM0_BASE_ADDR _AC(0x10015000,UL)
#define UART1_BASE_ADDR _AC(0x10023000,UL)
#define SPI1_BASE_ADDR _AC(0x10024000,UL)
#define PWM1_BASE_ADDR _AC(0x10025000,UL)
#define SPI2_BASE_ADDR _AC(0x10034000,UL)
#define PWM2_BASE_ADDR _AC(0x10035000,UL)
#define SPI0_MMAP_ADDR _AC(0x20000000,UL)
#define MEM_BASE_ADDR _AC(0x80000000,UL)
// IOF masks
#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
#define SPI11_NUM_SS (4)
#define IOF_SPI1_SS0 (2u)
#define IOF_SPI1_SS1 (8u)
#define IOF_SPI1_SS2 (9u)
#define IOF_SPI1_SS3 (10u)
#define IOF_SPI1_MOSI (3u)
#define IOF_SPI1_MISO (4u)
#define IOF_SPI1_SCK (5u)
#define IOF_SPI1_DQ0 (3u)
#define IOF_SPI1_DQ1 (4u)
#define IOF_SPI1_DQ2 (6u)
#define IOF_SPI1_DQ3 (7u)
#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
#define SPI2_NUM_SS (1)
#define IOF_SPI2_SS0 (26u)
#define IOF_SPI2_MOSI (27u)
#define IOF_SPI2_MISO (28u)
#define IOF_SPI2_SCK (29u)
#define IOF_SPI2_DQ0 (27u)
#define IOF_SPI2_DQ1 (28u)
#define IOF_SPI2_DQ2 (30u)
#define IOF_SPI2_DQ3 (31u)
//#define IOF0_I2C_MASK _AC(0x00003000,UL)
#define IOF0_UART0_MASK _AC(0x00030000, UL)
#define IOF_UART0_RX (16u)
#define IOF_UART0_TX (17u)
#define IOF0_UART1_MASK _AC(0x03000000, UL)
#define IOF_UART1_RX (24u)
#define IOF_UART1_TX (25u)
#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
#define IOF1_PWM1_MASK _AC(0x00780000, UL)
#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
// Interrupt numbers
#define INT_RESERVED 0
#define INT_WDOGCMP 1
#define INT_RTCCMP 2
#define INT_UART0_BASE 3
#define INT_UART1_BASE 4
#define INT_SPI0_BASE 5
#define INT_SPI1_BASE 6
#define INT_SPI2_BASE 7
#define INT_GPIO_BASE 8
#define INT_PWM0_BASE 40
#define INT_PWM1_BASE 44
#define INT_PWM2_BASE 48
// Helper functions
#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset)
#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset)
#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset)
#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset)
#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset)
#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset)
#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset)
#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset)
#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset)
#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset)
#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset)
#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset)
#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset)
#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset)
// Misc
#include <stdint.h>
#define NUM_GPIO 32
#define PLIC_NUM_INTERRUPTS 52
#define PLIC_NUM_PRIORITIES 7
#include "hifive1.h"
unsigned long get_cpu_freq(void);
unsigned long get_timer_freq(void);
uint64_t get_timer_value(void);
#endif /* _SIFIVE_PLATFORM_H */

54
hifive1-vp/hello/bsp/env/start.S vendored Normal file
View File

@ -0,0 +1,54 @@
// See LICENSE for license details.
.section .init
.globl _start
.type _start,@function
_start:
la gp, _gp
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 */
la a0, __libc_fini_array
call atexit
call __libc_init_array
#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