Some restructuring.

This commit is contained in:
2024-01-29 18:14:20 +01:00
parent 3fff3bd8fc
commit 54a5ee720f
33 changed files with 230 additions and 190 deletions

View File

@@ -8,9 +8,10 @@ kernel_env['CXX'] = 'x86_64-elf-g++'
kernel_env['LD'] = 'x86_64-elf-g++'
kernel_env.Append(CFLAGS = ['-ffreestanding'])
kernel_env.Append(CPPDEFINES = ['__baos_kernel_source__=1'])
kernel_env.Append(CXXFLAGS = ['-ffreestanding', '-fno-exceptions', '-fno-rtti', '-std=c++20'])
kernel_env.Append(LINKFLAGS = ['-T', kernel_env.File('linker.ld').abspath, '-ffreestanding', '-nostdlib', '-mcmodel=large', '-mno-red-zone', '-mno-mmx', '-mno-sse', '-mno-sse2'])
kernel_env.Append(CPPPATH = ['#targets/_any/include', '#bastl/include', 'include', '/usr/include/efi'])
kernel_env.Append(CPPPATH = ['#targets/_any/include', '#bastl/include', 'include', '/usr/include/efi', '#targets/_any/kernel/include'])
def get_crt_object(name: str) -> str:
import subprocess

View File

@@ -61,7 +61,7 @@ __setGDT:
.global __setIDT
.type __setIDT @function
// void __setIDT(uint16_t limit [%di], void* base [%rsi])
// void __setIDT(uint16_t limit [%di], const void* base [%rsi])
__setIDT:
movw %di, __idt_storage
movq %rsi, (__idt_storage + 2)

View File

@@ -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);

View File

@@ -171,35 +171,6 @@ inline constexpr const SegmentDescriptor SEGMENT_USER_DATA = {
// --- Interrupts --- //
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));
struct TaskStateSegment
{
/* 0 */ std::uint32_t reserved0 = 0;