Add the non-standard "IO interrupt" vector used by lowRISC.

For now they provide UART irq only.

Sponsored by:	DARPA, AFRL
Sponsored by:	HEIF5
This commit is contained in:
Ruslan Bukin 2016-04-26 12:56:44 +00:00
parent 6c0d33bcb3
commit 00106e52c2
4 changed files with 29 additions and 3 deletions

View File

@ -60,6 +60,8 @@ enum {
IRQ_SOFTWARE,
IRQ_TIMER,
IRQ_HTIF,
IRQ_COP, /* lowRISC only */
IRQ_UART, /* lowRISC only */
NIRQS
};

View File

@ -47,7 +47,8 @@
#define ECALL_SEND_IPI 0x07
#define ECALL_CLEAR_IPI 0x08
#define ECALL_HTIF_LOWPUTC 0x09
#define ECALL_MIE_SET 0x10
#define ECALL_MIE_SET 0x0a
#define ECALL_IO_IRQ_MASK 0x0b
#define EXCP_SHIFT 0
#define EXCP_MASK (0xf << EXCP_SHIFT)
@ -119,6 +120,7 @@
#define NCSRS 4096
#define CSR_IPI 0x783
#define CSR_IO_IRQ 0x7c0 /* lowRISC only? */
#define XLEN 8
#define INSN_SIZE 4

View File

@ -270,18 +270,27 @@ supervisor_trap:
machine_interrupt:
/* Type of interrupt ? */
csrr t0, mcause
andi t0, t0, 3
andi t0, t0, EXCP_MASK
li t1, 0
beq t1, t0, software_interrupt
li t1, 1
beq t1, t0, timer_interrupt
li t1, 2
beq t1, t0, htif_interrupt
li t1, 4
beq t1, t0, io_interrupt /* lowRISC only */
/* not reached */
1:
j 1b
io_interrupt:
/* Disable IO interrupts so we can go to supervisor mode */
csrwi CSR_IO_IRQ, 0
/* Handle the trap in supervisor mode */
j exit_mrts
software_interrupt:
li t0, MIP_MSIP
csrc mip, t0
@ -307,7 +316,7 @@ software_interrupt:
j exit
1:
/* Serve a trap in supervisor mode */
/* Handle the trap in supervisor mode */
j exit_mrts
timer_interrupt:
@ -415,6 +424,12 @@ supervisor_call:
beq t5, t4, htif_lowputc
li t4, ECALL_MIE_SET
beq t5, t4, mie_set
li t4, ECALL_IO_IRQ_MASK
beq t5, t4, io_irq_mask
j exit_next_instr
io_irq_mask:
csrw CSR_IO_IRQ, t6
j exit_next_instr
mie_set:

View File

@ -101,6 +101,9 @@ riscv_mask_irq(void *source)
case IRQ_SOFTWARE:
csr_clear(sie, SIE_SSIE);
break;
case IRQ_UART:
machine_command(ECALL_IO_IRQ_MASK, 0);
break;
default:
panic("Unknown irq %d\n", irq);
}
@ -120,6 +123,9 @@ riscv_unmask_irq(void *source)
case IRQ_SOFTWARE:
csr_set(sie, SIE_SSIE);
break;
case IRQ_UART:
machine_command(ECALL_IO_IRQ_MASK, 1);
break;
default:
panic("Unknown irq %d\n", irq);
}
@ -203,6 +209,7 @@ riscv_cpu_intr(struct trapframe *frame)
active_irq = (frame->tf_scause & EXCP_MASK);
switch (active_irq) {
case IRQ_UART:
case IRQ_SOFTWARE:
case IRQ_TIMER:
event = intr_events[active_irq];