From d78b60f868f40cefe3ac958800ac828f2eafc81c Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 4 Jun 2024 23:32:33 +0200 Subject: Supervisor trap & claim MSI --- build.bat | 2 ++ kernel/aplic.c | 24 +++++++++++------ kernel/aplic.h | 2 ++ kernel/start.c | 77 ++++++++++++++++++++++++++++++++++++++----------------- kernel/strap.s | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/vm.c | 8 +++--- 6 files changed, 158 insertions(+), 36 deletions(-) create mode 100644 kernel/strap.s diff --git a/build.bat b/build.bat index 98e0cf3..31c1456 100644 --- a/build.bat +++ b/build.bat @@ -11,6 +11,7 @@ clang %CC_OPTS% kernel\lib.c -c -o build\lib.o clang %CC_OPTS% kernel\vm.c -c -o build\vm.o clang %CC_OPTS% kernel\spinlock.c -c -o build\spinlock.o clang %CC_OPTS% kernel\aplic.c -c -o build\aplic.o +clang %CC_OPTS% kernel\strap.s -c -o build\strap.o ld.lld -T kernel\linker.lds -o build\kernel.elf ^ build\boot.o ^ @@ -20,3 +21,4 @@ ld.lld -T kernel\linker.lds -o build\kernel.elf ^ build\vm.o ^ build\spinlock.o ^ build\aplic.o ^ + build\strap.o ^ diff --git a/kernel/aplic.c b/kernel/aplic.c index 61a42c3..a5b91be 100644 --- a/kernel/aplic.c +++ b/kernel/aplic.c @@ -1,5 +1,4 @@ #include "kernel/aplic.h" -#include "kernel/spinlock.h" static volatile char* APLIC_M = (volatile char*)0x0c00'0000; static volatile char* APLIC_S = (volatile char*)0x0d00'0000; @@ -109,13 +108,22 @@ void aplic_init() aplic_w_smsiaddr(APLIC_M, (void*)IMSIC_S); - uint32_t uart_source = 10; - aplic_w_sourcecfg_delegate(APLIC_M, uart_source, 0); - aplic_w_sourcecfg_active_high(APLIC_S, uart_source); - aplic_w_target_msi(APLIC_S, uart_source, 0, 0, uart_source); - aplic_enable_intr(APLIC_S, uart_source); - imsic_w_seithreshold(0); imsic_w_seidelivery(EIDELIVERY_ENABLED); - imsic_s_seie(uart_source); +} + +void aplic_enable_intr_s(uint32_t source, uint32_t msg) +{ + aplic_w_sourcecfg_delegate(APLIC_M, source, 0); + aplic_w_sourcecfg_active_high(APLIC_S, source); + aplic_w_target_msi(APLIC_S, source, 0, 0, msg); + aplic_enable_intr(APLIC_S, source); + imsic_s_seie(msg); +} + +uint32_t aplic_claim_msi_s() +{ + uint32_t intr; + __asm__ volatile("csrrw %0, stopei, zero" : "=r"(intr)); + return intr >> 16; } diff --git a/kernel/aplic.h b/kernel/aplic.h index b96363d..af12e9d 100644 --- a/kernel/aplic.h +++ b/kernel/aplic.h @@ -4,3 +4,5 @@ void aplic_init(); +void aplic_enable_intr_s(uint32_t source, uint32_t msg); +uint32_t aplic_claim_msi_s(); diff --git a/kernel/start.c b/kernel/start.c index 859ae5d..ddd31c2 100644 --- a/kernel/start.c +++ b/kernel/start.c @@ -11,29 +11,56 @@ extern uint32_t _bss_start; extern uint32_t _bss_end; extern uint32_t _ram_end; -void kstrap() +#define UART_MSI 1 + +extern uint32_t strap; + +void ktrap(uint32_t cause) { - uint32_t scause; - __asm__ volatile("csrr %0, scause" : "=r"(scause)); - switch (scause) + if ((cause & 0x8000'0000) == 0) + { + switch (cause) + { + case 0: panic("kstrap: Instruction address misaligned"); + case 1: panic("kstrap: Instruction access fault"); + case 2: panic("kstrap: Illegal instruction"); + case 3: panic("kstrap: Breakpoint"); + case 4: panic("kstrap: Load address misaligned"); + case 5: panic("kstrap: Load access fault"); + case 6: panic("kstrap: Store/AMO address misaligned"); + case 7: panic("kstrap: Store/AMO access fault"); + case 8: panic("kstrap: Environment call from U-mode"); + case 9: panic("kstrap: Environment call from S-mode"); + case 12: panic("kstrap: Instruction page fault"); + case 13: panic("kstrap: Load page fault"); + case 14: panic("kstrap: Reserved"); + case 15: panic("kstrap: Store/AMO page fault"); + case 18: panic("kstrap: Software check"); + case 19: panic("kstrap: Hardware error"); + default: panic("kstrap: Unknown"); + } + } + else { - case 0: panic("kstrap: Instruction address misaligned"); - case 1: panic("kstrap: Instruction access fault"); - case 2: panic("kstrap: Illegal instruction"); - case 3: panic("kstrap: Breakpoint"); - case 4: panic("kstrap: Load address misaligned"); - case 5: panic("kstrap: Load access fault"); - case 6: panic("kstrap: Store/AMO address misaligned"); - case 7: panic("kstrap: Store/AMO access fault"); - case 8: panic("kstrap: Environment call from U-mode"); - case 9: panic("kstrap: Environment call from S-mode"); - case 12: panic("kstrap: Instruction page fault"); - case 13: panic("kstrap: Load page fault"); - case 14: panic("kstrap: Reserved"); - case 15: panic("kstrap: Store/AMO page fault"); - case 18: panic("kstrap: Software check"); - case 19: panic("kstrap: Hardware error"); - default: panic("kstrap: Unknown"); + cause = cause & 0x7fff'ffff; + if (cause == 9) + { + uint32_t msi = aplic_claim_msi_s(); + switch (msi) + { + case UART_MSI: + { + volatile char* UART_BASE = (volatile char*)0x1000'0000; + *UART_BASE = *UART_BASE; + break; + } + default: panic("Unknown MSI"); + } + } + else + { + panic("Interrupt"); + } } } @@ -57,9 +84,8 @@ void kstart() kalloc_init(); kvm_init(); - aplic_init(); - panic("kstart: end"); + panic("kstart: end\n"); } void kinit() @@ -80,7 +106,10 @@ void kinit() w_sstatus(SSTATUS_SPIE | SSTATUS_SPP_S); w_sie(SIE_SEIE); w_sepc(&kstart); - w_stvec(&kstrap); + w_stvec(&strap); + + aplic_init(); + aplic_enable_intr_s(10, UART_MSI); w_pmpcfg0(PMPCFG_RW | PMPCFG_X | PMPCFG_TOR); w_pmpaddr0(((uint32_t)&_ram_end) >> PMPADDR_SHIFT); diff --git a/kernel/strap.s b/kernel/strap.s new file mode 100644 index 0000000..079c579 --- /dev/null +++ b/kernel/strap.s @@ -0,0 +1,81 @@ +.option norvc +.section .text + +.global ktrap + +.set FRAME_SIZE, 4 * 31 + +.global strap +strap: + addi sp, sp, -FRAME_SIZE + + sw x1, (0 * 4)(sp) + sw x2, (1 * 4)(sp) + sw x3, (2 * 4)(sp) + sw x4, (3 * 4)(sp) + sw x5, (4 * 4)(sp) + sw x6, (5 * 4)(sp) + sw x7, (6 * 4)(sp) + sw x8, (7 * 4)(sp) + sw x9, (8 * 4)(sp) + sw x10, (9 * 4)(sp) + sw x11, (10 * 4)(sp) + sw x12, (11 * 4)(sp) + sw x13, (12 * 4)(sp) + sw x14, (13 * 4)(sp) + sw x15, (14 * 4)(sp) + sw x16, (15 * 4)(sp) + sw x17, (16 * 4)(sp) + sw x18, (17 * 4)(sp) + sw x19, (18 * 4)(sp) + sw x20, (19 * 4)(sp) + sw x21, (20 * 4)(sp) + sw x22, (21 * 4)(sp) + sw x23, (22 * 4)(sp) + sw x24, (23 * 4)(sp) + sw x25, (24 * 4)(sp) + sw x26, (25 * 4)(sp) + sw x27, (26 * 4)(sp) + sw x28, (27 * 4)(sp) + sw x29, (28 * 4)(sp) + sw x30, (29 * 4)(sp) + sw x31, (30 * 4)(sp) + + csrr a0, scause + call ktrap + + lw x1, (0 * 4)(sp) + lw x2, (1 * 4)(sp) + lw x3, (2 * 4)(sp) + lw x4, (3 * 4)(sp) + lw x5, (4 * 4)(sp) + lw x6, (5 * 4)(sp) + lw x7, (6 * 4)(sp) + lw x8, (7 * 4)(sp) + lw x9, (8 * 4)(sp) + lw x10, (9 * 4)(sp) + lw x11, (10 * 4)(sp) + lw x12, (11 * 4)(sp) + lw x13, (12 * 4)(sp) + lw x14, (13 * 4)(sp) + lw x15, (14 * 4)(sp) + lw x16, (15 * 4)(sp) + lw x17, (16 * 4)(sp) + lw x18, (17 * 4)(sp) + lw x19, (18 * 4)(sp) + lw x20, (19 * 4)(sp) + lw x21, (20 * 4)(sp) + lw x22, (21 * 4)(sp) + lw x23, (22 * 4)(sp) + lw x24, (23 * 4)(sp) + lw x25, (24 * 4)(sp) + lw x26, (25 * 4)(sp) + lw x27, (26 * 4)(sp) + lw x28, (27 * 4)(sp) + lw x29, (28 * 4)(sp) + lw x30, (29 * 4)(sp) + lw x31, (30 * 4)(sp) + + addi sp, sp, FRAME_SIZE + + sret diff --git a/kernel/vm.c b/kernel/vm.c index 8ca6666..f4c349c 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -100,10 +100,10 @@ void kvm_init() kvm_map(&_stack_start, &_stack_start, &_stack_end - &_stack_start, VM_RW); kvm_map((void*)0x1000'0000, (void*)0x1000'0000, PAGE_SIZE, VM_RW); // UART - kvm_map((void*)0x0c00'0000, (void*)0x0c00'0000, 0x8000, VM_RW); // APLIC M - kvm_map((void*)0x0d00'0000, (void*)0x0d00'0000, 0x8000, VM_RW); // APLIC S - kvm_map((void*)0x2400'0000, (void*)0x2400'0000, 0x1000, VM_RW); // IMSIC M - kvm_map((void*)0x2800'0000, (void*)0x2800'0000, 0x1000, VM_RW); // IMSIC S + // kvm_map((void*)0x0c00'0000, (void*)0x0c00'0000, 0x8000, VM_RW); // APLIC M + // kvm_map((void*)0x0d00'0000, (void*)0x0d00'0000, 0x8000, VM_RW); // APLIC S + // kvm_map((void*)0x2400'0000, (void*)0x2400'0000, 0x1000, VM_RW); // IMSIC M + // kvm_map((void*)0x2800'0000, (void*)0x2800'0000, 0x1000, VM_RW); // IMSIC S w_satp(SATP_MODE_SV32 | ((uint32_t)kroot >> 12)); sfence_vma(); -- cgit