Files
ThreadX4TGFS/port/moonlight/trap_vectored.c
2026-01-27 20:58:23 +01:00

78 lines
2.3 KiB
C

/*
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