summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/aplos.h4
-rw-r--r--src/interrupt.c115
-rw-r--r--src/main.c4
-rw-r--r--src/nasty.S33
-rw-r--r--src/paging.c12
5 files changed, 122 insertions, 46 deletions
diff --git a/src/aplos.h b/src/aplos.h
index e364eea..d9d6cdb 100644
--- a/src/aplos.h
+++ b/src/aplos.h
@@ -49,8 +49,12 @@ void disable_interrupts(void);
void enable_interrupts(void);
void set_gdt(struct table_reg *, uint64_t, uint64_t, uint64_t);
void set_idt(struct table_reg *);
+uint64_t get_cr2(void);
extern void (*isr_stubs[32])(void);
+/* paging.c */
+bool page_fault_handler(uint32_t);
+
/* panic.c */
void panic(void);
diff --git a/src/interrupt.c b/src/interrupt.c
index 97bc921..54f9947 100644
--- a/src/interrupt.c
+++ b/src/interrupt.c
@@ -1,41 +1,92 @@
#include "aplos.h"
-static char8_t *descriptions[256] = {
- [0] = u8"divide-by-zero-error",
- [1] = u8"debug",
- [2] = u8"non-maskable-interrupt",
- [3] = u8"breakpoint",
- [4] = u8"overflow",
- [5] = u8"bound-range",
- [6] = u8"invalid-opcode",
- [7] = u8"device-not-available",
- [8] = u8"double-fault",
- [9] = u8"coprocessor-segment-overrun",
- [10] = u8"invalid-tss",
- [11] = u8"segment-not-present",
- [12] = u8"stack",
- [13] = u8"general-protection",
- [14] = u8"page-fault",
- [16] = u8"x87 floating-point exception-pending",
- [17] = u8"alignment-check",
- [18] = u8"machine-check",
- [19] = u8"simd floating-point",
- [21] = u8"control protection",
- [28] = u8"hypervisor injection exception",
- [29] = u8"vmm communication exception",
- [30] = u8"security exception",
+struct handler {
+ char8_t *description;
+ bool (*fn)(uint32_t code);
+} handlers[256] = {
+ [0] = {
+ .description = u8"divide-by-zero-error"
+ },
+ [1] = {
+ .description = u8"debug"
+ },
+ [2] = {
+ .description = u8"non-maskable-interrupt"
+ },
+ [3] = {
+ .description = u8"breakpoint"
+ },
+ [4] = {
+ .description = u8"overflow"
+ },
+ [5] = {
+ .description = u8"bound-range"
+ },
+ [6] = {
+ .description = u8"invalid-opcode"
+ },
+ [7] = {
+ .description = u8"device-not-available"
+ },
+ [8] = {
+ .description = u8"double-fault"
+ },
+ [9] = {
+ .description = u8"coprocessor-segment-overrun"
+ },
+ [10] = {
+ .description = u8"invalid-tss"
+ },
+ [11] = {
+ .description = u8"segment-not-present"
+ },
+ [12] = {
+ .description = u8"stack"
+ },
+ [13] = {
+ .description = u8"general-protection"
+ },
+ [14] = {
+ .description = u8"page-fault",
+ .fn = page_fault_handler
+ },
+ [16] = {
+ .description = u8"x87 floating-point exception-pending"
+ },
+ [17] = {
+ .description = u8"alignment-check"
+ },
+ [18] = {
+ .description = u8"machine-check"
+ },
+ [19] = {
+ .description = u8"simd floating-point"
+ },
+ [21] = {
+ .description = u8"control protection"
+ },
+ [28] = {
+ .description = u8"hypervisor injection exception"
+ },
+ [29] = {
+ .description = u8"vmm communication exception"
+ },
+ [30] = {
+ .description = u8"security exception"
+ }
};
void
-interrupt_handler(uint8_t n)
+interrupt_handler(uint8_t n, uint32_t code)
{
- char8_t *desc = descriptions[n];
-
- print(u8"Got interrupt: %u8", n);
- if(desc)
- print(u8" (%s)", desc);
- print(u8"\n");
- panic();
+ struct handler *h = handlers+n;
+ bool handled;
+ if(h->fn)
+ handled = h->fn(code);
+ if(!handled){
+ print(u8"Unhandled interrupt: %u8 (%s) with error code %x32\n", n, h->description ? h->description : u8"???", code);
+ panic();
+ }
}
diff --git a/src/main.c b/src/main.c
index a0c0ebc..cfec00f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,10 +12,6 @@ main(struct boot_info *info)
welcome();
print(u8"CPU count: %u64\n", cpu_count());
print_memmap(info);
-
- /* Uncomment lines below to trigger a page fault (to see if the interrupts are setup correctly) */
-// uint64_t *silly = (uint64_t *)0x1234;
-// print(u8"Fun: %u64\n", *silly);
}
static void
diff --git a/src/nasty.S b/src/nasty.S
index 3f1c569..ac9fc91 100644
--- a/src/nasty.S
+++ b/src/nasty.S
@@ -37,6 +37,11 @@ enable_interrupts:
sti
ret
+.global get_cr2
+get_cr2:
+ mov rax, cr2
+ ret
+
#define DEFINE_ISRS \
ISR(0) \
ISR(1) \
@@ -46,20 +51,20 @@ enable_interrupts:
ISR(5) \
ISR(6) \
ISR(7) \
- ISR(8) \
+ ISR_E(8) \
ISR(9) \
- ISR(10) \
- ISR(11) \
- ISR(12) \
- ISR(13) \
- ISR(14) \
+ ISR_E(10) \
+ ISR_E(11) \
+ ISR_E(12) \
+ ISR_E(13) \
+ ISR_E(14) \
ISR(15) \
ISR(16) \
- ISR(17) \
+ ISR_E(17) \
ISR(18) \
ISR(19) \
ISR(20) \
- ISR(21) \
+ ISR_E(21) \
ISR(22) \
ISR(23) \
ISR(24) \
@@ -75,13 +80,21 @@ enable_interrupts:
#define ISR(n) \
isr_stub_##n: \
mov rdi, n; \
+ mov rsi, 0; \
call interrupt_handler; \
iretq;
+#define ISR_E(n) \
+isr_stub_##n: \
+ pop rsi; \
+ mov rdi, n; \
+ call interrupt_handler;
+ iretq;
DEFINE_ISRS
#undef ISR
+#undef ISR_E
-#define ISR(n) \
- .quad isr_stub_##n;
+#define ISR(n) .quad isr_stub_##n;
+#define ISR_E(n) .quad isr_stub_##n;
.section .data
.global isr_stubs
diff --git a/src/paging.c b/src/paging.c
new file mode 100644
index 0000000..539b26a
--- /dev/null
+++ b/src/paging.c
@@ -0,0 +1,12 @@
+#include "aplos.h"
+
+bool
+page_fault_handler(uint32_t code)
+{
+ int write = code&0x2;
+
+ uint64_t addr = get_cr2();
+ print(u8"Page fault trying to %s %p\n", write ? u8"write to" : u8"read from", addr);
+
+ return false; /* We didn't actually handle it */
+}