Supervisor trap & claim MSI

This commit is contained in:
2024-06-04 23:32:33 +02:00
parent f95c522b0a
commit d78b60f868
6 changed files with 158 additions and 36 deletions

View File

@ -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\vm.c -c -o build\vm.o
clang %CC_OPTS% kernel\spinlock.c -c -o build\spinlock.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\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 ^ ld.lld -T kernel\linker.lds -o build\kernel.elf ^
build\boot.o ^ build\boot.o ^
@ -20,3 +21,4 @@ ld.lld -T kernel\linker.lds -o build\kernel.elf ^
build\vm.o ^ build\vm.o ^
build\spinlock.o ^ build\spinlock.o ^
build\aplic.o ^ build\aplic.o ^
build\strap.o ^

View File

@ -1,5 +1,4 @@
#include "kernel/aplic.h" #include "kernel/aplic.h"
#include "kernel/spinlock.h"
static volatile char* APLIC_M = (volatile char*)0x0c00'0000; static volatile char* APLIC_M = (volatile char*)0x0c00'0000;
static volatile char* APLIC_S = (volatile char*)0x0d00'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); 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_seithreshold(0);
imsic_w_seidelivery(EIDELIVERY_ENABLED); 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;
} }

View File

@ -4,3 +4,5 @@
void aplic_init(); void aplic_init();
void aplic_enable_intr_s(uint32_t source, uint32_t msg);
uint32_t aplic_claim_msi_s();

View File

@ -11,29 +11,56 @@ extern uint32_t _bss_start;
extern uint32_t _bss_end; extern uint32_t _bss_end;
extern uint32_t _ram_end; extern uint32_t _ram_end;
void kstrap() #define UART_MSI 1
extern uint32_t strap;
void ktrap(uint32_t cause)
{ {
uint32_t scause; if ((cause & 0x8000'0000) == 0)
__asm__ volatile("csrr %0, scause" : "=r"(scause));
switch (scause)
{ {
case 0: panic("kstrap: Instruction address misaligned"); switch (cause)
case 1: panic("kstrap: Instruction access fault"); {
case 2: panic("kstrap: Illegal instruction"); case 0: panic("kstrap: Instruction address misaligned");
case 3: panic("kstrap: Breakpoint"); case 1: panic("kstrap: Instruction access fault");
case 4: panic("kstrap: Load address misaligned"); case 2: panic("kstrap: Illegal instruction");
case 5: panic("kstrap: Load access fault"); case 3: panic("kstrap: Breakpoint");
case 6: panic("kstrap: Store/AMO address misaligned"); case 4: panic("kstrap: Load address misaligned");
case 7: panic("kstrap: Store/AMO access fault"); case 5: panic("kstrap: Load access fault");
case 8: panic("kstrap: Environment call from U-mode"); case 6: panic("kstrap: Store/AMO address misaligned");
case 9: panic("kstrap: Environment call from S-mode"); case 7: panic("kstrap: Store/AMO access fault");
case 12: panic("kstrap: Instruction page fault"); case 8: panic("kstrap: Environment call from U-mode");
case 13: panic("kstrap: Load page fault"); case 9: panic("kstrap: Environment call from S-mode");
case 14: panic("kstrap: Reserved"); case 12: panic("kstrap: Instruction page fault");
case 15: panic("kstrap: Store/AMO page fault"); case 13: panic("kstrap: Load page fault");
case 18: panic("kstrap: Software check"); case 14: panic("kstrap: Reserved");
case 19: panic("kstrap: Hardware error"); case 15: panic("kstrap: Store/AMO page fault");
default: panic("kstrap: Unknown"); case 18: panic("kstrap: Software check");
case 19: panic("kstrap: Hardware error");
default: panic("kstrap: Unknown");
}
}
else
{
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(); kalloc_init();
kvm_init(); kvm_init();
aplic_init();
panic("kstart: end"); panic("kstart: end\n");
} }
void kinit() void kinit()
@ -80,7 +106,10 @@ void kinit()
w_sstatus(SSTATUS_SPIE | SSTATUS_SPP_S); w_sstatus(SSTATUS_SPIE | SSTATUS_SPP_S);
w_sie(SIE_SEIE); w_sie(SIE_SEIE);
w_sepc(&kstart); 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_pmpcfg0(PMPCFG_RW | PMPCFG_X | PMPCFG_TOR);
w_pmpaddr0(((uint32_t)&_ram_end) >> PMPADDR_SHIFT); w_pmpaddr0(((uint32_t)&_ram_end) >> PMPADDR_SHIFT);

81
kernel/strap.s Normal file
View File

@ -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

View File

@ -100,10 +100,10 @@ void kvm_init()
kvm_map(&_stack_start, &_stack_start, &_stack_end - &_stack_start, VM_RW); 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*)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*)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*)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*)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*)0x2800'0000, (void*)0x2800'0000, 0x1000, VM_RW); // IMSIC S
w_satp(SATP_MODE_SV32 | ((uint32_t)kroot >> 12)); w_satp(SATP_MODE_SV32 | ((uint32_t)kroot >> 12));
sfence_vma(); sfence_vma();