23 Commits

Author SHA1 Message Date
be32d2467c adds all defined aclint regs 2025-12-14 13:37:07 +01:00
c8ea882b3e adds some hooks for SMT startup 2025-11-29 12:49:50 +01:00
5f220ff09b simplifies linker scripts of riscv-vp 2025-11-29 06:38:45 +01:00
d8728e319c fixes stack pointer adjustment 2025-11-21 17:41:35 +01:00
fce1372494 improves bsp of riscv-vp by including init.c 2025-11-21 15:40:08 +01:00
fc3f6c57e5 fixes wrong trap handler pre- and postamble 2025-11-21 14:45:16 +01:00
328a961276 adds csr access functions 2025-11-21 11:26:09 +01:00
6e2607cecc adds Linker script dir to Linker script path 2025-11-05 19:22:02 +01:00
fced281870 adds terminator to char str in wrap_puts 2025-10-24 10:05:55 +02:00
703fbf67b4 fixes ROM location 2025-09-15 21:02:23 +02:00
59d0a22738 adapts riscv-vp rom to implementation 2025-09-15 20:52:50 +02:00
3df19468e9 corrects XIP start addr in risc-v vp 2025-09-14 14:55:23 +02:00
bf0e4ec057 extends and relocates ISS RAM 2025-09-12 08:32:47 +02:00
018e07ecee removes duplicate 'inline' statement 2025-08-22 15:34:32 +02:00
fc37441911 corrects setting of mtimecmp in aclint to be as recommended in the spec 2025-08-21 11:47:58 +02:00
b5cee82f3e adds rom linker script 2025-07-30 06:36:41 +02:00
20161cc1af adds RISCV-VP platform 2025-07-30 06:35:53 +02:00
0843d92878 adds platform dir to link dirs to find linker script includes 2025-07-30 06:33:58 +02:00
a7b4e7b715 fixes moonlight memory layout in link.lds 2025-07-15 07:40:39 +02:00
b69fd19910 updates the flash/ram ORIGIN so that 64bit works 2025-07-04 18:56:29 +02:00
25306948c9 Merge branch 'develop' of https://git.minres.com/Firmware/MNRS-BM-BSP.git into develop 2025-07-04 13:18:12 +02:00
74fd5b0a2b replaces strlen function in puts in case not libc is used 2025-07-04 13:16:50 +02:00
ca36d3ef84 makes no-warn-rwx-segments check if compiler has the option 2025-06-17 19:42:16 +02:00
21 changed files with 17954 additions and 60 deletions

View File

@@ -1,7 +1,11 @@
cmake_minimum_required(VERSION 3.21)
include(CheckLinkerFlag)
project(mnrs-bsp LANGUAGES ASM C)
option(NO_INIT "use an empty init routine" OFF)
set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/env/${BOARD}/link.lds"
CACHE FILEPATH "Linker script to use for BSP linking")
get_filename_component(LINKER_SCRIPT_DIR "${LINKER_SCRIPT}" DIRECTORY)
set(BSP_STARTUP "${CMAKE_CURRENT_SOURCE_DIR}/env/start.S"
CACHE FILEPATH "Path to the BSP startup assembly file")
set(BSP_TRAP_HANDLER "${CMAKE_CURRENT_SOURCE_DIR}/env/entry.S"
@@ -27,12 +31,22 @@ target_include_directories(startup PUBLIC env include)
add_subdirectory(libwrap)
add_library(bsp STATIC env/${BOARD}/init.c)
target_link_libraries(bsp PUBLIC startup wrap)
target_include_directories(bsp PUBLIC env/${BOARD})
target_link_options(bsp INTERFACE LINKER:--no-warn-rwx-segments -nostartfiles -T ${LINKER_SCRIPT})
add_library(runtime STATIC env/${BOARD}/init.c)
target_include_directories(runtime PUBLIC env/${BOARD} env include)
if(NO_INIT)
target_compile_definitions(runtime PRIVATE NO_INIT)
endif()
check_linker_flag(C "LINKER:--no-warn-rwx-segments" HAS_NO_WARN_RWX_SEGMENTS)
if(HAS_NO_WARN_RWX_SEGMENTS)
target_link_options(runtime INTERFACE LINKER:--no-warn-rwx-segments)
endif()
target_link_options(runtime INTERFACE LINKER: -nostartfiles -T ${LINKER_SCRIPT} -L${LINKER_SCRIPT_DIR})
if(SEMIHOSTING)
target_include_directories(bsp INTERFACE include)
target_sources(bsp INTERFACE env/semihosting.c env/trap.c)
target_sources(runtime INTERFACE env/semihosting.c env/trap.c)
endif()
add_library(bsp INTERFACE)
target_link_libraries(bsp INTERFACE startup runtime wrap)

2
env/common-gcc.mk vendored
View File

@@ -28,7 +28,7 @@ INCLUDES += -I$(PLATFORM_DIR)
INCLUDES += -I$(BSP_BASE)/libwrap/sys/
LDFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI)
LDFLAGS += -L$(ENV_DIR)
LDFLAGS += -L$(ENV_DIR) -L$(PLATFORM_DIR)
LD_SCRIPT += -T $(LINKER_SCRIPT) -Wl,--no-warn-rwx-segments -Wl,-Map=$(TARGET).map -nostartfiles
ifneq (,$(findstring specs=nano.specs,$(LDFLAGS), LD_SCRIPT))

