summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/include/hilbert/kernel/serial.hpp27
-rw-r--r--kernel/makefile2
-rw-r--r--kernel/source/entry.cpp3
-rw-r--r--kernel/source/interrupts.asm80
-rw-r--r--kernel/source/interrupts.cpp37
-rw-r--r--kernel/source/serial.asm58
6 files changed, 169 insertions, 38 deletions
diff --git a/kernel/include/hilbert/kernel/serial.hpp b/kernel/include/hilbert/kernel/serial.hpp
new file mode 100644
index 0000000..e7a44f2
--- /dev/null
+++ b/kernel/include/hilbert/kernel/serial.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <stdint.h>
+
+namespace hilbert::kernel {
+
+ extern "C" void serial_init();
+
+ extern "C" void serial_putchar(char ch);
+
+ static inline void serial_putstr(const char *str) {
+ while (*str) {
+ serial_putchar(*str);
+ ++str;
+ }
+ }
+
+ template <int digits, int dot_every = 4>
+ static inline void serial_puthex(uint64_t n) {
+ for (int d = digits - 1; d >= 0; --d) {
+ serial_putchar("0123456789abcdef"[(n >> (d * 4)) & 0xf]);
+ if (d % dot_every == 0 && d != 0)
+ serial_putchar('.');
+ }
+ }
+
+}
diff --git a/kernel/makefile b/kernel/makefile
index 1cb2d52..27565f7 100644
--- a/kernel/makefile
+++ b/kernel/makefile
@@ -2,7 +2,7 @@ SOURCES = \
storage/bd/memory.cpp storage/fs/tarfs.cpp application.asm application.cpp \
framebuffer.cpp interrupts.asm interrupts.cpp allocator.cpp storage.cpp \
syscall.cpp utility.cpp paging.asm paging.cpp entry.cpp input.cpp panic.cpp \
- vfile.cpp
+ vfile.cpp serial.asm
build/%.asm.o: source/%.asm
@mkdir -p $(@D)
diff --git a/kernel/source/entry.cpp b/kernel/source/entry.cpp
index 820b107..5db3515 100644
--- a/kernel/source/entry.cpp
+++ b/kernel/source/entry.cpp
@@ -3,6 +3,7 @@
#include <hilbert/kernel/application.hpp>
#include <hilbert/kernel/framebuffer.hpp>
#include <hilbert/kernel/paging.hpp>
+#include <hilbert/kernel/serial.hpp>
#include <hilbert/kernel/input.hpp>
#include <hilbert/kernel/panic.hpp>
#include <hilbert/kernel/vfile.hpp>
@@ -97,6 +98,8 @@ static bool have_initfs;
extern "C" [[noreturn]] void entry() {
+ serial_init();
+
//TODO?: maybe we should check if the limine requests were
// fulfilled and display some error message if not
diff --git a/kernel/source/interrupts.asm b/kernel/source/interrupts.asm
index e0c3cdb..e4912ee 100644
--- a/kernel/source/interrupts.asm
+++ b/kernel/source/interrupts.asm
@@ -227,19 +227,51 @@ section .bss
section .text
+isr_start:
+
+ push rcx
+ mov rcx, qword [rsp + 8]
+ mov qword [rsp + 8], rax
+ push rdx
+ push rdi
+ push rsi
+ push r8
+ push r9
+ push r10
+ push r11
+ push rcx
+
+ ;this is a complete hack but it works
+ mov rdi, qword [rsp + 10 * 8 + 4 * 8]
+ cmp rdi, 0x38
+ je .fix_ss
+ ret
+
+.fix_ss:
+ mov qword [rsp + 10 * 8 + 4 * 8], 0x3b
+ ret
+
+isr_end:
+
+ pop rcx
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rsi
+ pop rdi
+ pop rdx
+ mov rax, qword [rsp + 8]
+ mov qword [rsp + 8], rcx
+ pop rcx
+
+ ret
+
extern on_keyboard_interrupt
keyboard_isr:
- push r11
- push r10
- push r9
- push r8
- push rsi
- push rdi
- push rdx
- push rcx
- push rax
+ call isr_start
call wait_read_ps2
in al, 0x60
@@ -250,15 +282,7 @@ keyboard_isr:
mov al, 0x20
out 0x20, al
- pop rax
- pop rcx
- pop rdx
- pop rdi
- pop rsi
- pop r8
- pop r9
- pop r10
- pop r11
+ call isr_end
iretq
@@ -266,15 +290,7 @@ extern on_mouse_interrupt
mouse_isr:
- push r11
- push r10
- push r9
- push r8
- push rsi
- push rdi
- push rdx
- push rcx
- push rax
+ call isr_start
call wait_read_ps2
in al, 0x60
@@ -286,15 +302,7 @@ mouse_isr:
out 0x20, al
out 0xa0, al
- pop rax
- pop rcx
- pop rdx
- pop rdi
- pop rsi
- pop r8
- pop r9
- pop r10
- pop r11
+ call isr_end
iretq
diff --git a/kernel/source/interrupts.cpp b/kernel/source/interrupts.cpp
index f8e613e..4046021 100644
--- a/kernel/source/interrupts.cpp
+++ b/kernel/source/interrupts.cpp
@@ -1,4 +1,5 @@
#include <hilbert/kernel/framebuffer.hpp>
+#include <hilbert/kernel/serial.hpp>
#include <hilbert/kernel/input.hpp>
#include <hilbert/kernel/panic.hpp>
@@ -36,13 +37,47 @@ struct [[gnu::packed]] exception_info_t {
extern exception_info_t exception_info;
+static inline void print_reg(const char *regname, uint64_t value) {
+ serial_putstr(" ");
+ serial_putstr(regname);
+ serial_putstr(" = 0x");
+ serial_puthex<16>(value);
+ serial_putchar('\n');
+}
+
extern "C" [[noreturn]] void print_exception() {
//so exception_info's type is known by gdb
exception_info_t the_exception_info = exception_info;
(void)the_exception_info;
- //TODO: log exception, and recover if possible.
+ serial_putstr("exception 0x");
+ serial_puthex<2>(exception_info.exception_number);
+ serial_putchar('\n');
+
+ if (exception_info.has_error)
+ print_reg("error code", exception_info.error);
+
+ print_reg("rflags", exception_info.rflags);
+ print_reg("rip", exception_info.rip);
+ print_reg("cr2", exception_info.cr2);
+ print_reg("cr3", exception_info.cr3);
+ print_reg("rax", exception_info.rax);
+ print_reg("rbx", exception_info.rbx);
+ print_reg("rcx", exception_info.rcx);
+ print_reg("rdx", exception_info.rdx);
+ print_reg("rdi", exception_info.rdi);
+ print_reg("rsi", exception_info.rsi);
+ print_reg("rbp", exception_info.rbp);
+ print_reg("rsp", exception_info.rsp);
+ print_reg("r8 ", exception_info.r8 );
+ print_reg("r9 ", exception_info.r9 );
+ print_reg("r10", exception_info.r10);
+ print_reg("r11", exception_info.r11);
+ print_reg("r12", exception_info.r12);
+ print_reg("r13", exception_info.r13);
+ print_reg("r14", exception_info.r14);
+ print_reg("r15", exception_info.r15);
panic(0xba40bb);
diff --git a/kernel/source/serial.asm b/kernel/source/serial.asm
new file mode 100644
index 0000000..071e525
--- /dev/null
+++ b/kernel/source/serial.asm
@@ -0,0 +1,58 @@
+bits 64
+
+global serial_init
+global serial_putchar
+
+section .text
+
+serial_init:
+
+ xor al, al
+ mov dx, 0x03f9
+ out dx, al
+
+ mov al, 0x80
+ mov dx, 0x03fb
+ out dx, al
+
+ mov al, 0x03
+ mov dx, 0x03f8
+ out dx, al
+
+ xor al, al
+ mov dx, 0x03f9
+ out dx, al
+
+ mov al, 0x03
+ mov dx, 0x03fb
+ out dx, al
+
+ mov al, 0xc7
+ mov dx, 0x03fa
+ out dx, al
+
+ ret
+
+serial_putchar:
+
+ cmp dil, 0x0a
+ je .do_cr
+.cr_ret:
+
+ mov dx, 0x03fd
+
+.loop:
+ in al, dx
+ test al, 0x20
+ jz .loop
+
+ mov al, dil
+ mov dx, 0x03f8
+ out dx, al
+ ret
+
+.do_cr:
+ mov dil, 0x0d
+ call serial_putchar
+ mov dil, 0x0a
+ jmp .cr_ret