]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Enabled basic interrupts and setup LAPIC, (though no IOAPIC yet)
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Fri, 13 May 2022 01:23:13 +0000 (03:23 +0200)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Fri, 13 May 2022 01:23:13 +0000 (03:23 +0200)
src/interrupts.S [new file with mode: 0644]
src/interrupts.cpp [new file with mode: 0644]
src/interrupts.hpp [new file with mode: 0644]
src/kernel.cpp
src/utils.cpp
src/utils.hpp

diff --git a/src/interrupts.S b/src/interrupts.S
new file mode 100644 (file)
index 0000000..4e3f37b
--- /dev/null
@@ -0,0 +1,265 @@
+#define HANDLER(n) .globl handler_##n ;\
+       handler_##n: ;\
+       mov $n, %rdi ;\
+       call handler_impl ;\
+       cli ;\
+1:     hlt ;\
+       jmp 1b ;\
+       iretq
+
+HANDLER(0x00)
+HANDLER(0x01)
+HANDLER(0x02)
+HANDLER(0x03)
+HANDLER(0x04)
+HANDLER(0x05)
+HANDLER(0x06)
+HANDLER(0x07)
+HANDLER(0x08)
+HANDLER(0x09)
+HANDLER(0x0a)
+HANDLER(0x0b)
+HANDLER(0x0c)
+HANDLER(0x0d)
+HANDLER(0x0e)
+HANDLER(0x0f)
+HANDLER(0x10)
+HANDLER(0x11)
+HANDLER(0x12)
+HANDLER(0x13)
+HANDLER(0x14)
+HANDLER(0x15)
+HANDLER(0x16)
+HANDLER(0x17)
+HANDLER(0x18)
+HANDLER(0x19)
+HANDLER(0x1a)
+HANDLER(0x1b)
+HANDLER(0x1c)
+HANDLER(0x1d)
+HANDLER(0x1e)
+HANDLER(0x1f)
+HANDLER(0x20)
+HANDLER(0x21)
+HANDLER(0x22)
+HANDLER(0x23)
+HANDLER(0x24)
+HANDLER(0x25)
+HANDLER(0x26)
+HANDLER(0x27)
+HANDLER(0x28)
+HANDLER(0x29)
+HANDLER(0x2a)
+HANDLER(0x2b)
+HANDLER(0x2c)
+HANDLER(0x2d)
+HANDLER(0x2e)
+HANDLER(0x2f)
+HANDLER(0x30)
+HANDLER(0x31)
+HANDLER(0x32)
+HANDLER(0x33)
+HANDLER(0x34)
+HANDLER(0x35)
+HANDLER(0x36)
+HANDLER(0x37)
+HANDLER(0x38)
+HANDLER(0x39)
+HANDLER(0x3a)
+HANDLER(0x3b)
+HANDLER(0x3c)
+HANDLER(0x3d)
+HANDLER(0x3e)
+HANDLER(0x3f)
+HANDLER(0x40)
+HANDLER(0x41)
+HANDLER(0x42)
+HANDLER(0x43)
+HANDLER(0x44)
+HANDLER(0x45)
+HANDLER(0x46)
+HANDLER(0x47)
+HANDLER(0x48)
+HANDLER(0x49)
+HANDLER(0x4a)
+HANDLER(0x4b)
+HANDLER(0x4c)
+HANDLER(0x4d)
+HANDLER(0x4e)
+HANDLER(0x4f)
+HANDLER(0x50)
+HANDLER(0x51)
+HANDLER(0x52)
+HANDLER(0x53)
+HANDLER(0x54)
+HANDLER(0x55)
+HANDLER(0x56)
+HANDLER(0x57)
+HANDLER(0x58)
+HANDLER(0x59)
+HANDLER(0x5a)
+HANDLER(0x5b)
+HANDLER(0x5c)
+HANDLER(0x5d)
+HANDLER(0x5e)
+HANDLER(0x5f)
+HANDLER(0x60)
+HANDLER(0x61)
+HANDLER(0x62)
+HANDLER(0x63)
+HANDLER(0x64)
+HANDLER(0x65)
+HANDLER(0x66)
+HANDLER(0x67)
+HANDLER(0x68)
+HANDLER(0x69)
+HANDLER(0x6a)
+HANDLER(0x6b)
+HANDLER(0x6c)
+HANDLER(0x6d)
+HANDLER(0x6e)
+HANDLER(0x6f)
+HANDLER(0x70)
+HANDLER(0x71)
+HANDLER(0x72)
+HANDLER(0x73)
+HANDLER(0x74)
+HANDLER(0x75)
+HANDLER(0x76)
+HANDLER(0x77)
+HANDLER(0x78)
+HANDLER(0x79)
+HANDLER(0x7a)
+HANDLER(0x7b)
+HANDLER(0x7c)
+HANDLER(0x7d)
+HANDLER(0x7e)
+HANDLER(0x7f)
+HANDLER(0x80)
+HANDLER(0x81)
+HANDLER(0x82)
+HANDLER(0x83)
+HANDLER(0x84)
+HANDLER(0x85)
+HANDLER(0x86)
+HANDLER(0x87)
+HANDLER(0x88)
+HANDLER(0x89)
+HANDLER(0x8a)
+HANDLER(0x8b)
+HANDLER(0x8c)
+HANDLER(0x8d)
+HANDLER(0x8e)
+HANDLER(0x8f)
+HANDLER(0x90)
+HANDLER(0x91)
+HANDLER(0x92)
+HANDLER(0x93)
+HANDLER(0x94)
+HANDLER(0x95)
+HANDLER(0x96)
+HANDLER(0x97)
+HANDLER(0x98)
+HANDLER(0x99)
+HANDLER(0x9a)
+HANDLER(0x9b)
+HANDLER(0x9c)
+HANDLER(0x9d)
+HANDLER(0x9e)
+HANDLER(0x9f)
+HANDLER(0xa0)
+HANDLER(0xa1)
+HANDLER(0xa2)
+HANDLER(0xa3)
+HANDLER(0xa4)
+HANDLER(0xa5)
+HANDLER(0xa6)
+HANDLER(0xa7)
+HANDLER(0xa8)
+HANDLER(0xa9)
+HANDLER(0xaa)
+HANDLER(0xab)
+HANDLER(0xac)
+HANDLER(0xad)
+HANDLER(0xae)
+HANDLER(0xaf)
+HANDLER(0xb0)
+HANDLER(0xb1)
+HANDLER(0xb2)
+HANDLER(0xb3)
+HANDLER(0xb4)
+HANDLER(0xb5)
+HANDLER(0xb6)
+HANDLER(0xb7)
+HANDLER(0xb8)
+HANDLER(0xb9)
+HANDLER(0xba)
+HANDLER(0xbb)
+HANDLER(0xbc)
+HANDLER(0xbd)
+HANDLER(0xbe)
+HANDLER(0xbf)
+HANDLER(0xc0)
+HANDLER(0xc1)
+HANDLER(0xc2)
+HANDLER(0xc3)
+HANDLER(0xc4)
+HANDLER(0xc5)
+HANDLER(0xc6)
+HANDLER(0xc7)
+HANDLER(0xc8)
+HANDLER(0xc9)
+HANDLER(0xca)
+HANDLER(0xcb)
+HANDLER(0xcc)
+HANDLER(0xcd)
+HANDLER(0xce)
+HANDLER(0xcf)
+HANDLER(0xd0)
+HANDLER(0xd1)
+HANDLER(0xd2)
+HANDLER(0xd3)
+HANDLER(0xd4)
+HANDLER(0xd5)
+HANDLER(0xd6)
+HANDLER(0xd7)
+HANDLER(0xd8)
+HANDLER(0xd9)
+HANDLER(0xda)
+HANDLER(0xdb)
+HANDLER(0xdc)
+HANDLER(0xdd)
+HANDLER(0xde)
+HANDLER(0xdf)
+HANDLER(0xe0)
+HANDLER(0xe1)
+HANDLER(0xe2)
+HANDLER(0xe3)
+HANDLER(0xe4)
+HANDLER(0xe5)
+HANDLER(0xe6)
+HANDLER(0xe7)
+HANDLER(0xe8)
+HANDLER(0xe9)
+HANDLER(0xea)
+HANDLER(0xeb)
+HANDLER(0xec)
+HANDLER(0xed)
+HANDLER(0xee)
+HANDLER(0xef)
+HANDLER(0xf0)
+HANDLER(0xf1)
+HANDLER(0xf2)
+HANDLER(0xf3)
+HANDLER(0xf4)
+HANDLER(0xf5)
+HANDLER(0xf6)
+HANDLER(0xf7)
+HANDLER(0xf8)
+HANDLER(0xf9)
+HANDLER(0xfa)
+HANDLER(0xfb)
+HANDLER(0xfc)
+HANDLER(0xfd)
+HANDLER(0xfe)
+HANDLER(0xff)
diff --git a/src/interrupts.cpp b/src/interrupts.cpp
new file mode 100644 (file)
index 0000000..6d0beea
--- /dev/null
@@ -0,0 +1,329 @@
+#include "interrupts.hpp"
+#include "serial.hpp"
+#include "utils.hpp"
+#include <cpuid.h>
+
+void os::cli() {
+       asm volatile("cli");
+}
+void os::sti() {
+       asm volatile("sti");
+}
+void os::lidt(idtr idtr) {
+       asm volatile("lidt %0" : : "m"(idtr));
+}
+bool os::is_APIC_builtin() {
+       std::uint32_t eax, ebx, ecx, edx;
+       __cpuid(0x01, eax, ebx, ecx, edx);
+       return (edx & (1 << 9)) != 0;
+}
+void os::disable_PIC() {
+       outb(0xA1, 0xFF);
+       outb(0x21, 0xFF);
+}
+void os::set_APIC_base(os::phys_ptr<volatile std::uint32_t> ptr) {
+       os::set_msr(0x1B, (ptr.get_phys_addr() & 0xFFFFFFFFFFFFF000) | 0x800);
+}
+os::phys_ptr<volatile std::uint32_t> os::get_APIC_base() {
+       return os::phys_ptr<volatile std::uint32_t>{os::get_msr(0x1B) & 0xFFFFFFFFFFFFF000};
+}
+std::uint32_t os::get_APIC_reg(std::ptrdiff_t offset) {
+       return get_APIC_base()[offset / 4];
+}
+void os::set_APIC_reg(std::ptrdiff_t offset, std::uint32_t v) {
+       get_APIC_base()[offset / 4] = v;
+}
+
+std::uintptr_t handlers[256];
+os::idt idt;
+os::idtr idtr{
+       .size = sizeof(idt) - 1,
+       .offset = reinterpret_cast<uintptr_t>(&idt[0]),
+};
+
+extern "C" void handler_impl(std::uint8_t id) {
+       os::print("Interrupt #");
+       os::print(id);
+       os::print(" !\n");
+}
+
+void os::enable_interrupts() {
+       os::assert(is_APIC_builtin(), "No builtin APIC.");
+
+       disable_PIC();
+       // Enable APIC:
+       set_APIC_reg(0xF0, 0x1FF);
+
+       asm ("movq $handler_0x00,%0" : "=ri"(handlers[0x00]) : );
+       asm ("movq $handler_0x01,%0" : "=ri"(handlers[0x01]) : );
+       asm ("movq $handler_0x02,%0" : "=ri"(handlers[0x02]) : );
+       asm ("movq $handler_0x03,%0" : "=ri"(handlers[0x03]) : );
+       asm ("movq $handler_0x04,%0" : "=ri"(handlers[0x04]) : );
+       asm ("movq $handler_0x05,%0" : "=ri"(handlers[0x05]) : );
+       asm ("movq $handler_0x06,%0" : "=ri"(handlers[0x06]) : );
+       asm ("movq $handler_0x07,%0" : "=ri"(handlers[0x07]) : );
+       asm ("movq $handler_0x08,%0" : "=ri"(handlers[0x08]) : );
+       asm ("movq $handler_0x09,%0" : "=ri"(handlers[0x09]) : );
+       asm ("movq $handler_0x0a,%0" : "=ri"(handlers[0x0a]) : );
+       asm ("movq $handler_0x0b,%0" : "=ri"(handlers[0x0b]) : );
+       asm ("movq $handler_0x0c,%0" : "=ri"(handlers[0x0c]) : );
+       asm ("movq $handler_0x0d,%0" : "=ri"(handlers[0x0d]) : );
+       asm ("movq $handler_0x0e,%0" : "=ri"(handlers[0x0e]) : );
+       asm ("movq $handler_0x0f,%0" : "=ri"(handlers[0x0f]) : );
+       asm ("movq $handler_0x10,%0" : "=ri"(handlers[0x10]) : );
+       asm ("movq $handler_0x11,%0" : "=ri"(handlers[0x11]) : );
+       asm ("movq $handler_0x12,%0" : "=ri"(handlers[0x12]) : );
+       asm ("movq $handler_0x13,%0" : "=ri"(handlers[0x13]) : );
+       asm ("movq $handler_0x14,%0" : "=ri"(handlers[0x14]) : );
+       asm ("movq $handler_0x15,%0" : "=ri"(handlers[0x15]) : );
+       asm ("movq $handler_0x16,%0" : "=ri"(handlers[0x16]) : );
+       asm ("movq $handler_0x17,%0" : "=ri"(handlers[0x17]) : );
+       asm ("movq $handler_0x18,%0" : "=ri"(handlers[0x18]) : );
+       asm ("movq $handler_0x19,%0" : "=ri"(handlers[0x19]) : );
+       asm ("movq $handler_0x1a,%0" : "=ri"(handlers[0x1a]) : );
+       asm ("movq $handler_0x1b,%0" : "=ri"(handlers[0x1b]) : );
+       asm ("movq $handler_0x1c,%0" : "=ri"(handlers[0x1c]) : );
+       asm ("movq $handler_0x1d,%0" : "=ri"(handlers[0x1d]) : );
+       asm ("movq $handler_0x1e,%0" : "=ri"(handlers[0x1e]) : );
+       asm ("movq $handler_0x1f,%0" : "=ri"(handlers[0x1f]) : );
+       asm ("movq $handler_0x20,%0" : "=ri"(handlers[0x20]) : );
+       asm ("movq $handler_0x21,%0" : "=ri"(handlers[0x21]) : );
+       asm ("movq $handler_0x22,%0" : "=ri"(handlers[0x22]) : );
+       asm ("movq $handler_0x23,%0" : "=ri"(handlers[0x23]) : );
+       asm ("movq $handler_0x24,%0" : "=ri"(handlers[0x24]) : );
+       asm ("movq $handler_0x25,%0" : "=ri"(handlers[0x25]) : );
+       asm ("movq $handler_0x26,%0" : "=ri"(handlers[0x26]) : );
+       asm ("movq $handler_0x27,%0" : "=ri"(handlers[0x27]) : );
+       asm ("movq $handler_0x28,%0" : "=ri"(handlers[0x28]) : );
+       asm ("movq $handler_0x29,%0" : "=ri"(handlers[0x29]) : );
+       asm ("movq $handler_0x2a,%0" : "=ri"(handlers[0x2a]) : );
+       asm ("movq $handler_0x2b,%0" : "=ri"(handlers[0x2b]) : );
+       asm ("movq $handler_0x2c,%0" : "=ri"(handlers[0x2c]) : );
+       asm ("movq $handler_0x2d,%0" : "=ri"(handlers[0x2d]) : );
+       asm ("movq $handler_0x2e,%0" : "=ri"(handlers[0x2e]) : );
+       asm ("movq $handler_0x2f,%0" : "=ri"(handlers[0x2f]) : );
+       asm ("movq $handler_0x30,%0" : "=ri"(handlers[0x30]) : );
+       asm ("movq $handler_0x31,%0" : "=ri"(handlers[0x31]) : );
+       asm ("movq $handler_0x32,%0" : "=ri"(handlers[0x32]) : );
+       asm ("movq $handler_0x33,%0" : "=ri"(handlers[0x33]) : );
+       asm ("movq $handler_0x34,%0" : "=ri"(handlers[0x34]) : );
+       asm ("movq $handler_0x35,%0" : "=ri"(handlers[0x35]) : );
+       asm ("movq $handler_0x36,%0" : "=ri"(handlers[0x36]) : );
+       asm ("movq $handler_0x37,%0" : "=ri"(handlers[0x37]) : );
+       asm ("movq $handler_0x38,%0" : "=ri"(handlers[0x38]) : );
+       asm ("movq $handler_0x39,%0" : "=ri"(handlers[0x39]) : );
+       asm ("movq $handler_0x3a,%0" : "=ri"(handlers[0x3a]) : );
+       asm ("movq $handler_0x3b,%0" : "=ri"(handlers[0x3b]) : );
+       asm ("movq $handler_0x3c,%0" : "=ri"(handlers[0x3c]) : );
+       asm ("movq $handler_0x3d,%0" : "=ri"(handlers[0x3d]) : );
+       asm ("movq $handler_0x3e,%0" : "=ri"(handlers[0x3e]) : );
+       asm ("movq $handler_0x3f,%0" : "=ri"(handlers[0x3f]) : );
+       asm ("movq $handler_0x40,%0" : "=ri"(handlers[0x40]) : );
+       asm ("movq $handler_0x41,%0" : "=ri"(handlers[0x41]) : );
+       asm ("movq $handler_0x42,%0" : "=ri"(handlers[0x42]) : );
+       asm ("movq $handler_0x43,%0" : "=ri"(handlers[0x43]) : );
+       asm ("movq $handler_0x44,%0" : "=ri"(handlers[0x44]) : );
+       asm ("movq $handler_0x45,%0" : "=ri"(handlers[0x45]) : );
+       asm ("movq $handler_0x46,%0" : "=ri"(handlers[0x46]) : );
+       asm ("movq $handler_0x47,%0" : "=ri"(handlers[0x47]) : );
+       asm ("movq $handler_0x48,%0" : "=ri"(handlers[0x48]) : );
+       asm ("movq $handler_0x49,%0" : "=ri"(handlers[0x49]) : );
+       asm ("movq $handler_0x4a,%0" : "=ri"(handlers[0x4a]) : );
+       asm ("movq $handler_0x4b,%0" : "=ri"(handlers[0x4b]) : );
+       asm ("movq $handler_0x4c,%0" : "=ri"(handlers[0x4c]) : );
+       asm ("movq $handler_0x4d,%0" : "=ri"(handlers[0x4d]) : );
+       asm ("movq $handler_0x4e,%0" : "=ri"(handlers[0x4e]) : );
+       asm ("movq $handler_0x4f,%0" : "=ri"(handlers[0x4f]) : );
+       asm ("movq $handler_0x50,%0" : "=ri"(handlers[0x50]) : );
+       asm ("movq $handler_0x51,%0" : "=ri"(handlers[0x51]) : );
+       asm ("movq $handler_0x52,%0" : "=ri"(handlers[0x52]) : );
+       asm ("movq $handler_0x53,%0" : "=ri"(handlers[0x53]) : );
+       asm ("movq $handler_0x54,%0" : "=ri"(handlers[0x54]) : );
+       asm ("movq $handler_0x55,%0" : "=ri"(handlers[0x55]) : );
+       asm ("movq $handler_0x56,%0" : "=ri"(handlers[0x56]) : );
+       asm ("movq $handler_0x57,%0" : "=ri"(handlers[0x57]) : );
+       asm ("movq $handler_0x58,%0" : "=ri"(handlers[0x58]) : );
+       asm ("movq $handler_0x59,%0" : "=ri"(handlers[0x59]) : );
+       asm ("movq $handler_0x5a,%0" : "=ri"(handlers[0x5a]) : );
+       asm ("movq $handler_0x5b,%0" : "=ri"(handlers[0x5b]) : );
+       asm ("movq $handler_0x5c,%0" : "=ri"(handlers[0x5c]) : );
+       asm ("movq $handler_0x5d,%0" : "=ri"(handlers[0x5d]) : );
+       asm ("movq $handler_0x5e,%0" : "=ri"(handlers[0x5e]) : );
+       asm ("movq $handler_0x5f,%0" : "=ri"(handlers[0x5f]) : );
+       asm ("movq $handler_0x60,%0" : "=ri"(handlers[0x60]) : );
+       asm ("movq $handler_0x61,%0" : "=ri"(handlers[0x61]) : );
+       asm ("movq $handler_0x62,%0" : "=ri"(handlers[0x62]) : );
+       asm ("movq $handler_0x63,%0" : "=ri"(handlers[0x63]) : );
+       asm ("movq $handler_0x64,%0" : "=ri"(handlers[0x64]) : );
+       asm ("movq $handler_0x65,%0" : "=ri"(handlers[0x65]) : );
+       asm ("movq $handler_0x66,%0" : "=ri"(handlers[0x66]) : );
+       asm ("movq $handler_0x67,%0" : "=ri"(handlers[0x67]) : );
+       asm ("movq $handler_0x68,%0" : "=ri"(handlers[0x68]) : );
+       asm ("movq $handler_0x69,%0" : "=ri"(handlers[0x69]) : );
+       asm ("movq $handler_0x6a,%0" : "=ri"(handlers[0x6a]) : );
+       asm ("movq $handler_0x6b,%0" : "=ri"(handlers[0x6b]) : );
+       asm ("movq $handler_0x6c,%0" : "=ri"(handlers[0x6c]) : );
+       asm ("movq $handler_0x6d,%0" : "=ri"(handlers[0x6d]) : );
+       asm ("movq $handler_0x6e,%0" : "=ri"(handlers[0x6e]) : );
+       asm ("movq $handler_0x6f,%0" : "=ri"(handlers[0x6f]) : );
+       asm ("movq $handler_0x70,%0" : "=ri"(handlers[0x70]) : );
+       asm ("movq $handler_0x71,%0" : "=ri"(handlers[0x71]) : );
+       asm ("movq $handler_0x72,%0" : "=ri"(handlers[0x72]) : );
+       asm ("movq $handler_0x73,%0" : "=ri"(handlers[0x73]) : );
+       asm ("movq $handler_0x74,%0" : "=ri"(handlers[0x74]) : );
+       asm ("movq $handler_0x75,%0" : "=ri"(handlers[0x75]) : );
+       asm ("movq $handler_0x76,%0" : "=ri"(handlers[0x76]) : );
+       asm ("movq $handler_0x77,%0" : "=ri"(handlers[0x77]) : );
+       asm ("movq $handler_0x78,%0" : "=ri"(handlers[0x78]) : );
+       asm ("movq $handler_0x79,%0" : "=ri"(handlers[0x79]) : );
+       asm ("movq $handler_0x7a,%0" : "=ri"(handlers[0x7a]) : );
+       asm ("movq $handler_0x7b,%0" : "=ri"(handlers[0x7b]) : );
+       asm ("movq $handler_0x7c,%0" : "=ri"(handlers[0x7c]) : );
+       asm ("movq $handler_0x7d,%0" : "=ri"(handlers[0x7d]) : );
+       asm ("movq $handler_0x7e,%0" : "=ri"(handlers[0x7e]) : );
+       asm ("movq $handler_0x7f,%0" : "=ri"(handlers[0x7f]) : );
+       asm ("movq $handler_0x80,%0" : "=ri"(handlers[0x80]) : );
+       asm ("movq $handler_0x81,%0" : "=ri"(handlers[0x81]) : );
+       asm ("movq $handler_0x82,%0" : "=ri"(handlers[0x82]) : );
+       asm ("movq $handler_0x83,%0" : "=ri"(handlers[0x83]) : );
+       asm ("movq $handler_0x84,%0" : "=ri"(handlers[0x84]) : );
+       asm ("movq $handler_0x85,%0" : "=ri"(handlers[0x85]) : );
+       asm ("movq $handler_0x86,%0" : "=ri"(handlers[0x86]) : );
+       asm ("movq $handler_0x87,%0" : "=ri"(handlers[0x87]) : );
+       asm ("movq $handler_0x88,%0" : "=ri"(handlers[0x88]) : );
+       asm ("movq $handler_0x89,%0" : "=ri"(handlers[0x89]) : );
+       asm ("movq $handler_0x8a,%0" : "=ri"(handlers[0x8a]) : );
+       asm ("movq $handler_0x8b,%0" : "=ri"(handlers[0x8b]) : );
+       asm ("movq $handler_0x8c,%0" : "=ri"(handlers[0x8c]) : );
+       asm ("movq $handler_0x8d,%0" : "=ri"(handlers[0x8d]) : );
+       asm ("movq $handler_0x8e,%0" : "=ri"(handlers[0x8e]) : );
+       asm ("movq $handler_0x8f,%0" : "=ri"(handlers[0x8f]) : );
+       asm ("movq $handler_0x90,%0" : "=ri"(handlers[0x90]) : );
+       asm ("movq $handler_0x91,%0" : "=ri"(handlers[0x91]) : );
+       asm ("movq $handler_0x92,%0" : "=ri"(handlers[0x92]) : );
+       asm ("movq $handler_0x93,%0" : "=ri"(handlers[0x93]) : );
+       asm ("movq $handler_0x94,%0" : "=ri"(handlers[0x94]) : );
+       asm ("movq $handler_0x95,%0" : "=ri"(handlers[0x95]) : );
+       asm ("movq $handler_0x96,%0" : "=ri"(handlers[0x96]) : );
+       asm ("movq $handler_0x97,%0" : "=ri"(handlers[0x97]) : );
+       asm ("movq $handler_0x98,%0" : "=ri"(handlers[0x98]) : );
+       asm ("movq $handler_0x99,%0" : "=ri"(handlers[0x99]) : );
+       asm ("movq $handler_0x9a,%0" : "=ri"(handlers[0x9a]) : );
+       asm ("movq $handler_0x9b,%0" : "=ri"(handlers[0x9b]) : );
+       asm ("movq $handler_0x9c,%0" : "=ri"(handlers[0x9c]) : );
+       asm ("movq $handler_0x9d,%0" : "=ri"(handlers[0x9d]) : );
+       asm ("movq $handler_0x9e,%0" : "=ri"(handlers[0x9e]) : );
+       asm ("movq $handler_0x9f,%0" : "=ri"(handlers[0x9f]) : );
+       asm ("movq $handler_0xa0,%0" : "=ri"(handlers[0xa0]) : );
+       asm ("movq $handler_0xa1,%0" : "=ri"(handlers[0xa1]) : );
+       asm ("movq $handler_0xa2,%0" : "=ri"(handlers[0xa2]) : );
+       asm ("movq $handler_0xa3,%0" : "=ri"(handlers[0xa3]) : );
+       asm ("movq $handler_0xa4,%0" : "=ri"(handlers[0xa4]) : );
+       asm ("movq $handler_0xa5,%0" : "=ri"(handlers[0xa5]) : );
+       asm ("movq $handler_0xa6,%0" : "=ri"(handlers[0xa6]) : );
+       asm ("movq $handler_0xa7,%0" : "=ri"(handlers[0xa7]) : );
+       asm ("movq $handler_0xa8,%0" : "=ri"(handlers[0xa8]) : );
+       asm ("movq $handler_0xa9,%0" : "=ri"(handlers[0xa9]) : );
+       asm ("movq $handler_0xaa,%0" : "=ri"(handlers[0xaa]) : );
+       asm ("movq $handler_0xab,%0" : "=ri"(handlers[0xab]) : );
+       asm ("movq $handler_0xac,%0" : "=ri"(handlers[0xac]) : );
+       asm ("movq $handler_0xad,%0" : "=ri"(handlers[0xad]) : );
+       asm ("movq $handler_0xae,%0" : "=ri"(handlers[0xae]) : );
+       asm ("movq $handler_0xaf,%0" : "=ri"(handlers[0xaf]) : );
+       asm ("movq $handler_0xb0,%0" : "=ri"(handlers[0xb0]) : );
+       asm ("movq $handler_0xb1,%0" : "=ri"(handlers[0xb1]) : );
+       asm ("movq $handler_0xb2,%0" : "=ri"(handlers[0xb2]) : );
+       asm ("movq $handler_0xb3,%0" : "=ri"(handlers[0xb3]) : );
+       asm ("movq $handler_0xb4,%0" : "=ri"(handlers[0xb4]) : );
+       asm ("movq $handler_0xb5,%0" : "=ri"(handlers[0xb5]) : );
+       asm ("movq $handler_0xb6,%0" : "=ri"(handlers[0xb6]) : );
+       asm ("movq $handler_0xb7,%0" : "=ri"(handlers[0xb7]) : );
+       asm ("movq $handler_0xb8,%0" : "=ri"(handlers[0xb8]) : );
+       asm ("movq $handler_0xb9,%0" : "=ri"(handlers[0xb9]) : );
+       asm ("movq $handler_0xba,%0" : "=ri"(handlers[0xba]) : );
+       asm ("movq $handler_0xbb,%0" : "=ri"(handlers[0xbb]) : );
+       asm ("movq $handler_0xbc,%0" : "=ri"(handlers[0xbc]) : );
+       asm ("movq $handler_0xbd,%0" : "=ri"(handlers[0xbd]) : );
+       asm ("movq $handler_0xbe,%0" : "=ri"(handlers[0xbe]) : );
+       asm ("movq $handler_0xbf,%0" : "=ri"(handlers[0xbf]) : );
+       asm ("movq $handler_0xc0,%0" : "=ri"(handlers[0xc0]) : );
+       asm ("movq $handler_0xc1,%0" : "=ri"(handlers[0xc1]) : );
+       asm ("movq $handler_0xc2,%0" : "=ri"(handlers[0xc2]) : );
+       asm ("movq $handler_0xc3,%0" : "=ri"(handlers[0xc3]) : );
+       asm ("movq $handler_0xc4,%0" : "=ri"(handlers[0xc4]) : );
+       asm ("movq $handler_0xc5,%0" : "=ri"(handlers[0xc5]) : );
+       asm ("movq $handler_0xc6,%0" : "=ri"(handlers[0xc6]) : );
+       asm ("movq $handler_0xc7,%0" : "=ri"(handlers[0xc7]) : );
+       asm ("movq $handler_0xc8,%0" : "=ri"(handlers[0xc8]) : );
+       asm ("movq $handler_0xc9,%0" : "=ri"(handlers[0xc9]) : );
+       asm ("movq $handler_0xca,%0" : "=ri"(handlers[0xca]) : );
+       asm ("movq $handler_0xcb,%0" : "=ri"(handlers[0xcb]) : );
+       asm ("movq $handler_0xcc,%0" : "=ri"(handlers[0xcc]) : );
+       asm ("movq $handler_0xcd,%0" : "=ri"(handlers[0xcd]) : );
+       asm ("movq $handler_0xce,%0" : "=ri"(handlers[0xce]) : );
+       asm ("movq $handler_0xcf,%0" : "=ri"(handlers[0xcf]) : );
+       asm ("movq $handler_0xd0,%0" : "=ri"(handlers[0xd0]) : );
+       asm ("movq $handler_0xd1,%0" : "=ri"(handlers[0xd1]) : );
+       asm ("movq $handler_0xd2,%0" : "=ri"(handlers[0xd2]) : );
+       asm ("movq $handler_0xd3,%0" : "=ri"(handlers[0xd3]) : );
+       asm ("movq $handler_0xd4,%0" : "=ri"(handlers[0xd4]) : );
+       asm ("movq $handler_0xd5,%0" : "=ri"(handlers[0xd5]) : );
+       asm ("movq $handler_0xd6,%0" : "=ri"(handlers[0xd6]) : );
+       asm ("movq $handler_0xd7,%0" : "=ri"(handlers[0xd7]) : );
+       asm ("movq $handler_0xd8,%0" : "=ri"(handlers[0xd8]) : );
+       asm ("movq $handler_0xd9,%0" : "=ri"(handlers[0xd9]) : );
+       asm ("movq $handler_0xda,%0" : "=ri"(handlers[0xda]) : );
+       asm ("movq $handler_0xdb,%0" : "=ri"(handlers[0xdb]) : );
+       asm ("movq $handler_0xdc,%0" : "=ri"(handlers[0xdc]) : );
+       asm ("movq $handler_0xdd,%0" : "=ri"(handlers[0xdd]) : );
+       asm ("movq $handler_0xde,%0" : "=ri"(handlers[0xde]) : );
+       asm ("movq $handler_0xdf,%0" : "=ri"(handlers[0xdf]) : );
+       asm ("movq $handler_0xe0,%0" : "=ri"(handlers[0xe0]) : );
+       asm ("movq $handler_0xe1,%0" : "=ri"(handlers[0xe1]) : );
+       asm ("movq $handler_0xe2,%0" : "=ri"(handlers[0xe2]) : );
+       asm ("movq $handler_0xe3,%0" : "=ri"(handlers[0xe3]) : );
+       asm ("movq $handler_0xe4,%0" : "=ri"(handlers[0xe4]) : );
+       asm ("movq $handler_0xe5,%0" : "=ri"(handlers[0xe5]) : );
+       asm ("movq $handler_0xe6,%0" : "=ri"(handlers[0xe6]) : );
+       asm ("movq $handler_0xe7,%0" : "=ri"(handlers[0xe7]) : );
+       asm ("movq $handler_0xe8,%0" : "=ri"(handlers[0xe8]) : );
+       asm ("movq $handler_0xe9,%0" : "=ri"(handlers[0xe9]) : );
+       asm ("movq $handler_0xea,%0" : "=ri"(handlers[0xea]) : );
+       asm ("movq $handler_0xeb,%0" : "=ri"(handlers[0xeb]) : );
+       asm ("movq $handler_0xec,%0" : "=ri"(handlers[0xec]) : );
+       asm ("movq $handler_0xed,%0" : "=ri"(handlers[0xed]) : );
+       asm ("movq $handler_0xee,%0" : "=ri"(handlers[0xee]) : );
+       asm ("movq $handler_0xef,%0" : "=ri"(handlers[0xef]) : );
+       asm ("movq $handler_0xf0,%0" : "=ri"(handlers[0xf0]) : );
+       asm ("movq $handler_0xf1,%0" : "=ri"(handlers[0xf1]) : );
+       asm ("movq $handler_0xf2,%0" : "=ri"(handlers[0xf2]) : );
+       asm ("movq $handler_0xf3,%0" : "=ri"(handlers[0xf3]) : );
+       asm ("movq $handler_0xf4,%0" : "=ri"(handlers[0xf4]) : );
+       asm ("movq $handler_0xf5,%0" : "=ri"(handlers[0xf5]) : );
+       asm ("movq $handler_0xf6,%0" : "=ri"(handlers[0xf6]) : );
+       asm ("movq $handler_0xf7,%0" : "=ri"(handlers[0xf7]) : );
+       asm ("movq $handler_0xf8,%0" : "=ri"(handlers[0xf8]) : );
+       asm ("movq $handler_0xf9,%0" : "=ri"(handlers[0xf9]) : );
+       asm ("movq $handler_0xfa,%0" : "=ri"(handlers[0xfa]) : );
+       asm ("movq $handler_0xfb,%0" : "=ri"(handlers[0xfb]) : );
+       asm ("movq $handler_0xfc,%0" : "=ri"(handlers[0xfc]) : );
+       asm ("movq $handler_0xfd,%0" : "=ri"(handlers[0xfd]) : );
+       asm ("movq $handler_0xfe,%0" : "=ri"(handlers[0xfe]) : );
+       asm ("movq $handler_0xff,%0" : "=ri"(handlers[0xff]) : );
+
+       for (std::size_t i = 0; i < 256; i++) {
+               ::idt[i] = {
+                       .offset_low  = uint16_t(handlers[i] & 0xFFFF),
+                       .kernel_cs   = 0x08,
+                       .ist_offset  = 0,
+                       .gate_type   = 0xF, // Trap gate.
+                       .dpl         = 0b00,
+                       .present     = 1,
+                       .offset_mid  = uint16_t((handlers[i] >> 16) & 0xFFFF),
+                       .offset_high = uint32_t((handlers[i] >> 32) & 0xFFFFFFFF),
+               };
+       }
+
+       lidt(::idtr);
+       sti();
+}
diff --git a/src/interrupts.hpp b/src/interrupts.hpp
new file mode 100644 (file)
index 0000000..1a8702b
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <cstdint>
+#include "phys_ptr.hpp"
+
+namespace os {
+
+struct __attribute__((packed)) ide {
+       std::uint16_t offset_low;
+       std::uint16_t kernel_cs;
+       std::uint8_t ist_offset : 3;
+       std::uint8_t reserved_1 : 5 = 0;
+       std::uint8_t gate_type : 4;
+       std::uint8_t bit_0 : 1 = 0;
+       std::uint8_t dpl : 2;
+       std::uint8_t present : 1;
+       std::uint16_t offset_mid;
+       std::uint32_t offset_high;
+       std::uint32_t reserved_2 = 0;
+};
+
+using idt __attribute__((aligned(0x1000))) = ide[256];
+
+struct __attribute__((packed)) idtr {
+       std::uint16_t size;
+       std::uint64_t offset;
+};
+
+void cli();
+void sti();
+void lidt(idtr idtr);
+bool is_APIC_builtin();
+void disable_PIC();
+void set_APIC_base(phys_ptr<volatile std::uint32_t> ptr);
+phys_ptr<volatile std::uint32_t> get_APIC_base();
+std::uint32_t get_APIC_reg(std::ptrdiff_t offset);
+void set_APIC_reg(std::ptrdiff_t offset, std::uint32_t v);
+
+void enable_interrupts();
+
+}
index 9512d14a690bec730524011362899ce538e20795..01ae69b2a78330cd7611c36724f18d29d3b332e0 100644 (file)
@@ -3,6 +3,7 @@
 #include "fb.hpp"
 #include "utils.hpp"
 #include "serial.hpp"