16
env/entry.S vendored
View File

@@ -10,12 +10,13 @@
.align 2
.global trap_entry
trap_entry:
addi sp, sp, -32*REGBYTES
#ifdef __riscv_abi_rve
addi sp, sp, -12*REGBYTES
#else
addi sp, sp, -28*REGBYTES
#endif
sw x1, 1*REGBYTES(sp)
sw x2, 2*REGBYTES(sp)
sw x3, 3*REGBYTES(sp)
sw x4, 4*REGBYTES(sp)
sw x5, 5*REGBYTES(sp)
sw x6, 6*REGBYTES(sp)
sw x7, 7*REGBYTES(sp)
@@ -53,9 +54,6 @@ trap_entry:
lw x1, 1*REGBYTES(sp)
lw x2, 2*REGBYTES(sp)
lw x3, 3*REGBYTES(sp)
lw x4, 4*REGBYTES(sp)
lw x5, 5*REGBYTES(sp)
lw x6, 6*REGBYTES(sp)
lw x7, 7*REGBYTES(sp)
@@ -84,6 +82,9 @@ trap_entry:
lw x29, 29*REGBYTES(sp)
lw x30, 30*REGBYTES(sp)
lw x31, 31*REGBYTES(sp)
addi sp, sp, 28*REGBYTES
#else
addi sp, sp, 12*REGBYTES
#endif
mret
@@ -91,5 +92,4 @@ trap_entry:
handle_trap:
1:
j 1b
#endif

2
env/iss/link.lds vendored
View File

@@ -5,7 +5,7 @@ ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M
ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 64K
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 1M
}
PHDRS

1
env/riscv_vp/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.o

21
env/riscv_vp/bsp_read.c vendored Normal file
View File

@@ -0,0 +1,21 @@
#include "platform.h"
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
ssize_t _bsp_read(int fd, void *ptr, size_t len) {
uint8_t *current = (uint8_t *)ptr;
ssize_t result = 0;
if (isatty(fd)) {
for (current = (uint8_t *)ptr; (current < ((uint8_t *)ptr) + len) &&
(get_uart_rx_tx_reg_rx_avail(uart) > 0);
current++) {
*current = uart_read(uart);
result++;
}
return result;
}
return EOF;
}

21
env/riscv_vp/bsp_write.c vendored Normal file
View File

@@ -0,0 +1,21 @@
/* See LICENSE of license details. */
#include "platform.h"
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
ssize_t _bsp_write(int fd, const void *ptr, size_t len) {
const uint8_t *current = (const uint8_t *)ptr;
if (isatty(fd)) {
for (size_t jj = 0; jj < len; jj++) {
uart_write(uart, current[jj]);
if (current[jj] == '\n') {
uart_write(uart, '\r');
}
}
return len;
}
return 1;
}

