From f9e43c1790960585a0733a2016c5669d07e103fb Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Fri, 13 May 2022 03:23:13 +0200 Subject: [PATCH] Enabled basic interrupts and setup LAPIC, (though no IOAPIC yet) --- src/interrupts.S | 265 ++++++++++++++++++++++++++++++++++++ src/interrupts.cpp | 329 +++++++++++++++++++++++++++++++++++++++++++++ src/interrupts.hpp | 41 ++++++ src/kernel.cpp | 13 +- src/utils.cpp | 29 ++-- src/utils.hpp | 6 +- 6 files changed, 662 insertions(+), 21 deletions(-) create mode 100644 src/interrupts.S create mode 100644 src/interrupts.cpp create mode 100644 src/interrupts.hpp diff --git a/src/interrupts.S b/src/interrupts.S new file mode 100644 index 0000000..4e3f37b --- /dev/null +++ b/src/interrupts.S @@ -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 index 0000000..6d0beea --- /dev/null +++ b/src/interrupts.cpp @@ -0,0 +1,329 @@ +#include "interrupts.hpp" +#include "serial.hpp" +#include "utils.hpp" +#include + +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 ptr) { + os::set_msr(0x1B, (ptr.get_phys_addr() & 0xFFFFFFFFFFFFF000) | 0x800); +} +os::phys_ptr os::get_APIC_base() { + return os::phys_ptr{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(&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 index 0000000..1a8702b --- /dev/null +++ b/src/interrupts.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#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 ptr); +phys_ptr 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(); + +} diff --git a/src/kernel.cpp b/src/kernel.cpp index 9512d14..01ae69b 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -3,6 +3,7 @@ #include "fb.hpp" #include "utils.hpp" #include "serial.hpp" +#include "interrupts.hpp" void remove_some_mem(os::phys_ptr mem_start, os::phys_ptr mem_end, @@ -31,12 +32,12 @@ void remove_some_mem(os::phys_ptr mem_start, os::paging::page one_past_end_page_for_page_allocator; os::paging::page_allocator page_allocator(os::phys_ptr(reinterpret_cast(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000)); - extern "C" void kmain(unsigned long magic, os::phys_ptr 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 kernel_start = ([]() { @@ -55,8 +56,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptrtype != 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 -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)); +} diff --git a/src/utils.hpp b/src/utils.hpp index baa4b05..da225dd 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -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 -- 2.47.0