+#include "interrupts.hpp"
 
 void remove_some_mem(os::phys_ptr<os::paging::page> mem_start,
                os::phys_ptr<os::paging::page> mem_end,
@@ -31,12 +32,12 @@ void remove_some_mem(os::phys_ptr<os::paging::page> mem_start,
 os::paging::page one_past_end_page_for_page_allocator;
 os::paging::page_allocator page_allocator(os::phys_ptr<os::paging::page>(reinterpret_cast<uintptr_t>(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000));
 
-
 extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_start> info) {
        os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2.");
+       os::assert(os::cpu_has_msr(), "MSRs aren't supported.");
 
        if (!os::init_serial_port()) {
-               os::halt();
+               os::hlt();
        }
 
        const os::phys_ptr<os::paging::page> kernel_start = ([]() {
@@ -55,8 +56,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 
        os::framebuffer framebuffer;
 
-
-
        for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) {
                switch (it->type) {
                case multiboot2::info::type_t::framebuffer_info:
@@ -133,5 +132,9 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                }
        }
 
-       os::halt();
+       os::enable_interrupts();
+
+       while (true) {
+               os::hlt();
+       }
 }
index 5806cb6eacef877113e1aadc2c70728af280c1b4..8f66b484038bd4a9c234b0ed5655ec264dc79c42 100644 (file)
@@ -1,22 +1,11 @@
 #include "utils.hpp"
+#include "interrupts.hpp"
+#include <cpuid.h>
 
-void os::cli() {
-       asm volatile("cli");
-}
-void os::sti() {
-       asm volatile("sti");
-}
 void os::hlt() {
        asm volatile("hlt");
 }
 
-void os::halt() {
-       cli();
-       while (true) {
-               hlt();
-       }
-}
-
 void os::outb(std::uint16_t port, std::uint8_t data) {
        asm volatile ("outb %1,%0" : : "dN"(port), "a"(data));
 }
@@ -25,3 +14,17 @@ std::uint8_t os::inb(std::uint16_t port) {
        asm volatile ("inb %1,%0" : "=a"(data) : "dN"(port));
        return data;
 }
+
+bool os::cpu_has_msr() {
+       std::uint32_t eax, ebx, ecx, edx;
+       __cpuid(0x01, eax, ebx, ecx, edx);
+       return (edx & (1 << 5)) != 0;
+}
+std::uint64_t os::get_msr(std::uint32_t msr) {
+       std::uint64_t lo, hi;
+       asm volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
+       return lo + (hi << 32);
+}
+void os::set_msr(std::uint32_t msr, std::uint64_t v) {
+       asm volatile ("wrmsr" : : "a"(v & 0xFFFFFFFF), "d"((v >> 32) & 0xFFFFFFFF), "c"(msr));
+}
index baa4b0581b500429ed255df769a3c11f6b325cfd..da225dd018486073a1cf0be70880195cf71637b9 100644 (file)
@@ -4,11 +4,11 @@
 
 namespace os {
 
-void cli();
-void sti();
 void hlt();
-void halt();
 void outb(std::uint16_t port, std::uint8_t data);
 std::uint8_t inb(std::uint16_t port);
+bool cpu_has_msr();
+std::uint64_t get_msr(std::uint32_t msr);
+void set_msr(std::uint32_t msr, std::uint64_t v);
 
 } // namespace os