cleans up moonlight dir
This commit is contained in:
39
port/moonlight/src/board.c
Normal file
39
port/moonlight/src/board.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "hwtimer.h"
|
||||
#include "csr.h"
|
||||
#include "platform.h"
|
||||
#include "uart.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// needed by picolibc/port.c
|
||||
int uart_putc(int ch) {
|
||||
int intr_enable = riscv_mintr_get();
|
||||
riscv_mintr_off();
|
||||
uart_write(uart, ch);
|
||||
riscv_mintr_restore(intr_enable);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uart_getc(void) {
|
||||
int intr_enable = riscv_mintr_get();
|
||||
riscv_mintr_off();
|
||||
int ch = uart_read(uart);
|
||||
riscv_mintr_restore(intr_enable);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int uart_init(void) {
|
||||
puts("[UART0] : Uart Init Done, this is Test output!");
|
||||
return 0;
|
||||
};
|
||||
|
||||
int board_init(void) {
|
||||
int ret;
|
||||
ret = uart_init();
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = hwtimer_init();
|
||||
if(ret)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
128
port/moonlight/src/bootup.c
Normal file
128
port/moonlight/src/bootup.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Simple C++ startup routine to setup CRT
|
||||
SPDX-License-Identifier: Unlicense
|
||||
|
||||
(https://five-embeddev.com/ | http://www.shincbm.com/)
|
||||
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <picotls.h>
|
||||
#include <tx_port.h>
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C extern
|
||||
#endif
|
||||
|
||||
// Generic C function pointer.
|
||||
typedef void(*function_t)(void) ;
|
||||
// These symbols are defined by the linker script.
|
||||
// See linker.lds
|
||||
EXTERN_C uint8_t __bss_start;
|
||||
EXTERN_C uint8_t __bss_end;
|
||||
EXTERN_C const uint8_t __data_source;
|
||||
EXTERN_C uint8_t __data_start;
|
||||
EXTERN_C uint8_t __data_end;
|
||||
EXTERN_C const uint8_t __data_source;
|
||||
EXTERN_C uint8_t __tbss_start;
|
||||
EXTERN_C uintptr_t __tbss_size;
|
||||
EXTERN_C const uint8_t __tdata_source;
|
||||
EXTERN_C uint8_t __tls_base;
|
||||
EXTERN_C uintptr_t __tdata_size;
|
||||
|
||||
EXTERN_C function_t __init_array_start;
|
||||
EXTERN_C function_t __init_array_end;
|
||||
EXTERN_C function_t __fini_array_start;
|
||||
EXTERN_C function_t __fini_array_end;
|
||||
|
||||
// This function will be placed by the linker script according to the section
|
||||
// Raw function 'called' by the CPU with no runtime.
|
||||
EXTERN_C void _start(void) __attribute__ ((naked,section(".text.boot")));
|
||||
|
||||
// Entry and exit points as C functions.
|
||||
EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".text.boot")));
|
||||
EXTERN_C void _exit(int exit_code) __attribute__ ((noreturn,noinline,weak));
|
||||
|
||||
// Standard entry point, no arguments.
|
||||
extern int main(void);
|
||||
|
||||
// The linker script will place this in the reset entry point.
|
||||
// It will be 'called' with no stack or C runtime configuration.
|
||||
// tp will not be initialized
|
||||
void _start(void) {
|
||||
// Setup SP and GP
|
||||
// The locations are defined in the linker script
|
||||
__asm__ volatile (
|
||||
".option push;"
|
||||
// The 'norelax' option is critical here.
|
||||
// Without 'norelax' the global pointer will
|
||||
// be loaded relative to the global pointer!
|
||||
".option norelax;"
|
||||
"la gp, __global_pointer$;"
|
||||
".option pop;"
|
||||
"la sp, _sp;"
|
||||
#if defined(__riscv_zicsr)
|
||||
"csrr t0, mhartid;"
|
||||
#else
|
||||
"li t0, 0;"
|
||||
#endif
|
||||
"la t1, __stack_size;"
|
||||
"la t1, __stack_size;"
|
||||
"la sp, _sp;"
|
||||
// Loop incase M extension is not present
|
||||
"1:;"
|
||||
"beqz t0, 2f;"
|
||||
"sub sp, sp, t1;"
|
||||
"addi t0, t0, -1;"
|
||||
"j 1b;"
|
||||
"2:;"
|
||||
#ifdef TX_THREAD_SMP_MAX_CORES
|
||||
"call _tx_thread_smp_initialize_wait;"
|
||||
#endif
|
||||
"jal zero, _initialize;"
|
||||
: /* output: none %0 */
|
||||
: /* input: none */
|
||||
: /* clobbers: none */);
|
||||
// This point will not be executed, _initialize() will be called with no return.
|
||||
}
|
||||
|
||||
// At this point we have a stack and global poiner, but no access to global variables.
|
||||
void _initialize(void) {
|
||||
// Init memory regions
|
||||
// Clear the .bss section (global variables with no initial values)
|
||||
memset((void*) &__bss_start, 0, (&__bss_end - &__bss_start));
|
||||
// Initialize the .data section (global variables with initial values)
|
||||
memcpy((void*)&__data_start, (const void*)&__data_source, (&__data_end - &__data_start));
|
||||
// Clear the .tbss section (thread local variables with no initial values)
|
||||
memset((void*) &__tbss_start, 0, __tbss_size);
|
||||
// Initialize the .tls section (thread local variables with initial values)
|
||||
memcpy((void*) &__tls_base, (const void*)&__tdata_source, __tdata_size);
|
||||
// Call constructors
|
||||
for (const function_t* entry=&__init_array_start;
|
||||
entry < &__init_array_end;
|
||||
++entry) {
|
||||
(*entry)();
|
||||
}
|
||||
#ifdef __THREAD_LOCAL_STORAGE
|
||||
_set_tls(__tls_base)
|
||||
#endif
|
||||
int rc = main();
|
||||
// Call destructors
|
||||
for (const function_t* entry=&__fini_array_start;
|
||||
entry < &__fini_array_end;
|
||||
++entry) {
|
||||
(*entry)();
|
||||
}
|
||||
_exit(rc);
|
||||
}
|
||||
|
||||
// This should never be called. Busy loop with the CPU in idle state.
|
||||
void _exit(int exit_code) {
|
||||
(void)exit_code;
|
||||
// Halt
|
||||
while (1) {
|
||||
__asm__ volatile ("wfi");
|
||||
}
|
||||
}
|
||||
83
port/moonlight/src/exception.c
Normal file
83
port/moonlight/src/exception.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "riscv-traps.h"
|
||||
#include "riscv-csr.h"
|
||||
|
||||
// Expect this to increment one time per second - inside exception handler, after each return of MTI handler.
|
||||
static volatile uint64_t ecall_count = 0;
|
||||
#ifdef NX_DEBUG
|
||||
#define PUTS(STR) puts(STR)
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PUTS(STR)
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
void exception(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) {
|
||||
switch(mcause) {
|
||||
case RISCV_EXCP_INSTRUCTION_ADDRESS_MISALIGNED: {
|
||||
puts("[EXCEPTION] : Instruction address misaligned\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_INSTRUCTION_ACCESS_FAULT: {
|
||||
puts("[EXCEPTION] : Instruction access fault\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_ILLEGAL_INSTRUCTION: {
|
||||
puts("[EXCEPTION] : Illegal Instruction\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_BREAKPOINT: {
|
||||
puts("[EXCEPTION] : Breakpoint\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_LOAD_ADDRESS_MISALIGNED: {
|
||||
puts("[EXCEPTION] : Load address misaligned");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_LOAD_ACCESS_FAULT: {
|
||||
puts("[EXCEPTION] : Load access fault\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_STORE_AMO_ADDRESS_MISALIGNED: {
|
||||
puts("[EXCEPTION] : Store/AMO address misaligned");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_STORE_AMO_ACCESS_FAULT: {
|
||||
puts("[EXCEPTION] : Store/AMO access fault\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_ENVIRONMENT_CALL_FROM_U_MODE: {
|
||||
puts("[EXCEPTION] : Environment call from U-mode\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_ENVIRONMENT_CALL_FROM_S_MODE: {
|
||||
puts("[EXCEPTION] : Environment call from S-mode\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_ENVIRONMENT_CALL_FROM_M_MODE: {
|
||||
puts("[EXCEPTION] : Environment call from M-mode\n");
|
||||
ecall_count++;
|
||||
csr_write_mepc(mepc+4);
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_INSTRUCTION_PAGE_FAULT: {
|
||||
puts("[EXCEPTION] : Instruction page fault\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_LOAD_PAGE_FAULT: {
|
||||
puts("[EXCEPTION] : Load page fault\n");
|
||||
break;
|
||||
}
|
||||
case RISCV_EXCP_STORE_AMO_PAGE_FAULT: {
|
||||
puts("[EXCEPTION] : Store/AMO page fault\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf("[EXCEPTION] : Unknown trap cause: %lu\n", mcause);
|
||||
}
|
||||
}
|
||||
printf("[EXCEPTION] : PC: 0x%x\n", mepc);
|
||||
printf("[EXCEPTION] : Addr: 0x%x\n", mtval);
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
1004
port/moonlight/src/mnrs_network_driver.c
Normal file
1004
port/moonlight/src/mnrs_network_driver.c
Normal file
File diff suppressed because it is too large
Load Diff
66
port/moonlight/src/trap_non_vectored.c
Normal file
66
port/moonlight/src/trap_non_vectored.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "hwtimer.h"
|
||||
#include "platform.h"
|
||||
#include "riscv-traps.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <tx_api.h>
|
||||
#include <tx_port.h>
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#define INTERRUPT_BIT 0x8000000000000000ull
|
||||
#else
|
||||
#define INTERRUPT_BIT 0x80000000ull
|
||||
#endif
|
||||
#define OS_IS_INTERRUPT(mcause) (mcause & INTERRUPT_BIT)
|
||||
#define OS_IS_TICK_INT(mcause) (mcause == (0x7 | INTERRUPT_BIT))
|
||||
#define OS_IS_SOFT_INT(mcause) (mcause == (0x3 | INTERRUPT_BIT))
|
||||
#define OS_IS_EXT_INT(mcause) (mcause == (0xb | INTERRUPT_BIT))
|
||||
|
||||
extern void _tx_timer_interrupt(void);
|
||||
extern uintptr_t exception(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval);
|
||||
|
||||
void (*irq_handler[__riscv_xlen])();
|
||||
|
||||
int register_irq_handler(unsigned irq_num, void (*handler)()) {
|
||||
if(irq_num<__riscv_xlen){
|
||||
irq_handler[irq_num] = handler;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void trap_handler(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) {
|
||||
if(OS_IS_INTERRUPT(mcause)) {
|
||||
unsigned irq_id = mcause&(__riscv_xlen-1);
|
||||
switch(irq_id){
|
||||
case RISCV_INT_MTI:
|
||||
#ifdef NX_DEBUG
|
||||
printf("Timer interrupt being handled (pc=%lx)\n", mepc);
|
||||
#endif
|
||||
hwtimer_handler();
|
||||
_tx_timer_interrupt();
|
||||
break;
|
||||
#ifdef TX_THREAD_SMP_INTER_CORE_INTERRUPT
|
||||
case RISCV_INT_MSI:
|
||||
set_aclint_msip(aclint, csr_read_mhartid(), 0);
|
||||
break;
|
||||
#endif
|
||||
case RISCV_INT_MEI:
|
||||
puts("[INTERRUPT]: handler ext irq error!\n");
|
||||
while(1)
|
||||
;
|
||||
break;
|
||||
default:
|
||||
if(irq_handler[irq_id])
|
||||
irq_handler[irq_id]();
|
||||
else {
|
||||
printf("[INTERRUPT]: Unkown Interrupt %d!!\n", mcause&0xff);
|
||||
puts("[INTERRUPT]: now can't deal with the interrupt!\n");
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exception( mcause, mepc, mtval);
|
||||
}
|
||||
}
|
||||
78
port/moonlight/src/trap_vectored.c
Normal file
78
port/moonlight/src/trap_vectored.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Baremetal main program with timer interrupt.
|
||||
SPDX-License-Identifier: Unlicense
|
||||
|
||||
https://five-embeddev.com/
|
||||
|
||||
Tested with sifive-hifive-revb, but should not have any
|
||||
dependencies to any particular implementation.
|
||||
|
||||
*/
|
||||
|
||||
// RISC-V CSR definitions and access classes
|
||||
#include "riscv-csr.h"
|
||||
#include "riscv-interrupt.h"
|
||||
#include "hwtimer.h"
|
||||
#include "vector_table.h"
|
||||
|
||||
extern void _tx_timer_interrupt(void);
|
||||
|
||||
// Machine mode interrupt service routine
|
||||
|
||||
// Global to hold current timestamp, written in MTI handler.
|
||||
static volatile uint64_t timestamp = 0;
|
||||
|
||||
#define RISCV_MTVEC_MODE_VECTORED 1
|
||||
|
||||
int init_irq(void) {
|
||||
// Global interrupt disable
|
||||
csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK);
|
||||
csr_write_mie(0);
|
||||
|
||||
// Setup the IRQ handler entry point, set the mode to vectored
|
||||
csr_write_mtvec((uint_xlen_t) riscv_mtvec_table | RISCV_MTVEC_MODE_VECTORED);
|
||||
|
||||
// Enable MIE.MTI
|
||||
csr_set_bits_mie(MIE_MTI_BIT_MASK);
|
||||
|
||||
// Global interrupt enable
|
||||
csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK);
|
||||
|
||||
// Setup timer for 1 second interval
|
||||
hwtimer_init();
|
||||
|
||||
// Busy loop
|
||||
do {
|
||||
// Wait for timer interrupt
|
||||
__asm__ volatile ("wfi");
|
||||
// Try a synchronous exception.
|
||||
__asm__ volatile ("ecall");
|
||||
} while (1);
|
||||
|
||||
// Will not reach here
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
// Force the alignment for mtvec.BASE. A 'C' extension program could be aligned to to bytes.
|
||||
#pragma GCC optimize ("align-functions=4")
|
||||
// The 'riscv_mtvec_mti' function is added to the vector table by the vector_table.c
|
||||
void riscv_mtvec_mti(void) {
|
||||
hwtimer_handler();
|
||||
_tx_timer_interrupt();
|
||||
}
|
||||
// The 'riscv_mtvec_exception' function is added to the vector table by the vector_table.c
|
||||
// This function looks at the cause of the exception, if it is an 'ecall' instruction then increment a global counter.
|
||||
void riscv_mtvec_exception(void) {
|
||||
uint_xlen_t this_cause = csr_read_mcause();
|
||||
uint_xlen_t this_pc = csr_read_mepc();
|
||||
//uint_xlen_t this_value = csr_read_mtval();
|
||||
switch (this_cause) {
|
||||
case RISCV_EXCP_ENVIRONMENT_CALL_FROM_M_MODE:
|
||||
ecall_count++;
|
||||
// Make sure the return address is the instruction AFTER ecall
|
||||
csr_write_mepc(this_pc+4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
166
port/moonlight/src/vector_table.c
Normal file
166
port/moonlight/src/vector_table.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Baremetal main program with timer interrupt.
|
||||
SPDX-License-Identifier: Unlicense
|
||||
|
||||
https://five-embeddev.com/
|
||||
|
||||
Tested with sifive-hifive-revb, but should not have any
|
||||
dependencies to any particular implementation.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// Makes use of GCC interrupt and weak reference/alias attributes
|
||||
// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
|
||||
// https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html#RISC-V-Function-Attributes
|
||||
|
||||
// Vector table - not to be called.
|
||||
void riscv_mtvec_table(void) __attribute__ ((naked, section(".text.mtvec_table") ,aligned(256)));
|
||||
void riscv_stvec_table(void) __attribute__ ((naked, section(".text.stvec_table") ,aligned(256)));
|
||||
void riscv_utvec_table(void) __attribute__ ((naked, section(".text.utvec_table") ,aligned(256)));
|
||||
|
||||
// Default "NOP" implementations
|
||||
static void riscv_nop_machine(void) __attribute__ ((interrupt ("machine")) );
|
||||
static void riscv_nop_supervisor(void) __attribute__ ((interrupt ("supervisor")) );
|
||||
static void riscv_nop_user(void) __attribute__ ((interrupt ("user")) );
|
||||
|
||||
// Weak alias to the "NOP" implementations. If another function
|
||||
void riscv_mtvec_exception(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_msi(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_mti(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_mei(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_ssi(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_sti(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
|
||||
void riscv_mtvec_sei(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
|
||||
|
||||
void riscv_stvec_exception(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
|
||||
void riscv_stvec_ssi(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
|
||||
void riscv_stvec_sti(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
|
||||
void riscv_stvec_sei(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
|
||||
|
||||
void riscv_utvec_usi(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
|
||||
void riscv_utvec_uti(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
|
||||
void riscv_utvec_uei(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
|
||||
|
||||
#ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
|
||||
|
||||
void moonlight_mtvec_irq0(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq1(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq2(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq3(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq4(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq5(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq6(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq7(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq8(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq9(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq10(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq11(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq12(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq13(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq14(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
void moonlight_mtvec_irq15(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
|
||||
|
||||
#endif // #ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
|
||||
|
||||
#pragma GCC push_options
|
||||
|
||||
// Ensure the vector table is aligned.
|
||||
// The bottom 4 bits of MTVEC are ignored - so align to 16 bytes
|
||||
|
||||
// Vector table. Do not call!
|
||||
// Possible entries defined by mcause table
|
||||
// http://five-embeddev.com/riscv-isa-manual/latest/machine.html#sec:mcause
|
||||
//
|
||||
// When vectored interrupts are enabled, interrupt cause 0, which
|
||||
// corresponds to user-mode software interrupts, are vectored to the
|
||||
// same location as synchronous exceptions. This ambiguity does not
|
||||
// arise in practice, since user-mode software interrupts are either
|
||||
// disabled or delegated to user mode.
|
||||
void riscv_mtvec_table(void) {
|
||||
__asm__ volatile (
|
||||
".org riscv_mtvec_table + 0*4;"
|
||||
"jal zero,riscv_mtvec_exception;" /* 0 */
|
||||
".org riscv_mtvec_table + 1*4;"
|
||||
"jal zero,riscv_mtvec_ssi;" /* 1 */
|
||||
".org riscv_mtvec_table + 3*4;"
|
||||
"jal zero,riscv_mtvec_msi;" /* 3 */
|
||||
".org riscv_mtvec_table + 5*4;"
|
||||
"jal zero,riscv_mtvec_sti;" /* 5 */
|
||||
".org riscv_mtvec_table + 7*4;"
|
||||
"jal zero,riscv_mtvec_mti;" /* 7 */
|
||||
".org riscv_mtvec_table + 9*4;"
|
||||
"jal zero,riscv_mtvec_sei;" /* 9 */
|
||||
".org riscv_mtvec_table + 11*4;"
|
||||
"jal zero,riscv_mtvec_mei;" /* 11 */
|
||||
#ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
|
||||
".org riscv_mtvec_table + 16*4;"
|
||||
"jal moonlight_mtvec_irq0;"
|
||||
"jal moonlight_mtvec_irq1;"
|
||||
"jal moonlight_mtvec_irq2;"
|
||||
"jal moonlight_mtvec_irq3;"
|
||||
"jal moonlight_mtvec_irq4;"
|
||||
"jal moonlight_mtvec_irq5;"
|
||||
"jal moonlight_mtvec_irq6;"
|
||||
"jal moonlight_mtvec_irq7;"
|
||||
"jal moonlight_mtvec_irq8;"
|
||||
"jal moonlight_mtvec_irq9;"
|
||||
"jal moonlight_mtvec_irq10;"
|
||||
"jal moonlight_mtvec_irq11;"
|
||||
"jal moonlight_mtvec_irq12;"
|
||||
"jal moonlight_mtvec_irq13;"
|
||||
"jal moonlight_mtvec_irq14;"
|
||||
"jal moonlight_mtvec_irq15;"
|
||||
#endif
|
||||
: /* output: none */
|
||||
: /* input : immediate */
|
||||
: /* clobbers: none */
|
||||
);
|
||||
}
|
||||
// Vector table. Do not call!
|
||||
// See scause table for possible entries.
|
||||
// http://five-embeddev.com/riscv-isa-manual/latest/supervisor.html#sec:scause
|
||||
void riscv_stvec_table(void) {
|
||||
__asm__ volatile (
|
||||
".org riscv_stvec_table + 0*4;"
|
||||
"jal zero,riscv_stvec_exception;" /* 0 */
|
||||
".org riscv_stvec_table + 1*4;"
|
||||
"jal zero,riscv_stvec_ssi;" /* 1 */
|
||||
".org riscv_stvec_table + 5*4;"
|
||||
"jal zero,riscv_stvec_sti;" /* 5 */
|
||||
".org riscv_stvec_table + 9*4;"
|
||||
"jal zero,riscv_stvec_sei;" /* 9 */
|
||||
: /* output: none */
|
||||
: /* input : immediate */
|
||||
: /* clobbers: none */
|
||||
);
|
||||
}
|
||||
// Vector table. Do not call!
|
||||
void riscv_utvec_table(void) {
|
||||
__asm__ volatile (
|
||||
".org riscv_utvec_table + 0*4;"
|
||||
"jal zero,riscv_utvec_usi;" /* 0 */
|
||||
".org riscv_utvec_table + 4*4;"
|
||||
"jal zero,riscv_utvec_uti;" /* 4 */
|
||||
".org riscv_utvec_table + 8*4;"
|
||||
"jal zero,riscv_utvec_uei;" /* 8 */
|
||||
: /* output: none */
|
||||
: /* input : immediate */
|
||||
: /* clobbers: none */
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure all ISR functions are aligned.
|
||||
#pragma GCC optimize ("align-functions=4")
|
||||
|
||||
static void riscv_nop_machine(void) {
|
||||
// Nop machine mode interrupt.
|
||||
}
|
||||
static void riscv_nop_supervisor(void) {
|
||||
// Nop supervisor mode interrupt.
|
||||
}
|
||||
static void riscv_nop_user(void) {
|
||||
// Nop user mode interrupt.
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
Reference in New Issue
Block a user