#pragma once #if !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED) #define BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED #include #include #include namespace baos { #if defined(__x86_64__) inline constexpr std::uint8_t INTERRUPT_DIVISION_ERROR = 0x00; inline constexpr std::uint8_t INTERRUPT_OVERFLOW = 0x04; inline constexpr std::uint8_t INTERRUPT_BOUND_RANGE_EXCEEDED = 0x05; inline constexpr std::uint8_t INTERRUPT_INVALID_OPCODE = 0x06; inline constexpr std::uint8_t INTERRUPT_DEVICE_NOT_AVAILABLE = 0x07; inline constexpr std::uint8_t INTERRUPT_DOUBLE_FAULT = 0x08; inline constexpr std::uint8_t INTERRUPT_INVALID_TSS = 0x0A; inline constexpr std::uint8_t INTERRUPT_SEGMENT_NOT_PRESENT = 0x0B; inline constexpr std::uint8_t INTERRUPT_STACK_SEGMENT_FAULT = 0x0C; inline constexpr std::uint8_t INTERRUPT_GENERAL_PROTECTION_FAULT = 0x0D; inline constexpr std::uint8_t INTERRUPT_PAGE_FAULT = 0x0E; inline constexpr std::uint8_t INTERRUPT_X87_FP_EXCEPTION = 0x10; inline constexpr std::uint8_t INTERRUPT_ALIGNMENT_CHECK = 0x11; inline constexpr std::uint8_t INTERRUPT_MACHINE_CHECK = 0x12; inline constexpr std::uint8_t INTERRUPT_SIMD_FP_EXCEPTION = 0x13; inline constexpr std::uint8_t INTERRUPT_VIRTUALIZATION_EXCEPTION = 0x14; inline constexpr std::uint8_t INTERRUPT_CONTROL_PROTECTION_EXCEPTION = 0x15; struct InterruptFrame { std::uint64_t ip; std::uint64_t cs; std::uint64_t flags; std::uint64_t sp; std::uint64_t ss; }; using interrupt_error_code_t = std::uint64_t; enum class InterruptGateType { NONE = 0, INTERRUPT_GATE = 0xE, TRAP_GATE = 0xF }; enum class InterruptSelectorTable { GDT = 0, LDT = 1 }; struct InterruptDescriptor { /* 0 */ unsigned offsetLow : 16 = 0; /* 16 */ unsigned selectorPrivilegeLevel : 2 = 0; /* 18 */ InterruptSelectorTable selectorTable : 1 = InterruptSelectorTable::GDT; /* 19 */ unsigned selectorIndex : 13 = 0; /* 32 */ unsigned interruptStackTable : 3 = 0; /* 35 */ unsigned reserved0_ : 5 = 0; /* 40 */ InterruptGateType gateType : 4 = InterruptGateType::NONE; /* 44 */ unsigned reserved1_ : 1 = 0; /* 45 */ unsigned privilegeLevel : 2 = 0; /* 47 */ bool present : 1 = 0; /* 48 */ unsigned long offsetHigh : 48 = 0; /* 96 */ unsigned reserved2_ : 32 = 0; } __attribute__((packed)); class InterruptDescriptorTable { private: alignas(16) std::array mDescriptors; public: inline void install() const noexcept; template void setupInterrupt(std::uint8_t index, THandler handler) noexcept { const std::uint64_t offset = std::bit_cast(handler); mDescriptors[index] = InterruptDescriptor{ .offsetLow = static_cast(offset & 0xFFFF), .selectorPrivilegeLevel = 0, .selectorIndex = 1, // kernel code .interruptStackTable = 0, .gateType = InterruptGateType::INTERRUPT_GATE, .privilegeLevel = 0, .present = true, .offsetHigh = (offset >> 16) }; } inline void setupErrorInterrupts() noexcept; }; #endif using interrupt_handler_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*); using interrupt_handler_with_error_code_t = __attribute__((interrupt)) void(*)(baos::InterruptFrame*, interrupt_error_code_t); __attribute__((interrupt)) void isrDivisionError(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrOverflow(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrBoundRangeExceeded(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrInvalidOpCode(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrDeviceNotAvailable(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrDoubleFault(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrInvalidTSS(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrSegmentNotPresent(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrStackSegmentFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrGeneralProtectionFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrPageFault(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrX87FPException(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrAlignmentCheck(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; __attribute__((interrupt)) void isrMachineCheck(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrSimdFpException(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrVirtualizationException(InterruptFrame* interruptFrame) noexcept; __attribute__((interrupt)) void isrControlProtectionException(InterruptFrame* interruptFrame, interrupt_error_code_t errorCode) noexcept; extern "C" void __setIDT(uint16_t limit, const void* base); void InterruptDescriptorTable::install() const noexcept { __setIDT(sizeof(mDescriptors), &mDescriptors); } void InterruptDescriptorTable::setupErrorInterrupts() noexcept { setupInterrupt(INTERRUPT_DIVISION_ERROR, &isrDivisionError); setupInterrupt(INTERRUPT_OVERFLOW, &isrOverflow); setupInterrupt(INTERRUPT_BOUND_RANGE_EXCEEDED, &isrBoundRangeExceeded); setupInterrupt(INTERRUPT_INVALID_OPCODE, &isrInvalidOpCode); setupInterrupt(INTERRUPT_DEVICE_NOT_AVAILABLE, &isrDeviceNotAvailable); setupInterrupt(INTERRUPT_DOUBLE_FAULT, &isrDoubleFault); setupInterrupt(INTERRUPT_INVALID_TSS, &isrInvalidTSS); setupInterrupt(INTERRUPT_SEGMENT_NOT_PRESENT, &isrSegmentNotPresent); setupInterrupt(INTERRUPT_STACK_SEGMENT_FAULT, &isrStackSegmentFault); setupInterrupt(INTERRUPT_GENERAL_PROTECTION_FAULT, &isrGeneralProtectionFault); setupInterrupt(INTERRUPT_PAGE_FAULT, &isrPageFault); setupInterrupt(INTERRUPT_X87_FP_EXCEPTION, &isrX87FPException); setupInterrupt(INTERRUPT_ALIGNMENT_CHECK, &isrAlignmentCheck); setupInterrupt(INTERRUPT_MACHINE_CHECK, &isrMachineCheck); setupInterrupt(INTERRUPT_SIMD_FP_EXCEPTION, &isrSimdFpException); setupInterrupt(INTERRUPT_VIRTUALIZATION_EXCEPTION, &isrVirtualizationException); setupInterrupt(INTERRUPT_CONTROL_PROTECTION_EXCEPTION, &isrControlProtectionException); } } #endif // !defined(BAD_APPLE_OS_INTERRUPT_HPP_INCLUDED)