Keyboard Work - setting up PLIC, UART, Interrupts

This commit is contained in:
Liam Kerr 2026-02-10 01:21:49 +00:00
parent 4c0a4958a2
commit 50757427be
12 changed files with 295 additions and 68 deletions

View file

@ -2,7 +2,24 @@
#include <stdint.h>
#include <drivers/uart.h>
#include <syscon/syscon.h>
#include "memory.h"
#include <kernel/plic.h>
#include <kernel/interrupts.h>
#include <kernel/memory.h>
void interrupt_init()
{
kprint("Initialising Interrupts...");
uint64_t mstatus_val;
asm volatile("csrr %0, mstatus" : "=r"(mstatus_val));
mstatus_val |= (1 << MSTATUS_BIT_MIE);
asm volatile("csrw mstatus, %0" ::"r"(mstatus_val));
uint64_t mie_val;
asm volatile("csrr %0, mie" : "=r"(mie_val));
mie_val |= (1 << MIE_BIT_MEIE); //|(1 << MIE_BIT_MTIE);
asm volatile("csrw mie, %0" ::"r"(mie_val));
kputs("OK");
}
void kpanic(const char *reason)
{
@ -31,48 +48,74 @@ void kpanic_force()
void handle_trap()
{
kprint("\n!!! HARDWARE EXCEPTION DETECTED !!!\n");
// Read the 'mcause' register to see WHY we trapped
unsigned long cause;
__asm__ volatile("csrr %0, mcause" : "=r"(cause));
// fault address (if applicable)
uintptr_t mtval;
asm volatile("csrr %0, mtval" : "=r"(mtval));
// Check if the top bit is 1 (Interrupt) or 0 (Exception)
// For 64-bit RISC-V, the bit is 63
int is_interrupt = (cause >> 63) & 1;
switch (cause)
if (is_interrupt)
{
case 0:
kprint("Reason: Instruction Address Misaligned\n");
break;
case 1:
kprint("Reason: Instruction Access Fault\n");
break;
case 2:
kprint("Reason: Illegal Instruction\n");
break;
case 3:
kprint("Reason: Breakpoint (ebreak)\n");
break;
case 4:
kprint("Reason: Load Address Misaligned\n");
break;
case 5:
kprint("Reason: Load Access Fault\n");
break;
case 6:
kprint("Reason: Store/AMO Address Misaligned\n");
break;
case 7:
kprint("Reason: Store/AMO Access Fault\n");
break;
default:
kprintf("Reason: Unknown Exception Code %d\n", cause);
unsigned long code = cause & 0xfff;
handle_interrupt(code);
return;
}
kprintf("Faulting Address (if applicable): %x\n", mtval);
else
{
// fault address (if applicable)
uintptr_t mtval;
asm volatile("csrr %0, mtval" : "=r"(mtval));
heap_stats();
switch (cause)
{
case 0:
kpanic("Reason: Instruction Address Misaligned\n");
break;
case 1:
kpanic("Reason: Instruction Access Fault\n");
break;
case 2:
kpanic("Reason: Illegal Instruction\n");
break;
case 3:
kpanic("Reason: Breakpoint (ebreak)\n");
break;
case 4:
kpanic("Reason: Load Address Misaligned\n");
break;
case 5:
kpanic("Reason: Load Access Fault\n");
break;
case 6:
kpanic("Reason: Store/AMO Address Misaligned\n");
break;
case 7:
kpanic("Reason: Store/AMO Access Fault\n");
break;
default:
break;
// kpanic("Reason: Unknown Exception Code %d\n", cause);
}
kprintf("Faulting Address (if applicable): %x\n", mtval);
}
}
poweroff();
void handle_interrupt(unsigned long code)
{
switch (code)
{
case 7:
break; // timer Interrupt. Ignoring for now.
case 11:
volatile uint32_t *claim_reg = (uint32_t *)PLIC_CLAIM_COMPLETE;
uint32_t irq = *claim_reg;
if (irq == 10)
{
uart_handle_interrupt();
}
*claim_reg = irq;
break;
}
}