Supervisor trap & claim MSI
This commit is contained in:
@ -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 ^
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -4,3 +4,5 @@
|
||||
|
||||
void aplic_init();
|
||||
|
||||
void aplic_enable_intr_s(uint32_t source, uint32_t msg);
|
||||
uint32_t aplic_claim_msi_s();
|
||||
|
@ -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)
|
||||
{
|
||||
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");
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
81
kernel/strap.s
Normal file
81
kernel/strap.s
Normal 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
|
@ -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();
|
||||
|
Reference in New Issue
Block a user