12
env/riscv_vp/flash.lds vendored Normal file
View File

@@ -0,0 +1,12 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
INCLUDE memory_map.ld
REGION_ALIAS("REGION_TEXT", flash);
REGION_ALIAS("REGION_RODATA", flash);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
INCLUDE sections.ld

110
env/riscv_vp/init.c vendored Normal file
View File

@@ -0,0 +1,110 @@
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include "encoding.h"
#include "platform.h"
extern int main(int argc, char** argv);
extern void trap_entry(void);
#define IRQ_M_SOFT 3
#define IRQ_M_TIMER 7
#define IRQ_M_EXT 11
void handle_m_ext_interrupt(void);
void handle_m_time_interrupt(void);
uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp);
void default_handler(void);
void _init(void);
typedef void (*my_interrupt_function_ptr_t)(void);
my_interrupt_function_ptr_t localISR[NUM_INTERRUPTS] __attribute__((aligned(64)));
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(void) {
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 100000000; }
void init_pll(void) {
// TODO: implement initialization
}
static void uart_init(size_t baud_rate) {
// TODO: implement initialization
}
void __attribute__((weak)) handle_m_ext_interrupt() {}
void __attribute__((weak)) handle_m_time_interrupt() {
uint64_t time = get_aclint_mtime(aclint);
time += MTIMER_NEXT_TICK_INC;
set_aclint_mtimecmp(aclint, time);
}
void __attribute__((weak)) default_handler(void) { puts("default handler\n"); }
void __attribute__((weak)) interrupt_handler(unsigned) { puts("interrupt handler\n"); }
uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp) {
if((mcause & MCAUSE_INT)) {
if((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) {
handle_m_ext_interrupt();
} else if(((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)) {
handle_m_time_interrupt();
} else {
interrupt_handler(mcause & ~MCAUSE_INT);
}
} else {
write(1, "trap\n", 5);
_exit(1 + mcause);
}
return mepc;
}
void __attribute__((weak)) _init() {
#ifndef NO_INIT
init_pll();
uart_init(115200);
printf("core freq at %lu 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
}
int i = 0;
while(i < NUM_INTERRUPTS) {
localISR[i++] = default_handler;
}
#endif
}
void _fini(void) {}

7
env/riscv_vp/memory_map.ld vendored Normal file
View File

@@ -0,0 +1,7 @@
MEMORY
{
ram (wxa!ri) : ORIGIN = 0x00000000, LENGTH = 128K
rom (rxai!w) : ORIGIN = 0x10080000, LENGTH = 8k
flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 16M
dram (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 2048M
}

52
env/riscv_vp/platform.h vendored Normal file
View File

@@ -0,0 +1,52 @@
// See LICENSE for license details.
#ifndef _ISS_PLATFORM_H
#define _ISS_PLATFORM_H
#if __riscv_xlen == 32
#define MCAUSE_INT 0x80000000UL
#define MCAUSE_CAUSE 0x000003FFUL
#else
#define MCAUSE_INT 0x8000000000000000UL
#define MCAUSE_CAUSE 0x00000000000003FFUL
#endif
#define APB_BUS
#include "minres/devices/aclint.h"
#include "minres/devices/dma.h"
#include "minres/devices/gen/sysctrl.h"
#include "minres/devices/gpio.h"
#include "minres/devices/i2s.h"
#include "minres/devices/qspi.h"
#include "minres/devices/timer.h"
#include "minres/devices/uart.h"
#include <riscv/riscv_csr.h>
#define PERIPH(TYPE, ADDR) ((volatile TYPE*)(ADDR))
// values from memory_map.ld
#define XIP_START_LOC 0x20000000
#define RAM_START_LOC 0x00000000
#define APB_BASE 0x10000000
#define gpio PERIPH(gpio_t, APB_BASE + 0x0000)
#define uart PERIPH(uart_t, APB_BASE + 0x01000)
#define timer PERIPH(timercounter_t, APB_BASE + 0x20000)
#define aclint PERIPH(aclint_t, APB_BASE + 0x30000)
#define sysctrl PERIPH(sysctrl_t, APB_BASE + 0x40000)
#define qspi PERIPH(qspi_t, APB_BASE + 0x50000)
#define i2s PERIPH(i2s_t, APB_BASE + 0x90000)
#define dma PERIPH(dma_t, APB_BASE + 0xB0000)
// Misc
#include <stdint.h>
#define NUM_INTERRUPTS 16
#define MTIMER_NEXT_TICK_INC 1000
void init_pll(void);
unsigned long get_cpu_freq(void);
unsigned long get_timer_freq(void);
#endif /* _ISS_PLATFORM_H */

12
env/riscv_vp/ram.lds vendored Normal file
View File

@@ -0,0 +1,12 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
INCLUDE memory_map.ld
REGION_ALIAS("REGION_TEXT", ram);
REGION_ALIAS("REGION_RODATA", ram);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
INCLUDE sections.ld

12
env/riscv_vp/rom.lds vendored Normal file
View File

@@ -0,0 +1,12 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
INCLUDE memory_map.ld
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_RODATA", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
INCLUDE sections.ld

171
env/riscv_vp/sections.ld vendored Normal file
View File

@@ -0,0 +1,171 @@
PHDRS
{
flash PT_LOAD;
ram_init PT_LOAD;
ram PT_NULL;
dram PT_NULL;
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
__stack_segment_size = DEFINED(__stack_segment_size) ? __stack_segment_size : __stack_size;
.init ORIGIN(REGION_TEXT) :
{
KEEP (*(SORT_NONE(.init)))
} >REGION_TEXT AT>REGION_TEXT :flash
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >REGION_TEXT AT>REGION_TEXT :flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >REGION_TEXT AT>REGION_TEXT :flash
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} >REGION_RODATA AT>REGION_RODATA :flash
.srodata :
{
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >REGION_RODATA AT>REGION_RODATA :flash
. = ALIGN(4);
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >REGION_RODATA AT>REGION_RODATA :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 = .);
} >REGION_RODATA AT>REGION_RODATA :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 = .);
} >REGION_RODATA AT>REGION_RODATA :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))
} >REGION_RODATA AT>REGION_RODATA :flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >REGION_RODATA AT>REGION_RODATA :flash
.dummy :
{
*(.comment.*)
}
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >REGION_RODATA AT>REGION_RODATA :flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >REGION_DATA AT>REGION_RODATA :ram_init
.data :
{
__DATA_BEGIN__ = .;
*(.data .data.*)
*(.gnu.linkonce.d.*)
} >REGION_DATA AT>REGION_RODATA :ram_init
.sdata :
{
__SDATA_BEGIN__ = .;
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
} >REGION_DATA AT>REGION_RODATA :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);
} >REGION_BSS AT>REGION_BSS :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_segment_size :
{
PROVIDE( _heap_end = . );
. = __stack_segment_size;
PROVIDE( _sp = . );
} >REGION_BSS AT>REGION_BSS :ram
PROVIDE( tohost = . );
PROVIDE( fromhost = . + 8 );
}

