diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/aplic.c | 24 | ||||
-rw-r--r-- | kernel/aplic.h | 2 | ||||
-rw-r--r-- | kernel/start.c | 77 | ||||
-rw-r--r-- | kernel/strap.s | 81 | ||||
-rw-r--r-- | kernel/vm.c | 8 |
5 files changed, 156 insertions, 36 deletions
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();
|