initial commit
This commit is contained in:
78
port/moonlight/trap_vectored.c
Normal file
78
port/moonlight/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
|
||||
Reference in New Issue
Block a user