34
env/start.S vendored
View File

@@ -9,18 +9,35 @@ _start:
.option push
.option norelax
.option norvc
//#ifdef WITH_SIGNATURE
#ifdef WITH_SIGNATURE
j 1f
.2byte 0x4e4d
.2byte 0x5352
.4byte 0x669
1:
//#endif
#endif
la gp, __global_pointer$
.option pop
la sp, _sp
csrr t0, mhartid // Get hart ID
la t1, __stack_size // stack size
la sp, _sp // Base stack address
/* this loop is to avoid multiplication which is not available on all ISAs */
1:
beqz t0, 2f
sub sp, sp, t1 // Subtract __stack_size to get per-hart stack base
addi t0, t0, -1
j 1b
2:
la t0, trap_entry
csrw mtvec, t0
#ifdef HARTX_WAIT4WFI
/* block other cores until hart 0 has finished initialization */
csrr t0, mhartid
beqz t0, hart0_init
wfi
j hartx_start
hart0_init:
#endif
/* Load data section */
la a0, _data_lma
la a1, _data
@@ -50,6 +67,10 @@ _start:
call atexit
call __libc_init_array
#endif
la a0, mtx
li t0, 1
sw t0, 0(a0)
hartx_start:
#ifndef __riscv_float_abi_soft
/* Enable FPU */
li t0, MSTATUS_FS
@@ -60,9 +81,14 @@ _start:
fssr x0
1:
#endif
call _init
/* argc = argv = 0 */
li a0, 0
li a1, 0
call main
tail _exit
.data
mtx:
.word 0 # 32-bit value

