URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Details |
Compare with Previous |
View Log
| Line No. |
Rev |
Author |
Line |
| 1 |
5 |
sergeykhbr |
/******************************************************************************
|
| 2 |
|
|
* @file
|
| 3 |
|
|
* @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved.
|
| 4 |
|
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
| 5 |
|
|
* @brief General interrupt handler called from assembler.
|
| 6 |
|
|
******************************************************************************/
|
| 7 |
|
|
|
| 8 |
|
|
#include <string.h>
|
| 9 |
|
|
#include "axi_maps.h"
|
| 10 |
|
|
|
| 11 |
|
|
typedef void (*IRQ_HANDLER)(int idx, void *args);
|
| 12 |
|
|
|
| 13 |
|
|
typedef union csr_mcause_type {
|
| 14 |
|
|
struct bits_type {
|
| 15 |
|
|
uint64_t code : 63; // 11 - Machine external interrupt
|
| 16 |
|
|
uint64_t irq : 1;
|
| 17 |
|
|
} bits;
|
| 18 |
|
|
uint64_t value;
|
| 19 |
|
|
} csr_mcause_type;
|
| 20 |
|
|
|
| 21 |
|
|
extern void print_uart(const char *buf, int sz);
|
| 22 |
|
|
extern void print_uart_hex(long val);
|
| 23 |
|
|
|
| 24 |
|
|
long handle_trap(long cause, long epc, long long regs[32]) {
|
| 25 |
|
|
/**
|
| 26 |
|
|
* Pending interrupt bit is cleared in the crt.S file by calling:
|
| 27 |
|
|
* csrc mip, MIP_MSIP
|
| 28 |
|
|
* If we woudn't do it the interrupt handler will be called infinitly
|
| 29 |
|
|
*
|
| 30 |
|
|
* Rise interrupt from the software maybe done sending a self-IPI:
|
| 31 |
|
|
* csrwi mipi, 0
|
| 32 |
|
|
*/
|
| 33 |
|
|
irqctrl_map *p_irqctrl = (irqctrl_map *)ADDR_NASTI_SLAVE_IRQCTRL;
|
| 34 |
|
|
IRQ_HANDLER irq_handler = (IRQ_HANDLER)p_irqctrl->isr_table;
|
| 35 |
|
|
uint32_t pending;
|
| 36 |
|
|
csr_mcause_type mcause;
|
| 37 |
|
|
|
| 38 |
|
|
mcause.value = cause;
|
| 39 |
|
|
p_irqctrl->dbg_cause = cause;
|
| 40 |
|
|
p_irqctrl->dbg_epc = epc;
|
| 41 |
|
|
|
| 42 |
|
|
p_irqctrl->irq_lock = 1;
|
| 43 |
|
|
pending = p_irqctrl->irq_pending;
|
| 44 |
|
|
p_irqctrl->irq_clear = pending;
|
| 45 |
|
|
p_irqctrl->irq_lock = 0;
|
| 46 |
|
|
|
| 47 |
|
|
if (mcause.bits.irq == 0x1 && mcause.bits.code == 11) {
|
| 48 |
|
|
for (int i = 0; i < CFG_IRQ_TOTAL; i++) {
|
| 49 |
|
|
if (pending & 0x1) {
|
| 50 |
|
|
p_irqctrl->irq_cause_idx = i;
|
| 51 |
|
|
irq_handler(i, NULL);
|
| 52 |
|
|
}
|
| 53 |
|
|
pending >>= 1;
|
| 54 |
|
|
}
|
| 55 |
|
|
} else {
|
| 56 |
|
|
print_uart("mcause:", 7);
|
| 57 |
|
|
print_uart_hex(cause);
|
| 58 |
|
|
print_uart(",mepc:", 6);
|
| 59 |
|
|
print_uart_hex(epc);
|
| 60 |
|
|
print_uart("\r\n", 2);
|
| 61 |
|
|
/// Exception trap
|
| 62 |
|
|
((gpio_map *)ADDR_NASTI_SLAVE_GPIO)->led = 0xF0;
|
| 63 |
|
|
while (1) {}
|
| 64 |
|
|
}
|
| 65 |
|
|
|
| 66 |
|
|
return epc;
|
| 67 |
|
|
}
|
© copyright 1999-2025
OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.