|
|
|
|
@@ -32,23 +32,6 @@ constexpr std::uint8_t irqToInterrupt(std::uint8_t irq) noexcept
|
|
|
|
|
}
|
|
|
|
|
return SLAVE_PIC_OFFSET + irq;
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
inline constexpr std::uint8_t INTERRUPT_KEYBOARD = irqToInterrupt(1);
|
|
|
|
|
|
|
|
|
|
TaskStateSegment tss alignas(16);
|
|
|
|
|
@@ -63,8 +46,7 @@ constinit std::array GDT alignas(16) = {
|
|
|
|
|
SEGMENT_NULL // TSS higher
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constinit std::array<InterruptDescriptor, 256> IDT alignas(16);
|
|
|
|
|
|
|
|
|
|
constinit baos::InterruptDescriptorTable gInterruptDescriptorTable;
|
|
|
|
|
|
|
|
|
|
inline baos::MemoryType mapEfiMemoryType(UINT32 type) noexcept
|
|
|
|
|
{
|
|
|
|
|
@@ -145,27 +127,10 @@ void initGlobals()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void __setGDT(uint16_t limit, void* base);
|
|
|
|
|
extern "C" void __setIDT(uint16_t limit, void* base);
|
|
|
|
|
extern "C" void __reloadSegments(uint64_t code, uint64_t data);
|
|
|
|
|
extern "C" void __flushTSS(uint16_t segment);
|
|
|
|
|
extern "C" void __enterUsermode(uint16_t codeSegment, uint16_t dataSegment, void* rsp, void (*function)(), void* stackPtr);
|
|
|
|
|
|
|
|
|
|
template<typename THandler>
|
|
|
|
|
void setupInterrupt(std::uint8_t index, THandler handler) noexcept
|
|
|
|
|
{
|
|
|
|
|
const std::uint64_t offset = std::bit_cast<std::uint64_t>(handler);
|
|
|
|
|
IDT[index] = InterruptDescriptor{
|
|
|
|
|
.offsetLow = static_cast<unsigned>(offset & 0xFFFF),
|
|
|
|
|
.selectorPrivilegeLevel = 0,
|
|
|
|
|
.selectorIndex = 1, // kernel code
|
|
|
|
|
.interruptStackTable = 0,
|
|
|
|
|
.gateType = InterruptGateType::INTERRUPT_GATE,
|
|
|
|
|
.privilegeLevel = 0,
|
|
|
|
|
.present = true,
|
|
|
|
|
.offsetHigh = (offset >> 16)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initializePCIDevice(const baos::pci::Header& header) noexcept
|
|
|
|
|
{
|
|
|
|
|
using namespace baos;
|
|
|
|
|
@@ -192,28 +157,12 @@ void kernel_main()
|
|
|
|
|
{
|
|
|
|
|
using namespace baos;
|
|
|
|
|
|
|
|
|
|
setupInterrupt(INTERRUPT_DIVISION_ERROR, &baos::isrDivisionError);
|
|
|
|
|
setupInterrupt(INTERRUPT_OVERFLOW, &baos::isrOverflow);
|
|
|
|
|
setupInterrupt(INTERRUPT_BOUND_RANGE_EXCEEDED, &baos::isrBoundRangeExceeded);
|
|
|
|
|
setupInterrupt(INTERRUPT_INVALID_OPCODE, &baos::isrInvalidOpCode);
|
|
|
|
|
setupInterrupt(INTERRUPT_DEVICE_NOT_AVAILABLE, &baos::isrDeviceNotAvailable);
|
|
|
|
|
setupInterrupt(INTERRUPT_DOUBLE_FAULT, &baos::isrDoubleFault);
|
|
|
|
|
setupInterrupt(INTERRUPT_INVALID_TSS, &baos::isrInvalidTSS);
|
|
|
|
|
setupInterrupt(INTERRUPT_SEGMENT_NOT_PRESENT, &baos::isrSegmentNotPresent);
|
|
|
|
|
setupInterrupt(INTERRUPT_STACK_SEGMENT_FAULT, &baos::isrStackSegmentFault);
|
|
|
|
|
setupInterrupt(INTERRUPT_GENERAL_PROTECTION_FAULT, &baos::isrGeneralProtectionFault);
|
|
|
|
|
setupInterrupt(INTERRUPT_PAGE_FAULT, &baos::isrPageFault);
|
|
|
|
|
setupInterrupt(INTERRUPT_X87_FP_EXCEPTION, &baos::isrX87FPException);
|
|
|
|
|
setupInterrupt(INTERRUPT_ALIGNMENT_CHECK, &baos::isrAlignmentCheck);
|
|
|
|
|
setupInterrupt(INTERRUPT_MACHINE_CHECK, &baos::isrMachineCheck);
|
|
|
|
|
setupInterrupt(INTERRUPT_SIMD_FP_EXCEPTION, &baos::isrSimdFpException);
|
|
|
|
|
setupInterrupt(INTERRUPT_VIRTUALIZATION_EXCEPTION, &baos::isrVirtualizationException);
|
|
|
|
|
setupInterrupt(INTERRUPT_CONTROL_PROTECTION_EXCEPTION, &baos::isrControlProtectionException);
|
|
|
|
|
setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard);
|
|
|
|
|
gInterruptDescriptorTable.setupErrorInterrupts();
|
|
|
|
|
gInterruptDescriptorTable.setupInterrupt(INTERRUPT_KEYBOARD, &ps2::isrKeyboard);
|
|
|
|
|
|
|
|
|
|
makeTSSSegment(&tss, &GDT[5]);
|
|
|
|
|
__setGDT(sizeof(GDT), &GDT);
|
|
|
|
|
__setIDT(sizeof(IDT), &IDT);
|
|
|
|
|
gInterruptDescriptorTable.install();
|
|
|
|
|
__reloadSegments(SEGIDX_KERNEL_CODE, SEGIDX_KERNEL_DATA);
|
|
|
|
|
__flushTSS(SEGIDX_TSS);
|
|
|
|
|
|
|
|
|
|
|