diff --git a/plic.c b/plic.c new file mode 100644 index 0000000..0f19ab0 --- /dev/null +++ b/plic.c @@ -0,0 +1,63 @@ +#include "types.h" +#include "param.h" +#include "memlayout.h" +#include "riscv.h" +#include "defs.h" + +// +// the riscv Platform Level Interrupt Controller (PLIC). +// + +void +plicinit(void) +{ + // set uart's priority to be non-zero (otherwise disabled). + *(uint32*)(PLIC + UART0_IRQ*4) = 1; +} + +void +plicinithart(void) +{ + int hart = cpuid(); + + // set uart's enable bit for this hart's S-mode. + //*(uint32*)(PLIC + 0x2080)= (1 << UART0_IRQ); + *(uint32*)PLIC_SENABLE(hart)= (1 << UART0_IRQ); + + // set this hart's S-mode priority threshold to 0. + //*(uint32*)(PLIC + 0x201000) = 0; + *(uint32*)PLIC_SPRIORITY(hart) = 0; +} + +// return a bitmap of which IRQs are waiting +// to be served. +uint64 +plic_pending(void) +{ + uint64 mask; + + //mask = *(uint32*)(PLIC + 0x1000); + //mask |= (uint64)*(uint32*)(PLIC + 0x1004) << 32; + mask = *(uint64*)PLIC_PENDING; + + return mask; +} + +// ask the PLIC what interrupt we should serve. +int +plic_claim(void) +{ + int hart = cpuid(); + //int irq = *(uint32*)(PLIC + 0x201004); + int irq = *(uint32*)PLIC_SCLAIM(hart); + return irq; +} + +// tell the PLIC we've served this IRQ. +void +plic_complete(int irq) +{ + int hart = cpuid(); + //*(uint32*)(PLIC + 0x201004) = irq; + *(uint32*)PLIC_SCLAIM(hart) = irq; +}