View File

@@ -1,26 +1,36 @@
#ifndef _DEVICES_ACLINT_H
#define _DEVICES_ACLINT_H
#include <stdint.h>
#include "gen/aclint.h"
#include <stdint.h>
static void set_aclint_mtime(volatile aclint_t* reg, uint64_t value){
static void set_aclint_mtime(volatile aclint_t* reg, uint64_t value) {
set_aclint_mtime_hi(reg, (uint32_t)(value >> 32));
set_aclint_mtime_lo(reg, (uint32_t)value);
}
static uint64_t get_aclint_mtime(volatile aclint_t* reg){
uint64_t value = ((uint64_t)get_aclint_mtime_hi(reg) << 32) | (uint64_t)get_aclint_mtime_lo(reg);
return value;
static uint64_t get_aclint_mtime(volatile aclint_t* reg) {
// #if ( __riscv_xlen == 64)
// volatile uint64_t *mtime = (volatile uint64_t *)(RISCV_MTIME_ADDR);
// return *mtime;
// #else
uint32_t mtimeh_val;
uint32_t mtimel_val;
do {
mtimeh_val = get_aclint_mtime_hi(reg);
mtimel_val = get_aclint_mtime_lo(reg);
} while(mtimeh_val != get_aclint_mtime_hi(reg));
return (uint64_t)((((uint64_t)mtimeh_val) << 32) | mtimel_val);
// #endif
}
static void set_aclint_mtimecmp(volatile aclint_t* reg, uint64_t value){
static void set_aclint_mtimecmp(volatile aclint_t* reg, uint64_t value) {
set_aclint_mtimecmp0lo(reg, (uint32_t)0xFFFFFFFF);
set_aclint_mtimecmp0hi(reg, (uint32_t)(value >> 32));
set_aclint_mtimecmp0lo(reg, (uint32_t)value);
}
static uint64_t get_aclint_mtimecmp(volatile aclint_t* reg){
static uint64_t get_aclint_mtimecmp(volatile aclint_t* reg) {
uint64_t value = ((uint64_t)get_aclint_mtimecmp0hi(reg) << 32) | (uint64_t)get_aclint_mtimecmp0lo(reg);
return value;
}

View File

@@ -13,26 +13,26 @@
#include <stdint.h>
typedef struct {
volatile uint32_t MSIP0;
uint8_t fill0[16380];
volatile uint32_t MTIMECMP0LO;
volatile uint32_t MTIMECMP0HI;
uint8_t fill1[32752];
volatile uint32_t MTIME_LO;
volatile uint32_t MTIME_HI;
volatile uint32_t MSIP[4096];
struct {
volatile uint32_t LO;
volatile uint32_t HI;
} MTIMECMP[4096];
volatile uint32_t MTIME_LO;
volatile uint32_t MTIME_HI;
} aclint_t;
#define ACLINT_MSIP0_OFFS 0
#define ACLINT_MSIP0_MASK 0x1
#define ACLINT_MSIP0(V) ((V & ACLINT_MSIP0_MASK) << ACLINT_MSIP0_OFFS)
#define ACLINT_MSIP_OFFS 0
#define ACLINT_MSIP_MASK 0x1
#define ACLINT_MSIP(V) ((V & ACLINT_MSIP0_MASK) << ACLINT_MSIP0_OFFS)
#define ACLINT_MTIMECMP0LO_OFFS 0
#define ACLINT_MTIMECMP0LO_MASK 0xffffffff
#define ACLINT_MTIMECMP0LO(V) ((V & ACLINT_MTIMECMP0LO_MASK) << ACLINT_MTIMECMP0LO_OFFS)
#define ACLINT_MTIMECMPLO_OFFS 0
#define ACLINT_MTIMECMPLO_MASK 0xffffffff
#define ACLINT_MTIMECMPLO(V) ((V & ACLINT_MTIMECMP0LO_MASK) << ACLINT_MTIMECMP0LO_OFFS)
#define ACLINT_MTIMECMP0HI_OFFS 0
#define ACLINT_MTIMECMP0HI_MASK 0xffffffff
#define ACLINT_MTIMECMP0HI(V) ((V & ACLINT_MTIMECMP0HI_MASK) << ACLINT_MTIMECMP0HI_OFFS)
#define ACLINT_MTIMECMPHI_OFFS 0
#define ACLINT_MTIMECMPHI_MASK 0xffffffff
#define ACLINT_MTIMECMPHI(V) ((V & ACLINT_MTIMECMP0HI_MASK) << ACLINT_MTIMECMP0HI_OFFS)
#define ACLINT_MTIME_LO_OFFS 0
#define ACLINT_MTIME_LO_MASK 0xffffffff
@@ -43,33 +43,55 @@ typedef struct {
#define ACLINT_MTIME_HI(V) ((V & ACLINT_MTIME_HI_MASK) << ACLINT_MTIME_HI_OFFS)
// ACLINT_MSIP0
static inline uint32_t get_aclint_msip0(volatile aclint_t* reg) { return reg->MSIP0; }
static inline void set_aclint_msip0(volatile aclint_t* reg, uint32_t value) { reg->MSIP0 = value; }
static inline uint32_t get_aclint_msip0_msip(volatile aclint_t* reg) { return (reg->MSIP0 >> 0) & 0x1; }
static inline void set_aclint_msip0_msip(volatile aclint_t* reg, uint8_t value) { reg->MSIP0 = (reg->MSIP0 & ~(0x1U << 0)) | (value << 0); }
static inline uint32_t get_aclint_msip0(volatile aclint_t* reg) { return reg->MSIP[0]; }
static inline void set_aclint_msip0(volatile aclint_t* reg, uint32_t value) { reg->MSIP[0] = value; }
static inline uint32_t get_aclint_msip0_msip(volatile aclint_t* reg) { return (reg->MSIP[0] >> 0) & 0x1; }
static inline void set_aclint_msip0_msip(volatile aclint_t* reg, uint8_t value) {
reg->MSIP[0] = (reg->MSIP[0] & ~(0x1U << 0)) | (value << 0);
}
// ACLINT_MSIP
static inline uint32_t get_aclint_msip(volatile aclint_t* reg, unsigned idx) { return reg->MSIP[idx]; }
static inline void set_aclint_msip(volatile aclint_t* reg, unsigned idx, uint32_t value) { reg->MSIP[idx] = value; }
static inline uint32_t get_aclint_msip_msip(volatile aclint_t* reg, unsigned idx) { return (reg->MSIP[idx] >> 0) & 0x1; }
static inline void set_aclint_msip_msip(volatile aclint_t* reg, unsigned idx, uint8_t value) {
reg->MSIP[idx] = (reg->MSIP[idx] & ~(0x1U << 0)) | (value << 0);
}
// ACLINT_MTIMECMP0LO
static inline uint32_t get_aclint_mtimecmp0lo(volatile aclint_t* reg) { return (reg->MTIMECMP0LO >> 0) & 0xffffffff; }
static inline uint32_t get_aclint_mtimecmp0lo(volatile aclint_t* reg) { return (reg->MTIMECMP[0].LO >> 0) & 0xffffffff; }
static inline void set_aclint_mtimecmp0lo(volatile aclint_t* reg, uint32_t value) {
reg->MTIMECMP0LO = (reg->MTIMECMP0LO & ~(0xffffffffU << 0)) | (value << 0);
reg->MTIMECMP[0].LO = (reg->MTIMECMP[0].LO & ~(0xffffffffU << 0)) | (value << 0);
}
// ACLINT_MTIMECMPxLO
static inline uint32_t get_aclint_mtimecmplo(volatile aclint_t* reg, unsigned idx) { return (reg->MTIMECMP[idx].LO >> 0) & 0xffffffff; }
static inline void set_aclint_mtimecmplo(volatile aclint_t* reg, unsigned idx, uint32_t value) {
reg->MTIMECMP[idx].LO = (reg->MTIMECMP[idx].LO & ~(0xffffffffU << 0)) | (value << 0);
}
// ACLINT_MTIMECMP0HI
static inline uint32_t get_aclint_mtimecmp0hi(volatile aclint_t* reg) { return (reg->MTIMECMP0HI >> 0) & 0xffffffff; }
static inline uint32_t get_aclint_mtimecmp0hi(volatile aclint_t* reg) { return (reg->MTIMECMP[0].HI >> 0) & 0xffffffff; }
static inline void set_aclint_mtimecmp0hi(volatile aclint_t* reg, uint32_t value) {
reg->MTIMECMP0HI = (reg->MTIMECMP0HI & ~(0xffffffffU << 0)) | (value << 0);
reg->MTIMECMP[0].HI = (reg->MTIMECMP[0].HI & ~(0xffffffffU << 0)) | (value << 0);
}
// ACLINT_MTIMECMPxHI
static inline uint32_t get_aclint_mtimecmphi(volatile aclint_t* reg, unsigned idx) { return (reg->MTIMECMP[idx].HI >> 0) & 0xffffffff; }
static inline void set_aclint_mtimecmphi(volatile aclint_t* reg, unsigned idx, uint32_t value) {
reg->MTIMECMP[idx].HI = (reg->MTIMECMP[idx].HI & ~(0xffffffffU << 0)) | (value << 0);
}
// ACLINT_MTIME_LO
static inline uint32_t get_aclint_mtime_lo(volatile aclint_t* reg) { return (reg->MTIME_LO >> 0) & 0xffffffff; }
static inline void set_aclint_mtime_lo(volatile aclint_t* reg, uint32_t value) {
reg->MTIME_LO = (reg->MTIME_LO & ~(0xffffffffU << 0)) | (value << 0);
reg->MTIME_LO = (reg->MTIME_LO & ~(0xffffffffU << 0)) | (value << 0);
}
// ACLINT_MTIME_HI
static inline uint32_t get_aclint_mtime_hi(volatile aclint_t* reg) { return (reg->MTIME_HI >> 0) & 0xffffffff; }
static inline void set_aclint_mtime_hi(volatile aclint_t* reg, uint32_t value) {
reg->MTIME_HI = (reg->MTIME_HI & ~(0xffffffffU << 0)) | (value << 0);
reg->MTIME_HI = (reg->MTIME_HI & ~(0xffffffffU << 0)) | (value << 0);
}
#endif /* _BSP_ACLINT_H */

View File

@@ -21,7 +21,7 @@ static inline void uart_write(volatile uart_t* reg, uint8_t data){
set_uart_rx_tx_reg_data(reg, data);
}
static inline inline uint8_t uart_read(volatile uart_t* reg){
static inline uint8_t uart_read(volatile uart_t* reg){
uint32_t res = get_uart_rx_tx_reg_data(reg);
while((res&0x10000) == 0) res = get_uart_rx_tx_reg_data(reg);
return res;

3790
include/riscv/riscv_csr.h Normal file

File diff suppressed because it is too large Load Diff

13609
include/riscv/riscv_csr.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,10 +2,14 @@
#include <string.h>
#include <unistd.h>
extern ssize_t _bsp_write(int, const void *, size_t);
extern ssize_t _bsp_write(int, const void*, size_t);
int __wrap_puts(const char *s) {
int len = strlen(s);
return _bsp_write(STDOUT_FILENO, s, len);
int __wrap_puts(const char* s) {
if(!s) return -1;
const char* str = s;
while(*str)
++str;
*(char*)str='\n';
return _bsp_write(STDOUT_FILENO, s, (str - s)+1);
}
weak_under_alias(puts);
weak_under_alias(puts);