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\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 ^
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -11,11 +11,15 @@ 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)
|
switch (cause)
|
||||||
{
|
{
|
||||||
case 0: panic("kstrap: Instruction address misaligned");
|
case 0: panic("kstrap: Instruction address misaligned");
|
||||||
case 1: panic("kstrap: Instruction access fault");
|
case 1: panic("kstrap: Instruction access fault");
|
||||||
@ -36,6 +40,29 @@ void kstrap()
|
|||||||
default: panic("kstrap: Unknown");
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void uart_init()
|
void uart_init()
|
||||||
{
|
{
|
||||||
@ -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
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(&_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();
|
||||||
|
Reference in New Issue
Block a user