diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index bbbe814..e35e81c 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -13,6 +13,7 @@ "GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT_SHORT=\"0000000\"", "a64", + "a86", "DEBUG=\"1\"" ], "compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc", @@ -82,6 +83,7 @@ "GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT_SHORT=\"0000000\"", "a32", + "a86", "DEBUG=\"1\"" ], "compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc", diff --git a/.vscode/launch.json b/.vscode/launch.json index fb5d3ca..80f2cb1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,7 +2,7 @@ "version": "0.2.0", "configurations": [ { - "name": "Attach to a running QEMU instance", + "name": "Attach to a running VM instance", "type": "cppdbg", "request": "launch", "program": "${workspaceRoot}/kernel.fsys", diff --git a/Architecture/amd64/AdvancedConfigurationAndPowerInterface.cpp b/Architecture/amd64/AdvancedConfigurationAndPowerInterface.cpp index 75a3356..2d6499a 100644 --- a/Architecture/amd64/AdvancedConfigurationAndPowerInterface.cpp +++ b/Architecture/amd64/AdvancedConfigurationAndPowerInterface.cpp @@ -20,6 +20,8 @@ #include #include +#include "../../kernel.h" + #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" namespace ACPI @@ -28,20 +30,20 @@ namespace ACPI { for (uint64_t t = 0; t < ((ACPIHeader->Length - sizeof(ACPI::ACPIHeader)) / (XSDTSupported ? 8 : 4)); t++) { - // Should I be concerned about unaligned memory access? + // TODO: Should I be concerned about unaligned memory access? ACPI::ACPIHeader *SDTHdr = nullptr; if (XSDTSupported) SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8))); else SDTHdr = (ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 4))); - for (uint64_t i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { if (SDTHdr->Signature[i] != Signature[i]) break; if (i == 3) { - trace("%s found at address %p!", Signature, (uintptr_t)SDTHdr); + trace("%s found at address %p", Signature, (uintptr_t)SDTHdr); return SDTHdr; } } @@ -55,86 +57,86 @@ namespace ACPI if (!Header) return; - HPET = (HPETHeader *)FindTable(XSDT, (char *)"HPET"); - FADT = (FADTHeader *)FindTable(XSDT, (char *)"FACP"); - MCFG = (MCFGHeader *)FindTable(XSDT, (char *)"MCFG"); - BGRT = (BGRTHeader *)FindTable(XSDT, (char *)"BGRT"); - SRAT = (SRATHeader *)FindTable(XSDT, (char *)"SRAT"); - TPM2 = (TPM2Header *)FindTable(XSDT, (char *)"TPM2"); - TCPA = (TCPAHeader *)FindTable(XSDT, (char *)"TCPA"); - WAET = (WAETHeader *)FindTable(XSDT, (char *)"WAET"); - MADT = (MADTHeader *)FindTable(XSDT, (char *)"APIC"); - HEST = (HESTHeader *)FindTable(XSDT, (char *)"HEST"); - FindTable(XSDT, (char *)"BERT"); - FindTable(XSDT, (char *)"CPEP"); - FindTable(XSDT, (char *)"DSDT"); - FindTable(XSDT, (char *)"ECDT"); - FindTable(XSDT, (char *)"EINJ"); - FindTable(XSDT, (char *)"ERST"); - FindTable(XSDT, (char *)"FACS"); - FindTable(XSDT, (char *)"MSCT"); - FindTable(XSDT, (char *)"MPST"); - FindTable(XSDT, (char *)"OEMx"); - FindTable(XSDT, (char *)"PMTT"); - FindTable(XSDT, (char *)"PSDT"); - FindTable(XSDT, (char *)"RASF"); - FindTable(XSDT, (char *)"RSDT"); - FindTable(XSDT, (char *)"SBST"); - FindTable(XSDT, (char *)"SLIT"); - FindTable(XSDT, (char *)"SSDT"); - FindTable(XSDT, (char *)"XSDT"); - FindTable(XSDT, (char *)"DRTM"); - FindTable(XSDT, (char *)"FPDT"); - FindTable(XSDT, (char *)"GTDT"); - FindTable(XSDT, (char *)"PCCT"); - FindTable(XSDT, (char *)"S3PT"); - FindTable(XSDT, (char *)"MATR"); - FindTable(XSDT, (char *)"MSDM"); - FindTable(XSDT, (char *)"WPBT"); - FindTable(XSDT, (char *)"OSDT"); - FindTable(XSDT, (char *)"RSDP"); - FindTable(XSDT, (char *)"NFIT"); - FindTable(XSDT, (char *)"ASF!"); - FindTable(XSDT, (char *)"BOOT"); - FindTable(XSDT, (char *)"CSRT"); - FindTable(XSDT, (char *)"DBG2"); - FindTable(XSDT, (char *)"DBGP"); - FindTable(XSDT, (char *)"DMAR"); - FindTable(XSDT, (char *)"IBFT"); - FindTable(XSDT, (char *)"IORT"); - FindTable(XSDT, (char *)"IVRS"); - FindTable(XSDT, (char *)"LPIT"); - FindTable(XSDT, (char *)"MCHI"); - FindTable(XSDT, (char *)"MTMR"); - FindTable(XSDT, (char *)"SLIC"); - FindTable(XSDT, (char *)"SPCR"); - FindTable(XSDT, (char *)"SPMI"); - FindTable(XSDT, (char *)"UEFI"); - FindTable(XSDT, (char *)"VRTC"); - FindTable(XSDT, (char *)"WDAT"); - FindTable(XSDT, (char *)"WDDT"); - FindTable(XSDT, (char *)"WDRT"); - FindTable(XSDT, (char *)"ATKG"); - FindTable(XSDT, (char *)"GSCI"); - FindTable(XSDT, (char *)"IEIT"); - FindTable(XSDT, (char *)"HMAT"); - FindTable(XSDT, (char *)"CEDT"); - FindTable(XSDT, (char *)"AEST"); + HPET = (HPETHeader *)FindTable(Header, (char *)"HPET"); + FADT = (FADTHeader *)FindTable(Header, (char *)"FACP"); + MCFG = (MCFGHeader *)FindTable(Header, (char *)"MCFG"); + BGRT = (BGRTHeader *)FindTable(Header, (char *)"BGRT"); + SRAT = (SRATHeader *)FindTable(Header, (char *)"SRAT"); + TPM2 = (TPM2Header *)FindTable(Header, (char *)"TPM2"); + TCPA = (TCPAHeader *)FindTable(Header, (char *)"TCPA"); + WAET = (WAETHeader *)FindTable(Header, (char *)"WAET"); + MADT = (MADTHeader *)FindTable(Header, (char *)"APIC"); + HEST = (HESTHeader *)FindTable(Header, (char *)"HEST"); + FindTable(Header, (char *)"BERT"); + FindTable(Header, (char *)"CPEP"); + FindTable(Header, (char *)"DSDT"); + FindTable(Header, (char *)"ECDT"); + FindTable(Header, (char *)"EINJ"); + FindTable(Header, (char *)"ERST"); + FindTable(Header, (char *)"FACS"); + FindTable(Header, (char *)"MSCT"); + FindTable(Header, (char *)"MPST"); + FindTable(Header, (char *)"OEMx"); + FindTable(Header, (char *)"PMTT"); + FindTable(Header, (char *)"PSDT"); + FindTable(Header, (char *)"RASF"); + FindTable(Header, (char *)"RSDT"); + FindTable(Header, (char *)"SBST"); + FindTable(Header, (char *)"SLIT"); + FindTable(Header, (char *)"SSDT"); + FindTable(Header, (char *)"XSDT"); + FindTable(Header, (char *)"DRTM"); + FindTable(Header, (char *)"FPDT"); + FindTable(Header, (char *)"GTDT"); + FindTable(Header, (char *)"PCCT"); + FindTable(Header, (char *)"S3PT"); + FindTable(Header, (char *)"MATR"); + FindTable(Header, (char *)"MSDM"); + FindTable(Header, (char *)"WPBT"); + FindTable(Header, (char *)"OSDT"); + FindTable(Header, (char *)"RSDP"); + FindTable(Header, (char *)"NFIT"); + FindTable(Header, (char *)"ASF!"); + FindTable(Header, (char *)"BOOT"); + FindTable(Header, (char *)"CSRT"); + FindTable(Header, (char *)"DBG2"); + FindTable(Header, (char *)"DBGP"); + FindTable(Header, (char *)"DMAR"); + FindTable(Header, (char *)"IBFT"); + FindTable(Header, (char *)"IORT"); + FindTable(Header, (char *)"IVRS"); + FindTable(Header, (char *)"LPIT"); + FindTable(Header, (char *)"MCHI"); + FindTable(Header, (char *)"MTMR"); + FindTable(Header, (char *)"SLIC"); + FindTable(Header, (char *)"SPCR"); + FindTable(Header, (char *)"SPMI"); + FindTable(Header, (char *)"UEFI"); + FindTable(Header, (char *)"VRTC"); + FindTable(Header, (char *)"WDAT"); + FindTable(Header, (char *)"WDDT"); + FindTable(Header, (char *)"WDRT"); + FindTable(Header, (char *)"ATKG"); + FindTable(Header, (char *)"GSCI"); + FindTable(Header, (char *)"IEIT"); + FindTable(Header, (char *)"HMAT"); + FindTable(Header, (char *)"CEDT"); + FindTable(Header, (char *)"AEST"); } - ACPI::ACPI(BootInfo *Info) + ACPI::ACPI() { trace("Initializing ACPI"); - if (Info->RSDP->Revision >= 2 && Info->RSDP->XSDTAddress) + if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) { debug("XSDT supported"); XSDTSupported = true; - XSDT = (ACPIHeader *)(Info->RSDP->XSDTAddress); + XSDT = (ACPIHeader *)(bInfo.RSDP->XSDTAddress); } else { debug("RSDT supported"); - XSDT = (ACPIHeader *)(uintptr_t)Info->RSDP->RSDTAddress; + XSDT = (ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress; } this->SearchTables(XSDT); diff --git a/Architecture/amd64/Bootstrap/Limine.c b/Architecture/amd64/Bootstrap/Limine.c index 0ed0293..eceb740 100644 --- a/Architecture/amd64/Bootstrap/Limine.c +++ b/Architecture/amd64/Bootstrap/Limine.c @@ -68,12 +68,28 @@ __naked __used __no_stack_protector void InitLimine() : : "r"((uintptr_t)TempStackPtr - 0xFFFF800000000000)); + asmv("mov $0, %rax\n" + "mov $0, %rbx\n" + "mov $0, %rcx\n" + "mov $0, %rdx\n" + "mov $0, %rsi\n" + "mov $0, %rdi\n" + "mov $0, %rbp\n" + "mov $0, %r8\n" + "mov $0, %r9\n" + "mov $0, %r10\n" + "mov $0, %r11\n" + "mov $0, %r12\n" + "mov $0, %r13\n" + "mov $0, %r14\n" + "mov $0, %r15"); + asmv("jmp InitLimineAfterStack"); } SafeFunction NIF void InitLimineAfterStack() { - struct BootInfo binfo; + struct BootInfo binfo = {}; struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response; info("Bootloader: %s %s", BootloaderInfoResponse->name, BootloaderInfoResponse->version); @@ -82,8 +98,7 @@ SafeFunction NIF void InitLimineAfterStack() if (TerminalResponse == NULL || TerminalResponse->terminal_count < 1) { warn("No terminal available."); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } TerminalResponse->write(TerminalResponse->terminals[0], "\033[37mPlease wait... ", 20); @@ -97,67 +112,79 @@ SafeFunction NIF void InitLimineAfterStack() if (FrameBufferResponse == NULL || FrameBufferResponse->framebuffer_count < 1) { - error("No framebuffer available [%p;%ld]", FrameBufferResponse, + error("No framebuffer available [%#lx;%ld]", FrameBufferResponse, (FrameBufferResponse == NULL) ? 0 : FrameBufferResponse->framebuffer_count); + TerminalResponse->write(TerminalResponse->terminals[0], "No framebuffer available", 24); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } if (MemmapResponse == NULL || MemmapResponse->entry_count < 1) { - error("No memory map available [%p;%ld]", MemmapResponse, + error("No memory map available [%#lx;%ld]", MemmapResponse, (MemmapResponse == NULL) ? 0 : MemmapResponse->entry_count); + TerminalResponse->write(TerminalResponse->terminals[0], "No memory map available", 23); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } if (KernelAddressResponse == NULL) { - error("No kernel address available [%p]", KernelAddressResponse); + error("No kernel address available [%#lx]", KernelAddressResponse); + TerminalResponse->write(TerminalResponse->terminals[0], "No kernel address available", 27); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } if (RsdpResponse == NULL || RsdpResponse->address == 0) { - error("No RSDP address available [%p;%p]", RsdpResponse, + error("No RSDP address available [%#lx;%#lx]", RsdpResponse, (RsdpResponse == NULL) ? 0 : RsdpResponse->address); + TerminalResponse->write(TerminalResponse->terminals[0], "No RSDP address available", 25); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } if (KernelFileResponse == NULL || KernelFileResponse->kernel_file == NULL) { - error("No kernel file available [%p;%p]", KernelFileResponse, + error("No kernel file available [%#lx;%#lx]", KernelFileResponse, (KernelFileResponse == NULL) ? 0 : KernelFileResponse->kernel_file); + TerminalResponse->write(TerminalResponse->terminals[0], "No kernel file available", 24); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } if (ModuleResponse == NULL || ModuleResponse->module_count < 1) { - error("No module information available [%p;%ld]", ModuleResponse, + error("No module information available [%#lx;%ld]", ModuleResponse, (ModuleResponse == NULL) ? 0 : ModuleResponse->module_count); + TerminalResponse->write(TerminalResponse->terminals[0], "No module information available", 31); - while (1) - asmv("hlt"); + inf_loop asmv("hlt"); } + /* Actual parsing starts here */ + for (uint64_t i = 0; i < FrameBufferResponse->framebuffer_count; i++) { struct limine_framebuffer *framebuffer = FrameBufferResponse->framebuffers[i]; - binfo.Framebuffer[i].Type = RGB; - binfo.Framebuffer[i].BaseAddress = (void *)((uint64_t)framebuffer->address - 0xFFFF800000000000); + switch (framebuffer->memory_model) + { + case LIMINE_FRAMEBUFFER_RGB: + binfo.Framebuffer[i].Type = RGB; + break; + default: + { + error("Unsupported framebuffer memory model %d", framebuffer->memory_model); + TerminalResponse->write(TerminalResponse->terminals[0], "Unsupported framebuffer memory model", 37); + inf_loop asmv("hlt"); + } + } + binfo.Framebuffer[i].BaseAddress = (void *)((uintptr_t)framebuffer->address - 0xFFFF800000000000); binfo.Framebuffer[i].Width = (uint32_t)framebuffer->width; binfo.Framebuffer[i].Height = (uint32_t)framebuffer->height; binfo.Framebuffer[i].Pitch = (uint32_t)framebuffer->pitch; binfo.Framebuffer[i].BitsPerPixel = framebuffer->bpp; - binfo.Framebuffer[i].MemoryModel = framebuffer->memory_model; binfo.Framebuffer[i].RedMaskSize = framebuffer->red_mask_size; binfo.Framebuffer[i].RedMaskShift = framebuffer->red_mask_shift; binfo.Framebuffer[i].GreenMaskSize = framebuffer->green_mask_size; @@ -166,9 +193,24 @@ SafeFunction NIF void InitLimineAfterStack() binfo.Framebuffer[i].BlueMaskShift = framebuffer->blue_mask_shift; binfo.Framebuffer[i].ExtendedDisplayIdentificationData = framebuffer->edid; binfo.Framebuffer[i].EDIDSize = framebuffer->edid_size; - debug("Framebuffer %d: %dx%d %d bpp", i, framebuffer->width, framebuffer->height, framebuffer->bpp); - debug("More info:\nAddress: %p\nPitch: %ld\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d\nEDID: %p\nEDIDSize: %d", - (uint64_t)framebuffer->address - 0xFFFF800000000000, framebuffer->pitch, framebuffer->memory_model, framebuffer->red_mask_size, framebuffer->red_mask_shift, framebuffer->green_mask_size, framebuffer->green_mask_shift, framebuffer->blue_mask_size, framebuffer->blue_mask_shift, framebuffer->edid, framebuffer->edid_size); + + debug("Framebuffer %d: %dx%d %d bpp", i, + binfo.Framebuffer[i].Width, + binfo.Framebuffer[i].Height, + binfo.Framebuffer[i].BitsPerPixel); + + debug("More info:\nAddress: %#lx\nPitch: %ld\nType: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d\nEDID: %#lx\nEDIDSize: %d", + binfo.Framebuffer[i].BaseAddress, + binfo.Framebuffer[i].Pitch, + binfo.Framebuffer[i].Type, + binfo.Framebuffer[i].RedMaskSize, + binfo.Framebuffer[i].RedMaskShift, + binfo.Framebuffer[i].GreenMaskSize, + binfo.Framebuffer[i].GreenMaskShift, + binfo.Framebuffer[i].BlueMaskSize, + binfo.Framebuffer[i].BlueMaskShift, + binfo.Framebuffer[i].ExtendedDisplayIdentificationData, + binfo.Framebuffer[i].EDIDSize); } binfo.Memory.Entries = MemmapResponse->entry_count; @@ -181,6 +223,12 @@ SafeFunction NIF void InitLimineAfterStack() } struct limine_memmap_entry *entry = MemmapResponse->entries[i]; + if (!entry) + { + warn("Null memory entry %ld (%#lx), skipping...", i, entry); + continue; + } + binfo.Memory.Size += entry->length; switch (entry->type) { @@ -241,47 +289,58 @@ SafeFunction NIF void InitLimineAfterStack() } binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xFFFF800000000000); + binfo.Modules[i].Size = ModuleResponse->modules[i]->size; + strncpy(binfo.Modules[i].Path, ModuleResponse->modules[i]->path, strlen(ModuleResponse->modules[i]->path) + 1); + strncpy(binfo.Modules[i].CommandLine, ModuleResponse->modules[i]->cmdline, strlen(ModuleResponse->modules[i]->cmdline) + 1); - binfo.Modules[i].Size = ModuleResponse->modules[i]->size; - debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i, - (uint64_t)ModuleResponse->modules[i]->address - 0xFFFF800000000000, ModuleResponse->modules[i]->path, - ModuleResponse->modules[i]->cmdline, ModuleResponse->modules[i]->size); + + debug("Module %d:\nAddress: %#lx\nPath: \"%s\"\nCommand Line: \"%s\"\nSize: %ld", + i, + binfo.Modules[i].Address, + binfo.Modules[i].Path, + binfo.Modules[i].CommandLine, + binfo.Modules[i].Size); } - binfo.RSDP = (struct RSDPInfo *)((uint64_t)RsdpResponse->address - 0xFFFF800000000000); - trace("RSDP: %p(%p) [Signature: %.8s] [OEM: %.6s]", - RsdpResponse->address, binfo.RSDP, binfo.RSDP->Signature, binfo.RSDP->OEMID); + binfo.RSDP = (struct RSDPInfo *)((uintptr_t)RsdpResponse->address - 0xFFFF800000000000); + debug("RSDP: %#lx [Signature: \"%.8s\"] [OEM: \"%.6s\"]", + binfo.RSDP, binfo.RSDP->Signature, binfo.RSDP->OEMID); - debug("SMBIOS: %p %p", SmbiosResponse->entry_32, SmbiosResponse->entry_64); - if (SmbiosResponse->entry_32 != NULL) - binfo.SMBIOSPtr = (void *)((uint64_t)SmbiosResponse->entry_32 - 0xFFFF800000000000); - else if (SmbiosResponse->entry_64 != NULL) - binfo.SMBIOSPtr = (void *)((uint64_t)SmbiosResponse->entry_64 - 0xFFFF800000000000); + if (SmbiosResponse->entry_64 != NULL) + binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_64 - 0xFFFF800000000000); + else if (SmbiosResponse->entry_32 != NULL) + binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_32 - 0xFFFF800000000000); else binfo.SMBIOSPtr = NULL; + debug("SMBIOS: %#lx %#lx (binfo: %#lx)", + SmbiosResponse->entry_32, + SmbiosResponse->entry_64, + binfo.SMBIOSPtr); binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base; binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base; - binfo.Kernel.FileBase = (void *)((uint64_t)KernelFileResponse->kernel_file->address - 0xFFFF800000000000); + binfo.Kernel.FileBase = (void *)((uintptr_t)KernelFileResponse->kernel_file->address - 0xFFFF800000000000); + binfo.Kernel.Size = KernelFileResponse->kernel_file->size; + strncpy(binfo.Kernel.CommandLine, KernelFileResponse->kernel_file->cmdline, strlen(KernelFileResponse->kernel_file->cmdline) + 1); - binfo.Kernel.Size = KernelFileResponse->kernel_file->size; - trace("Kernel physical address: %p", KernelAddressResponse->physical_base); - trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base); + + debug("Kernel physical address: %#lx", binfo.Kernel.PhysicalBase); + debug("Kernel virtual address: %#lx", binfo.Kernel.VirtualBase); strncpy(binfo.Bootloader.Name, BootloaderInfoResponse->name, strlen(BootloaderInfoResponse->name) + 1); + strncpy(binfo.Bootloader.Version, BootloaderInfoResponse->version, strlen(BootloaderInfoResponse->version) + 1); - // Call kernel entry point Entry(&binfo); } diff --git a/Architecture/amd64/SystemCalls.cpp b/Architecture/amd64/SystemCalls.cpp index 5f2c529..25775b3 100644 --- a/Architecture/amd64/SystemCalls.cpp +++ b/Architecture/amd64/SystemCalls.cpp @@ -29,7 +29,7 @@ extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs); extern "C" void SystemCallHandlerStub(); -extern "C" __naked __used __no_stack_protector void SystemCallHandlerStub() +extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub() { asmv("swapgs\n" diff --git a/Architecture/amd64/acpi.hpp b/Architecture/amd64/acpi.hpp index f3b7093..e6ea0cd 100644 --- a/Architecture/amd64/acpi.hpp +++ b/Architecture/amd64/acpi.hpp @@ -198,7 +198,7 @@ namespace ACPI void *FindTable(ACPIHeader *ACPIHeader, char *Signature); void SearchTables(ACPIHeader *Header); - ACPI(BootInfo *Info); + ACPI(); ~ACPI(); }; diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp index 29c3cc9..d0fd298 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp @@ -48,10 +48,12 @@ namespace APIC uint32_t APIC::Read(uint32_t Register) { +#ifdef DEBUG if (Register != APIC_ICRLO && Register != APIC_ICRHI && Register != APIC_ID) debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0); +#endif if (x2APICSupported) { if (Register != APIC_ICRHI) @@ -70,6 +72,7 @@ namespace APIC void APIC::Write(uint32_t Register, uint32_t Value) { +#ifdef DEBUG if (Register != APIC_EOI && Register != APIC_TDCR && Register != APIC_TIMER && @@ -77,6 +80,7 @@ namespace APIC Register != APIC_ICRLO && Register != APIC_ICRHI) debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0); +#endif if (x2APICSupported) { if (Register != APIC_ICRHI) @@ -129,8 +133,8 @@ namespace APIC SmartCriticalSection(APICLock); if (x2APICSupported) { - fixme("Not implemented for x2APIC"); - // wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32); + wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw)); + this->WaitForIPI(); } else { @@ -145,8 +149,11 @@ namespace APIC SmartCriticalSection(APICLock); if (x2APICSupported) { - fixme("Not implemented for x2APIC"); - // wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32); + InterruptCommandRegisterLow icr = {.raw = 0}; + icr.DeliveryMode = INIT; + icr.Level = Assert; + wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw)); + this->WaitForIPI(); } else { @@ -164,8 +171,12 @@ namespace APIC SmartCriticalSection(APICLock); if (x2APICSupported) { - warn("Not tested for x2APIC"); - wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32 | StartupAddress); + InterruptCommandRegisterLow icr = {.raw = 0}; + icr.Vector = s_cst(uint8_t, StartupAddress >> 12); + icr.DeliveryMode = Startup; + icr.Level = Assert; + wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw)); + this->WaitForIPI(); } else { @@ -254,6 +265,7 @@ namespace APIC uint64_t BaseHigh = BaseStruct.ApicBaseHi; this->APICBaseAddress = BaseLow << 12u | BaseHigh << 32u; trace("APIC Address: %#lx", this->APICBaseAddress); + Memory::Virtual().Map((void *)this->APICBaseAddress, (void *)this->APICBaseAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD); bool x2APICSupported = false; if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) @@ -270,7 +282,11 @@ namespace APIC { CPU::x86::Intel::CPUID0x00000001 cpuid; cpuid.Get(); - x2APICSupported = cpuid.ECX.x2APIC; + if (cpuid.ECX.x2APIC) + { + // x2APICSupported = cpuid.ECX.x2APIC; + fixme("x2APIC is supported"); + } } if (x2APICSupported) diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp index a75d11b..5dc43de 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp @@ -115,8 +115,8 @@ namespace GlobalDescriptorTable .TaskStateSegment = {}, }; - GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; - GlobalDescriptorTableDescriptor gdt[MAX_CPU]; + GlobalDescriptorTableEntries GDTEntries[MAX_CPU] __aligned(16); + GlobalDescriptorTableDescriptor gdt[MAX_CPU] __aligned(16); TaskStateSegment tss[MAX_CPU] = { 0, @@ -154,12 +154,14 @@ namespace GlobalDescriptorTable "movw %%ax, %%es\n" :: : "memory", "rax"); - CPUStackPointer[Core] = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); + CPUStackPointer[Core] = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); memset(CPUStackPointer[Core], 0, STACK_SIZE); - debug("CPU %d Stack Pointer: %#lx", Core, CPUStackPointer[Core]); + debug("CPU %d Stack Pointer: %#lx-%#lx (%d pages)", Core, + CPUStackPointer[Core], (uintptr_t)CPUStackPointer[Core] + STACK_SIZE, + TO_PAGES(STACK_SIZE + 1)); - uint64_t Base = (uint64_t)&tss[Core]; - uint64_t Limit = Base + sizeof(TaskStateSegment); + uintptr_t Base = (uintptr_t)&tss[Core]; + size_t Limit = Base + sizeof(TaskStateSegment); gdt[Core].Entries->TaskStateSegment.Length = Limit & 0xFFFF; gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF; gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF; @@ -170,12 +172,15 @@ namespace GlobalDescriptorTable tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment); tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE; - tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; - tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; - tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; - memset((void *)(tss[Core].InterruptStackTable[0] - STACK_SIZE), 0, STACK_SIZE); - memset((void *)(tss[Core].InterruptStackTable[1] - STACK_SIZE), 0, STACK_SIZE); - memset((void *)(tss[Core].InterruptStackTable[2] - STACK_SIZE), 0, STACK_SIZE); + + for (size_t i = 0; i < sizeof(tss[Core].InterruptStackTable) / sizeof(tss[Core].InterruptStackTable[7]); i++) + { + void *NewStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); + + tss[Core].InterruptStackTable[i] = (uint64_t)NewStack + STACK_SIZE; + memset((void *)(tss[Core].InterruptStackTable[i] - STACK_SIZE), 0, STACK_SIZE); + debug("IST-%d: %#lx-%#lx", i, NewStack, (uintptr_t)NewStack + STACK_SIZE); + } CPU::x64::ltr(GDT_TSS); diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp index 9112db0..8f2d04b 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp @@ -23,6 +23,7 @@ #include #include "gdt.hpp" +#include "../../../kernel.h" /* conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘unsigned char:2’ may change value */ #pragma GCC diagnostic ignored "-Wconversion" @@ -41,24 +42,25 @@ namespace InterruptDescriptorTable void SetEntry(uint8_t Index, void (*Base)(), - InterruptDescriptorTableFlags Attribute, uint8_t InterruptStackTable, - InterruptDescriptorTableFlags Ring, + InterruptGateType Gate, + InterruptRingType Ring, + bool Present, uint16_t SegmentSelector) { Entries[Index].BaseLow = s_cst(uint16_t, ((uint64_t)Base & 0xFFFF)); Entries[Index].BaseHigh = s_cst(uint64_t, ((uint64_t)Base >> 16 /* & 0xFFFF */)); Entries[Index].SegmentSelector = SegmentSelector; - Entries[Index].Flags = Attribute; + Entries[Index].Flags = Gate; Entries[Index].Reserved1 = 0; Entries[Index].Reserved2 = 0; Entries[Index].Reserved3 = 0; Entries[Index].InterruptStackTable = InterruptStackTable; Entries[Index].Ring = Ring; - Entries[Index].Present = 1; + Entries[Index].Present = Present; } - extern "C" __naked __used __no_stack_protector void ExceptionHandlerStub() + extern "C" __naked __used __no_stack_protector __aligned(16) void ExceptionHandlerStub() { asm("cld\n" @@ -102,7 +104,7 @@ namespace InterruptDescriptorTable "iretq"); // pop CS RIP RFLAGS SS RSP } - extern "C" __naked __used __no_stack_protector void InterruptHandlerStub() + extern "C" __naked __used __no_stack_protector __aligned(16) void InterruptHandlerStub() { asm("cld\n" @@ -148,25 +150,25 @@ namespace InterruptDescriptorTable #pragma region Exceptions -#define EXCEPTION_HANDLER(num) \ - __naked __used __no_stack_protector static void InterruptHandler_##num() \ - { \ - asm("pushq $0\npushq $" #num "\n" \ - "jmp ExceptionHandlerStub"); \ +#define EXCEPTION_HANDLER(num) \ + __naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ } -#define EXCEPTION_ERROR_HANDLER(num) \ - __naked __used __no_stack_protector static void InterruptHandler_##num() \ - { \ - asm("pushq $" #num "\n" \ - "jmp ExceptionHandlerStub"); \ +#define EXCEPTION_ERROR_HANDLER(num) \ + __naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \ + { \ + asm("pushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ } -#define INTERRUPT_HANDLER(num) \ - __naked __used __no_stack_protector void InterruptHandler_##num() \ - { \ - asm("pushq $0\npushq $" #num "\n" \ - "jmp InterruptHandlerStub\n"); \ +#define INTERRUPT_HANDLER(num) \ + __naked __used __no_stack_protector __aligned(16) void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp InterruptHandlerStub\n"); \ } /* ISR */ @@ -472,271 +474,280 @@ namespace InterruptDescriptorTable /* ISR */ - SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1, InterruptHandler_0x1, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2, InterruptHandler_0x2, FlagGate_32BIT_TRAP, 2, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3, InterruptHandler_0x3, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4, InterruptHandler_0x4, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5, InterruptHandler_0x5, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6, InterruptHandler_0x6, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7, InterruptHandler_0x7, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8, InterruptHandler_0x8, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9, InterruptHandler_0x9, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa, InterruptHandler_0xa, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb, InterruptHandler_0xb, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc, InterruptHandler_0xc, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd, InterruptHandler_0xd, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe, InterruptHandler_0xe, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf, InterruptHandler_0xf, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x10, InterruptHandler_0x10, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x11, InterruptHandler_0x11, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x12, InterruptHandler_0x12, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x13, InterruptHandler_0x13, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x14, InterruptHandler_0x14, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x15, InterruptHandler_0x15, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x16, InterruptHandler_0x16, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x17, InterruptHandler_0x17, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x18, InterruptHandler_0x18, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x19, InterruptHandler_0x19, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1a, InterruptHandler_0x1a, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1b, InterruptHandler_0x1b, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1c, InterruptHandler_0x1c, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1d, InterruptHandler_0x1d, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1e, InterruptHandler_0x1e, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x1f, InterruptHandler_0x1f, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); +#ifdef DEBUG + if (!DebuggerIsAttached) + { +#endif + SetEntry(0x0, InterruptHandler_0x0, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1, InterruptHandler_0x1, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2, InterruptHandler_0x2, 2, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3, InterruptHandler_0x3, 1, TRAP_32BIT, RING3, (!DebuggerIsAttached), GDT_KERNEL_CODE); /* Do not handle breakpoints if we are debugging the kernel. */ + SetEntry(0x4, InterruptHandler_0x4, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5, InterruptHandler_0x5, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6, InterruptHandler_0x6, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7, InterruptHandler_0x7, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8, InterruptHandler_0x8, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9, InterruptHandler_0x9, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa, InterruptHandler_0xa, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb, InterruptHandler_0xb, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc, InterruptHandler_0xc, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd, InterruptHandler_0xd, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe, InterruptHandler_0xe, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf, InterruptHandler_0xf, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x10, InterruptHandler_0x10, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x11, InterruptHandler_0x11, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x12, InterruptHandler_0x12, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x13, InterruptHandler_0x13, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x14, InterruptHandler_0x14, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x15, InterruptHandler_0x15, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x16, InterruptHandler_0x16, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x17, InterruptHandler_0x17, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x18, InterruptHandler_0x18, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x19, InterruptHandler_0x19, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1a, InterruptHandler_0x1a, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1b, InterruptHandler_0x1b, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1c, InterruptHandler_0x1c, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1d, InterruptHandler_0x1d, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1e, InterruptHandler_0x1e, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x1f, InterruptHandler_0x1f, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); +#ifdef DEBUG + } + else + KPrint("\eFFA500The debugger is attached, not setting up the ISR."); +#endif /* IRQ */ - SetEntry(0x20, InterruptHandler_0x20, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x21, InterruptHandler_0x21, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x22, InterruptHandler_0x22, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x23, InterruptHandler_0x23, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x24, InterruptHandler_0x24, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x25, InterruptHandler_0x25, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x26, InterruptHandler_0x26, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x27, InterruptHandler_0x27, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x28, InterruptHandler_0x28, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x29, InterruptHandler_0x29, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2a, InterruptHandler_0x2a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2b, InterruptHandler_0x2b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2c, InterruptHandler_0x2c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2d, InterruptHandler_0x2d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2e, InterruptHandler_0x2e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x2f, InterruptHandler_0x2f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x20, InterruptHandler_0x20, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x21, InterruptHandler_0x21, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x22, InterruptHandler_0x22, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x23, InterruptHandler_0x23, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x24, InterruptHandler_0x24, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x25, InterruptHandler_0x25, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x26, InterruptHandler_0x26, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x27, InterruptHandler_0x27, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x28, InterruptHandler_0x28, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x29, InterruptHandler_0x29, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2a, InterruptHandler_0x2a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2b, InterruptHandler_0x2b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2c, InterruptHandler_0x2c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2d, InterruptHandler_0x2d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2e, InterruptHandler_0x2e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x2f, InterruptHandler_0x2f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); /* Reserved by OS */ - SetEntry(0x30, InterruptHandler_0x30, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x31, InterruptHandler_0x31, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x32, InterruptHandler_0x32, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x33, InterruptHandler_0x33, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x34, InterruptHandler_0x34, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x35, InterruptHandler_0x35, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x36, InterruptHandler_0x36, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x37, InterruptHandler_0x37, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x38, InterruptHandler_0x38, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x39, InterruptHandler_0x39, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3a, InterruptHandler_0x3a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3b, InterruptHandler_0x3b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3c, InterruptHandler_0x3c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3d, InterruptHandler_0x3d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x30, InterruptHandler_0x30, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x31, InterruptHandler_0x31, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x32, InterruptHandler_0x32, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x33, InterruptHandler_0x33, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x34, InterruptHandler_0x34, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x35, InterruptHandler_0x35, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x36, InterruptHandler_0x36, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x37, InterruptHandler_0x37, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x38, InterruptHandler_0x38, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x39, InterruptHandler_0x39, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3a, InterruptHandler_0x3a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3b, InterruptHandler_0x3b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3c, InterruptHandler_0x3c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3d, InterruptHandler_0x3d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); /* Free */ - SetEntry(0x3e, InterruptHandler_0x3e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x3f, InterruptHandler_0x3f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x40, InterruptHandler_0x40, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x41, InterruptHandler_0x41, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x42, InterruptHandler_0x42, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x43, InterruptHandler_0x43, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x44, InterruptHandler_0x44, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x45, InterruptHandler_0x45, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x46, InterruptHandler_0x46, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x47, InterruptHandler_0x47, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x48, InterruptHandler_0x48, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x49, InterruptHandler_0x49, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4a, InterruptHandler_0x4a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4b, InterruptHandler_0x4b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4c, InterruptHandler_0x4c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4d, InterruptHandler_0x4d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4e, InterruptHandler_0x4e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x4f, InterruptHandler_0x4f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x50, InterruptHandler_0x50, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x51, InterruptHandler_0x51, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x52, InterruptHandler_0x52, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x53, InterruptHandler_0x53, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x54, InterruptHandler_0x54, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x55, InterruptHandler_0x55, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x56, InterruptHandler_0x56, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x57, InterruptHandler_0x57, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x58, InterruptHandler_0x58, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x59, InterruptHandler_0x59, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5a, InterruptHandler_0x5a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5b, InterruptHandler_0x5b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5c, InterruptHandler_0x5c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5d, InterruptHandler_0x5d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5e, InterruptHandler_0x5e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x5f, InterruptHandler_0x5f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x60, InterruptHandler_0x60, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x61, InterruptHandler_0x61, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x62, InterruptHandler_0x62, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x63, InterruptHandler_0x63, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x64, InterruptHandler_0x64, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x65, InterruptHandler_0x65, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x66, InterruptHandler_0x66, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x67, InterruptHandler_0x67, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x68, InterruptHandler_0x68, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x69, InterruptHandler_0x69, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6a, InterruptHandler_0x6a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6b, InterruptHandler_0x6b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6c, InterruptHandler_0x6c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6d, InterruptHandler_0x6d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6e, InterruptHandler_0x6e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x6f, InterruptHandler_0x6f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x70, InterruptHandler_0x70, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x71, InterruptHandler_0x71, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x72, InterruptHandler_0x72, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x73, InterruptHandler_0x73, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x74, InterruptHandler_0x74, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x75, InterruptHandler_0x75, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x76, InterruptHandler_0x76, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x77, InterruptHandler_0x77, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x78, InterruptHandler_0x78, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x79, InterruptHandler_0x79, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7a, InterruptHandler_0x7a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7b, InterruptHandler_0x7b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7c, InterruptHandler_0x7c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7d, InterruptHandler_0x7d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7e, InterruptHandler_0x7e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x7f, InterruptHandler_0x7f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x80, InterruptHandler_0x80, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x81, InterruptHandler_0x81, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x82, InterruptHandler_0x82, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x83, InterruptHandler_0x83, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x84, InterruptHandler_0x84, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x85, InterruptHandler_0x85, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x86, InterruptHandler_0x86, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x87, InterruptHandler_0x87, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x88, InterruptHandler_0x88, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x89, InterruptHandler_0x89, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8a, InterruptHandler_0x8a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8b, InterruptHandler_0x8b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8c, InterruptHandler_0x8c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8d, InterruptHandler_0x8d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8e, InterruptHandler_0x8e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x8f, InterruptHandler_0x8f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x90, InterruptHandler_0x90, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x91, InterruptHandler_0x91, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x92, InterruptHandler_0x92, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x93, InterruptHandler_0x93, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x94, InterruptHandler_0x94, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x95, InterruptHandler_0x95, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x96, InterruptHandler_0x96, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x97, InterruptHandler_0x97, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x98, InterruptHandler_0x98, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x99, InterruptHandler_0x99, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9a, InterruptHandler_0x9a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9b, InterruptHandler_0x9b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9c, InterruptHandler_0x9c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9d, InterruptHandler_0x9d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9e, InterruptHandler_0x9e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0x9f, InterruptHandler_0x9f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa0, InterruptHandler_0xa0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa1, InterruptHandler_0xa1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa2, InterruptHandler_0xa2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa3, InterruptHandler_0xa3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa4, InterruptHandler_0xa4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa5, InterruptHandler_0xa5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa6, InterruptHandler_0xa6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa7, InterruptHandler_0xa7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa8, InterruptHandler_0xa8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xa9, InterruptHandler_0xa9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xaa, InterruptHandler_0xaa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xab, InterruptHandler_0xab, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xac, InterruptHandler_0xac, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xad, InterruptHandler_0xad, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xae, InterruptHandler_0xae, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xaf, InterruptHandler_0xaf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb0, InterruptHandler_0xb0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb1, InterruptHandler_0xb1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb2, InterruptHandler_0xb2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb3, InterruptHandler_0xb3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb4, InterruptHandler_0xb4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb5, InterruptHandler_0xb5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb6, InterruptHandler_0xb6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb7, InterruptHandler_0xb7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb8, InterruptHandler_0xb8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xb9, InterruptHandler_0xb9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xba, InterruptHandler_0xba, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xbb, InterruptHandler_0xbb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xbc, InterruptHandler_0xbc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xbd, InterruptHandler_0xbd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xbe, InterruptHandler_0xbe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xbf, InterruptHandler_0xbf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc0, InterruptHandler_0xc0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc1, InterruptHandler_0xc1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc2, InterruptHandler_0xc2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc3, InterruptHandler_0xc3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc4, InterruptHandler_0xc4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc5, InterruptHandler_0xc5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc6, InterruptHandler_0xc6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc7, InterruptHandler_0xc7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc8, InterruptHandler_0xc8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xc9, InterruptHandler_0xc9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xca, InterruptHandler_0xca, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xcb, InterruptHandler_0xcb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xcc, InterruptHandler_0xcc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xcd, InterruptHandler_0xcd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xce, InterruptHandler_0xce, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xcf, InterruptHandler_0xcf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd0, InterruptHandler_0xd0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd1, InterruptHandler_0xd1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd2, InterruptHandler_0xd2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd3, InterruptHandler_0xd3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd4, InterruptHandler_0xd4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd5, InterruptHandler_0xd5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd6, InterruptHandler_0xd6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd7, InterruptHandler_0xd7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd8, InterruptHandler_0xd8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xd9, InterruptHandler_0xd9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xda, InterruptHandler_0xda, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xdb, InterruptHandler_0xdb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xdc, InterruptHandler_0xdc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xdd, InterruptHandler_0xdd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xde, InterruptHandler_0xde, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xdf, InterruptHandler_0xdf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe0, InterruptHandler_0xe0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe1, InterruptHandler_0xe1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe2, InterruptHandler_0xe2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe3, InterruptHandler_0xe3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe4, InterruptHandler_0xe4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe5, InterruptHandler_0xe5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe6, InterruptHandler_0xe6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe7, InterruptHandler_0xe7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe8, InterruptHandler_0xe8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xe9, InterruptHandler_0xe9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xea, InterruptHandler_0xea, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xeb, InterruptHandler_0xeb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xec, InterruptHandler_0xec, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xed, InterruptHandler_0xed, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xee, InterruptHandler_0xee, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xef, InterruptHandler_0xef, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf0, InterruptHandler_0xf0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf1, InterruptHandler_0xf1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf2, InterruptHandler_0xf2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf3, InterruptHandler_0xf3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf4, InterruptHandler_0xf4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf5, InterruptHandler_0xf5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf6, InterruptHandler_0xf6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf7, InterruptHandler_0xf7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf8, InterruptHandler_0xf8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xf9, InterruptHandler_0xf9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xfa, InterruptHandler_0xfa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xfb, InterruptHandler_0xfb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xfc, InterruptHandler_0xfc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xfd, InterruptHandler_0xfd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xfe, InterruptHandler_0xfe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); - SetEntry(0xff, InterruptHandler_0xff, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3e, InterruptHandler_0x3e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x3f, InterruptHandler_0x3f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x40, InterruptHandler_0x40, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x41, InterruptHandler_0x41, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x42, InterruptHandler_0x42, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x43, InterruptHandler_0x43, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x44, InterruptHandler_0x44, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x45, InterruptHandler_0x45, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x46, InterruptHandler_0x46, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x47, InterruptHandler_0x47, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x48, InterruptHandler_0x48, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x49, InterruptHandler_0x49, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4a, InterruptHandler_0x4a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4b, InterruptHandler_0x4b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4c, InterruptHandler_0x4c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4d, InterruptHandler_0x4d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4e, InterruptHandler_0x4e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x4f, InterruptHandler_0x4f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x50, InterruptHandler_0x50, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x51, InterruptHandler_0x51, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x52, InterruptHandler_0x52, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x53, InterruptHandler_0x53, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x54, InterruptHandler_0x54, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x55, InterruptHandler_0x55, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x56, InterruptHandler_0x56, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x57, InterruptHandler_0x57, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x58, InterruptHandler_0x58, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x59, InterruptHandler_0x59, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5a, InterruptHandler_0x5a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5b, InterruptHandler_0x5b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5c, InterruptHandler_0x5c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5d, InterruptHandler_0x5d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5e, InterruptHandler_0x5e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x5f, InterruptHandler_0x5f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x60, InterruptHandler_0x60, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x61, InterruptHandler_0x61, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x62, InterruptHandler_0x62, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x63, InterruptHandler_0x63, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x64, InterruptHandler_0x64, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x65, InterruptHandler_0x65, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x66, InterruptHandler_0x66, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x67, InterruptHandler_0x67, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x68, InterruptHandler_0x68, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x69, InterruptHandler_0x69, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6a, InterruptHandler_0x6a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6b, InterruptHandler_0x6b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6c, InterruptHandler_0x6c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6d, InterruptHandler_0x6d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6e, InterruptHandler_0x6e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x6f, InterruptHandler_0x6f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x70, InterruptHandler_0x70, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x71, InterruptHandler_0x71, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x72, InterruptHandler_0x72, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x73, InterruptHandler_0x73, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x74, InterruptHandler_0x74, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x75, InterruptHandler_0x75, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x76, InterruptHandler_0x76, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x77, InterruptHandler_0x77, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x78, InterruptHandler_0x78, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x79, InterruptHandler_0x79, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7a, InterruptHandler_0x7a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7b, InterruptHandler_0x7b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7c, InterruptHandler_0x7c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7d, InterruptHandler_0x7d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7e, InterruptHandler_0x7e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x7f, InterruptHandler_0x7f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x80, InterruptHandler_0x80, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x81, InterruptHandler_0x81, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x82, InterruptHandler_0x82, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x83, InterruptHandler_0x83, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x84, InterruptHandler_0x84, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x85, InterruptHandler_0x85, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x86, InterruptHandler_0x86, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x87, InterruptHandler_0x87, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x88, InterruptHandler_0x88, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x89, InterruptHandler_0x89, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8a, InterruptHandler_0x8a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8b, InterruptHandler_0x8b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8c, InterruptHandler_0x8c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8d, InterruptHandler_0x8d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8e, InterruptHandler_0x8e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x8f, InterruptHandler_0x8f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x90, InterruptHandler_0x90, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x91, InterruptHandler_0x91, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x92, InterruptHandler_0x92, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x93, InterruptHandler_0x93, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x94, InterruptHandler_0x94, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x95, InterruptHandler_0x95, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x96, InterruptHandler_0x96, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x97, InterruptHandler_0x97, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x98, InterruptHandler_0x98, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x99, InterruptHandler_0x99, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9a, InterruptHandler_0x9a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9b, InterruptHandler_0x9b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9c, InterruptHandler_0x9c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9d, InterruptHandler_0x9d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9e, InterruptHandler_0x9e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0x9f, InterruptHandler_0x9f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa0, InterruptHandler_0xa0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa1, InterruptHandler_0xa1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa2, InterruptHandler_0xa2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa3, InterruptHandler_0xa3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa4, InterruptHandler_0xa4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa5, InterruptHandler_0xa5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa6, InterruptHandler_0xa6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa7, InterruptHandler_0xa7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa8, InterruptHandler_0xa8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xa9, InterruptHandler_0xa9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xaa, InterruptHandler_0xaa, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xab, InterruptHandler_0xab, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xac, InterruptHandler_0xac, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xad, InterruptHandler_0xad, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xae, InterruptHandler_0xae, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xaf, InterruptHandler_0xaf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb0, InterruptHandler_0xb0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb1, InterruptHandler_0xb1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb2, InterruptHandler_0xb2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb3, InterruptHandler_0xb3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb4, InterruptHandler_0xb4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb5, InterruptHandler_0xb5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb6, InterruptHandler_0xb6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb7, InterruptHandler_0xb7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb8, InterruptHandler_0xb8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xb9, InterruptHandler_0xb9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xba, InterruptHandler_0xba, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xbb, InterruptHandler_0xbb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xbc, InterruptHandler_0xbc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xbd, InterruptHandler_0xbd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xbe, InterruptHandler_0xbe, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xbf, InterruptHandler_0xbf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc0, InterruptHandler_0xc0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc1, InterruptHandler_0xc1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc2, InterruptHandler_0xc2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc3, InterruptHandler_0xc3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc4, InterruptHandler_0xc4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc5, InterruptHandler_0xc5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc6, InterruptHandler_0xc6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc7, InterruptHandler_0xc7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc8, InterruptHandler_0xc8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xc9, InterruptHandler_0xc9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xca, InterruptHandler_0xca, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xcb, InterruptHandler_0xcb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xcc, InterruptHandler_0xcc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xcd, InterruptHandler_0xcd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xce, InterruptHandler_0xce, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xcf, InterruptHandler_0xcf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd0, InterruptHandler_0xd0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd1, InterruptHandler_0xd1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd2, InterruptHandler_0xd2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd3, InterruptHandler_0xd3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd4, InterruptHandler_0xd4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd5, InterruptHandler_0xd5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd6, InterruptHandler_0xd6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd7, InterruptHandler_0xd7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd8, InterruptHandler_0xd8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xd9, InterruptHandler_0xd9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xda, InterruptHandler_0xda, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xdb, InterruptHandler_0xdb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xdc, InterruptHandler_0xdc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xdd, InterruptHandler_0xdd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xde, InterruptHandler_0xde, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xdf, InterruptHandler_0xdf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe0, InterruptHandler_0xe0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe1, InterruptHandler_0xe1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe2, InterruptHandler_0xe2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe3, InterruptHandler_0xe3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe4, InterruptHandler_0xe4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe5, InterruptHandler_0xe5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe6, InterruptHandler_0xe6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe7, InterruptHandler_0xe7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe8, InterruptHandler_0xe8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xe9, InterruptHandler_0xe9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xea, InterruptHandler_0xea, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xeb, InterruptHandler_0xeb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xec, InterruptHandler_0xec, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xed, InterruptHandler_0xed, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xee, InterruptHandler_0xee, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xef, InterruptHandler_0xef, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf0, InterruptHandler_0xf0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf1, InterruptHandler_0xf1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf2, InterruptHandler_0xf2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf3, InterruptHandler_0xf3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf4, InterruptHandler_0xf4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf5, InterruptHandler_0xf5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf6, InterruptHandler_0xf6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf7, InterruptHandler_0xf7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf8, InterruptHandler_0xf8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xf9, InterruptHandler_0xf9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xfa, InterruptHandler_0xfa, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xfb, InterruptHandler_0xfb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xfc, InterruptHandler_0xfc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xfd, InterruptHandler_0xfd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xfe, InterruptHandler_0xfe, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); + SetEntry(0xff, InterruptHandler_0xff, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE); CPU::x64::lidt(&idtd); } } diff --git a/Architecture/amd64/cpu/SMPTrampoline.asm b/Architecture/amd64/cpu/SMPTrampoline.asm index ed8249a..ca690e6 100644 --- a/Architecture/amd64/cpu/SMPTrampoline.asm +++ b/Architecture/amd64/cpu/SMPTrampoline.asm @@ -13,8 +13,16 @@ ; You should have received a copy of the GNU General Public License ; along with Fennix Kernel. If not, see . +; This has to be the same as enum SMPTrampolineAddress. +TRAMPOLINE_PAGE_TABLE equ 0x500 +TRAMPOLINE_START_ADDR equ 0x520 +TRAMPOLINE_STACK equ 0x570 +TRAMPOLINE_GDT equ 0x580 +TRAMPOLINE_IDT equ 0x590 +TRAMPOLINE_CORE equ 0x600 +TRAMPOLINE_START equ 0x2000 + [bits 16] -TRAMPOLINE_BASE equ 0x2000 extern StartCPU global _trampoline_start @@ -26,11 +34,11 @@ _trampoline_start: mov fs, ax mov gs, ax mov ss, ax - o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_BASE] + o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_START] mov eax, cr0 or al, 0x1 mov cr0, eax - jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_BASE) + jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_START) [bits 32] section .text @@ -39,7 +47,7 @@ Trampoline32: mov ds, bx mov es, bx mov ss, bx - mov eax, dword [0x500] + mov eax, dword [TRAMPOLINE_PAGE_TABLE] mov cr3, eax mov eax, cr4 or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5). @@ -52,8 +60,8 @@ Trampoline32: mov eax, cr0 or eax, 1 << 31 mov cr0, eax - lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_BASE] - jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_BASE) + lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_START] + jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_START) [bits 64] Trampoline64: @@ -64,9 +72,9 @@ Trampoline64: mov ax, 0x0 mov fs, ax mov gs, ax - lgdt [0x580] - lidt [0x590] - mov rsp, [0x570] + lgdt [TRAMPOLINE_GDT] + lidt [TRAMPOLINE_IDT] + mov rsp, [TRAMPOLINE_STACK] mov rbp, 0x0 ; Terminate stack traces here. ; Reset RFLAGS. push 0x0 @@ -91,7 +99,7 @@ vcode64: align 16 LongMode_gdtr: dw LongModeGDTEnd - LongModeGDTStart - 1 - dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_BASE + dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_START align 16 LongModeGDTStart: @@ -103,7 +111,7 @@ LongModeGDTEnd: align 16 ProtectedMode_gdtr: dw ProtectedModeGDTEnd - ProtectedModeGDTStart - 1 - dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_BASE + dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_START align 16 ProtectedModeGDTStart: diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp index c9d6567..7f3fc51 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp @@ -17,8 +17,9 @@ #include -#include #include +#include +#include #include #include @@ -28,6 +29,7 @@ extern "C" uint64_t _trampoline_start, _trampoline_end; +/* https://wiki.osdev.org/Memory_Map_(x86) */ enum SMPTrampolineAddress { PAGE_TABLE = 0x500, @@ -39,7 +41,7 @@ enum SMPTrampolineAddress TRAMPOLINE_START = 0x2000 }; -volatile bool CPUEnabled = false; +Atomic CPUEnabled = false; #pragma GCC diagnostic ignored "-Wmissing-field-initializers" static __aligned(PAGE_SIZE) CPUData CPUs[MAX_CPU] = {0}; @@ -73,10 +75,11 @@ extern "C" void StartCPU() Interrupts::Initialize(CoreID); Interrupts::Enable(CoreID); Interrupts::InitializeTimer(CoreID); + asmv("mov %0, %%rsp" ::"r"((&CPUs[CoreID])->Stack)); CPU::Interrupts(CPU::Enable); KPrint("\e058C19CPU \e8888FF%d \e058C19is online", CoreID); - CPUEnabled = true; + CPUEnabled.Store(true, MemoryOrder::Release); CPU::Halt(true); } @@ -95,42 +98,43 @@ namespace SMP CPUCores = Cores; + uint64_t TrampolineLength = (uintptr_t)&_trampoline_end - (uintptr_t)&_trampoline_start; + Memory::Virtual().Map(0x0, 0x0, Memory::PTFlag::RW); + /* We reserved the TRAMPOLINE_START address inside Physical class. */ + Memory::Virtual().Map((void *)TRAMPOLINE_START, (void *)TRAMPOLINE_START, TrampolineLength, Memory::PTFlag::RW); + memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength); + + void *CPUTmpStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); + asmv("sgdt [0x580]\n" + "sidt [0x590]\n"); + VPOKE(uintptr_t, STACK) = (uintptr_t)CPUTmpStack + STACK_SIZE; + VPOKE(uintptr_t, PAGE_TABLE) = (uintptr_t)KernelPageTable; + VPOKE(uint64_t, START_ADDR) = (uintptr_t)&StartCPU; + for (int i = 0; i < Cores; i++) { debug("Initializing CPU %d", i); if ((((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24) != ((ACPI::MADT *)madt)->lapic[i]->ACPIProcessorId) { - ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24)); - ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500); - - Memory::Virtual(KernelPageTable).Map(0x0, 0x0, Memory::PTFlag::RW | Memory::PTFlag::US); - - uint64_t TrampolineLength = (uintptr_t)&_trampoline_end - (uintptr_t)&_trampoline_start; - Memory::Virtual(KernelPageTable).Map((void *)TRAMPOLINE_START, (void *)TRAMPOLINE_START, TrampolineLength, Memory::PTFlag::RW | Memory::PTFlag::US); - - memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength); - - VPOKE(uint64_t, PAGE_TABLE) = (uint64_t)KernelPageTable; - VPOKE(uint64_t, STACK) = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; VPOKE(int, CORE) = i; - asmv("sgdt [0x580]\n" - "sidt [0x590]\n"); - - VPOKE(uint64_t, START_ADDR) = (uintptr_t)&StartCPU; + ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24)); + ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500); ((APIC::APIC *)Interrupts::apic[0])->SendInitIPI(((ACPI::MADT *)madt)->lapic[i]->APICId); ((APIC::APIC *)Interrupts::apic[0])->SendStartupIPI(((ACPI::MADT *)madt)->lapic[i]->APICId, TRAMPOLINE_START); - while (!CPUEnabled) + while (!CPUEnabled.Load(MemoryOrder::Acquire)) CPU::Pause(); - + CPUEnabled.Store(false, MemoryOrder::Release); trace("CPU %d loaded.", ((ACPI::MADT *)madt)->lapic[i]->APICId); - KernelAllocator.FreePages((void *)*reinterpret_cast(STACK), TO_PAGES(STACK_SIZE)); - CPUEnabled = false; } else KPrint("\e058C19CPU \e8888FF%d \e058C19is the BSP", ((ACPI::MADT *)madt)->lapic[i]->APICId); } + + KernelAllocator.FreePages(CPUTmpStack, TO_PAGES(STACK_SIZE + 1)); + /* We are going to unmap the page after we are done with it. */ + Memory::Virtual().Unmap(0x0); } } diff --git a/Architecture/amd64/cpu/gdt.hpp b/Architecture/amd64/cpu/gdt.hpp index 03b5699..7eec05d 100644 --- a/Architecture/amd64/cpu/gdt.hpp +++ b/Architecture/amd64/cpu/gdt.hpp @@ -32,42 +32,42 @@ namespace GlobalDescriptorTable /** @brief Access bit. * @note The CPU sets this bit to 1 when the segment is accessed. */ - uint8_t A : 1; + uint64_t A : 1; /** @brief Readable bit for code segments, writable bit for data segments. * @details For code segments, this bit must be 1 for the segment to be readable. * @details For data segments, this bit must be 1 for the segment to be writable. */ - uint8_t RW : 1; + uint64_t RW : 1; /** @brief Direction bit for data segments, conforming bit for code segments. * @details For data segments, this bit must be 1 for the segment to grow up (higher addresses). * @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level. */ - uint8_t DC : 1; + uint64_t DC : 1; /** @brief Executable bit. * @details This bit must be 1 for code-segment descriptors. * @details This bit must be 0 for data-segment and system descriptors. */ - uint8_t E : 1; + uint64_t E : 1; /** @brief Descriptor type. * @details This bit must be 0 for system descriptors. * @details This bit must be 1 for code or data segment descriptor. */ - uint8_t S : 1; + uint64_t S : 1; /** @brief Descriptor privilege level. * @details This field determines the privilege level of the segment. * @details 0 = kernel mode, 3 = user mode. */ - uint8_t DPL : 2; + uint64_t DPL : 2; /** @brief Present bit. * @details This bit must be 1 for all valid descriptors. */ - uint8_t P : 1; + uint64_t P : 1; } __packed; uint8_t Raw; }; @@ -78,13 +78,13 @@ namespace GlobalDescriptorTable struct { /** @brief Unknown. */ - uint8_t Unknown : 5; + uint64_t Unknown : 5; /** @brief Long mode. * @details If the long mode bit is clear, the segment is in 32-bit protected mode. * @details If the long mode bit is set, the segment is in 64-bit long mode. */ - uint8_t L : 1; + uint64_t L : 1; } __packed; uint8_t Raw; }; @@ -105,7 +105,7 @@ namespace GlobalDescriptorTable typedef struct _TaskStateSegment { - uint32_t Reserved0 __aligned(0x10); + uint32_t Reserved0 __aligned(16); uint64_t StackPointer[3]; uint64_t Reserved1; uint64_t InterruptStackTable[7]; diff --git a/Architecture/amd64/cpu/idt.hpp b/Architecture/amd64/cpu/idt.hpp index 15b10d8..719b66c 100644 --- a/Architecture/amd64/cpu/idt.hpp +++ b/Architecture/amd64/cpu/idt.hpp @@ -22,19 +22,22 @@ namespace InterruptDescriptorTable { - typedef enum _InterruptDescriptorTableFlags + typedef enum _InterruptGateType { - FlagGate_TASK = 0b101, - FlagGate_16BIT_INT = 0b110, - FlagGate_16BIT_TRAP = 0b111, - FlagGate_32BIT_INT = 0b1110, - FlagGate_32BIT_TRAP = 0b1111, - FlagGate_RING0 = 0b0, - FlagGate_RING1 = 0b1, - FlagGate_RING2 = 0b10, - FlagGate_RING3 = 0b11, - FlagGate_PRESENT = 0b1, // Not sure if this is correct. - } InterruptDescriptorTableFlags; + TASK = 0b101, + INT_16BIT = 0b110, + TRAP_16BIT = 0b111, + INT_32BIT = 0b1110, + TRAP_32BIT = 0b1111, + } InterruptGateType; + + typedef enum _InterruptRingType + { + RING0 = 0b0, + RING1 = 0b1, + RING2 = 0b10, + RING3 = 0b11, + } InterruptRingType; typedef struct _InterruptDescriptorTableEntry { @@ -42,7 +45,7 @@ namespace InterruptDescriptorTable uint64_t SegmentSelector : 16; uint64_t InterruptStackTable : 3; uint64_t Reserved1 : 5; - InterruptDescriptorTableFlags Flags : 4; + uint64_t Flags : 4; uint64_t Reserved2 : 1; uint64_t Ring : 2; uint64_t Present : 1; @@ -56,7 +59,14 @@ namespace InterruptDescriptorTable InterruptDescriptorTableEntry *Entries; } __packed InterruptDescriptorTableDescriptor; - void SetEntry(uint8_t Index, void (*Base)(), InterruptDescriptorTableFlags Attribute, uint8_t InterruptStackTable, InterruptDescriptorTableFlags Ring, uint16_t SegmentSelector); + void SetEntry(uint8_t Index, + void (*Base)(), + uint8_t InterruptStackTable, + InterruptGateType Gate, + InterruptRingType Ring, + bool Present, + uint16_t SegmentSelector); + void Init(int Core); } diff --git a/Architecture/i386/Bootstrap/Multiboot2.cpp b/Architecture/i386/Bootstrap/Multiboot2.cpp index 013c924..423567e 100644 --- a/Architecture/i386/Bootstrap/Multiboot2.cpp +++ b/Architecture/i386/Bootstrap/Multiboot2.cpp @@ -199,7 +199,6 @@ void ProcessMB2(unsigned long Info) mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; - mb2binfo.Framebuffer[fb_count].MemoryModel = fb->common.framebuffer_type; switch (fb->common.framebuffer_type) { case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: diff --git a/Architecture/i386/cpu/gdt.hpp b/Architecture/i386/cpu/gdt.hpp index 94f8262..92e4301 100644 --- a/Architecture/i386/cpu/gdt.hpp +++ b/Architecture/i386/cpu/gdt.hpp @@ -105,7 +105,7 @@ namespace GlobalDescriptorTable typedef struct _TaskStateSegment { - uint32_t Reserved0 __aligned(0x10); + uint32_t Reserved0 __aligned(16); uint64_t StackPointer[3]; uint64_t Reserved1; uint64_t InterruptStackTable[7]; diff --git a/Core/CPU.cpp b/Core/CPU.cpp index 6641771..8c5d554 100644 --- a/Core/CPU.cpp +++ b/Core/CPU.cpp @@ -30,19 +30,21 @@ namespace CPU char *Vendor() { - static char Vendor[13]; + static char Vendor[13] = {0}; + if (Vendor[0] != 0) + return Vendor; #if defined(a64) uint32_t eax, ebx, ecx, edx; x64::cpuid(0x0, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Vendor + 0, &ebx, 4); - memcpy_unsafe(Vendor + 4, &edx, 4); - memcpy_unsafe(Vendor + 8, &ecx, 4); + memcpy(Vendor + 0, &ebx, 4); + memcpy(Vendor + 4, &edx, 4); + memcpy(Vendor + 8, &ecx, 4); #elif defined(a32) uint32_t eax, ebx, ecx, edx; x32::cpuid(0x0, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Vendor + 0, &ebx, 4); - memcpy_unsafe(Vendor + 4, &edx, 4); - memcpy_unsafe(Vendor + 8, &ecx, 4); + memcpy(Vendor + 0, &ebx, 4); + memcpy(Vendor + 4, &edx, 4); + memcpy(Vendor + 8, &ecx, 4); #elif defined(aa64) asmv("mrs %0, MIDR_EL1" : "=r"(Vendor[0])); @@ -52,41 +54,43 @@ namespace CPU char *Name() { - static char Name[49]; + static char Name[49] = {0}; + if (Name[0] != 0) + return Name; #if defined(a64) uint32_t eax, ebx, ecx, edx; x64::cpuid(0x80000002, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 0, &eax, 4); - memcpy_unsafe(Name + 4, &ebx, 4); - memcpy_unsafe(Name + 8, &ecx, 4); - memcpy_unsafe(Name + 12, &edx, 4); + memcpy(Name + 0, &eax, 4); + memcpy(Name + 4, &ebx, 4); + memcpy(Name + 8, &ecx, 4); + memcpy(Name + 12, &edx, 4); x64::cpuid(0x80000003, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 16, &eax, 4); - memcpy_unsafe(Name + 20, &ebx, 4); - memcpy_unsafe(Name + 24, &ecx, 4); - memcpy_unsafe(Name + 28, &edx, 4); + memcpy(Name + 16, &eax, 4); + memcpy(Name + 20, &ebx, 4); + memcpy(Name + 24, &ecx, 4); + memcpy(Name + 28, &edx, 4); x64::cpuid(0x80000004, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 32, &eax, 4); - memcpy_unsafe(Name + 36, &ebx, 4); - memcpy_unsafe(Name + 40, &ecx, 4); - memcpy_unsafe(Name + 44, &edx, 4); + memcpy(Name + 32, &eax, 4); + memcpy(Name + 36, &ebx, 4); + memcpy(Name + 40, &ecx, 4); + memcpy(Name + 44, &edx, 4); #elif defined(a32) uint32_t eax, ebx, ecx, edx; x32::cpuid(0x80000002, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 0, &eax, 4); - memcpy_unsafe(Name + 4, &ebx, 4); - memcpy_unsafe(Name + 8, &ecx, 4); - memcpy_unsafe(Name + 12, &edx, 4); + memcpy(Name + 0, &eax, 4); + memcpy(Name + 4, &ebx, 4); + memcpy(Name + 8, &ecx, 4); + memcpy(Name + 12, &edx, 4); x32::cpuid(0x80000003, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 16, &eax, 4); - memcpy_unsafe(Name + 20, &ebx, 4); - memcpy_unsafe(Name + 24, &ecx, 4); - memcpy_unsafe(Name + 28, &edx, 4); + memcpy(Name + 16, &eax, 4); + memcpy(Name + 20, &ebx, 4); + memcpy(Name + 24, &ecx, 4); + memcpy(Name + 28, &edx, 4); x32::cpuid(0x80000004, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Name + 32, &eax, 4); - memcpy_unsafe(Name + 36, &ebx, 4); - memcpy_unsafe(Name + 40, &ecx, 4); - memcpy_unsafe(Name + 44, &edx, 4); + memcpy(Name + 32, &eax, 4); + memcpy(Name + 36, &ebx, 4); + memcpy(Name + 40, &ecx, 4); + memcpy(Name + 44, &edx, 4); #elif defined(aa64) asmv("mrs %0, MIDR_EL1" : "=r"(Name[0])); @@ -96,19 +100,21 @@ namespace CPU char *Hypervisor() { - static char Hypervisor[13]; + static char Hypervisor[13] = {0}; + if (Hypervisor[0] != 0) + return Hypervisor; #if defined(a64) uint32_t eax, ebx, ecx, edx; x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Hypervisor + 0, &ebx, 4); - memcpy_unsafe(Hypervisor + 4, &ecx, 4); - memcpy_unsafe(Hypervisor + 8, &edx, 4); + memcpy(Hypervisor + 0, &ebx, 4); + memcpy(Hypervisor + 4, &ecx, 4); + memcpy(Hypervisor + 8, &edx, 4); #elif defined(a32) uint32_t eax, ebx, ecx, edx; x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); - memcpy_unsafe(Hypervisor + 0, &ebx, 4); - memcpy_unsafe(Hypervisor + 4, &ecx, 4); - memcpy_unsafe(Hypervisor + 8, &edx, 4); + memcpy(Hypervisor + 0, &ebx, 4); + memcpy(Hypervisor + 4, &ecx, 4); + memcpy(Hypervisor + 8, &edx, 4); #elif defined(aa64) asmv("mrs %0, MIDR_EL1" : "=r"(Hypervisor[0])); @@ -141,7 +147,7 @@ namespace CPU } case Enable: { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("sti"); #elif defined(aa64) asmv("msr daifclr, #2"); @@ -150,7 +156,7 @@ namespace CPU } case Disable: { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cli"); #elif defined(aa64) asmv("msr daifset, #2"); @@ -195,30 +201,41 @@ namespace CPU void InitializeFeatures(long Core) { +#if defined(a64) bool PGESupport = false; bool SSESupport = false; -#if defined(a64) + bool UMIPSupport = false; + bool SMEPSupport = false; + bool SMAPSupport = false; + static int BSP = 0; x64::CR0 cr0 = x64::readcr0(); x64::CR4 cr4 = x64::readcr4(); if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { - CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); - if (cpuid.EDX.PGE) - PGESupport = true; - if (cpuid.EDX.SSE) - SSESupport = true; + CPU::x86::AMD::CPUID0x00000001 cpuid1; + CPU::x86::AMD::CPUID0x00000007 cpuid7; + cpuid1.Get(); + cpuid7.Get(); + + PGESupport = cpuid1.EDX.PGE; + SSESupport = cpuid1.EDX.SSE; + SMEPSupport = cpuid7.EBX.SMEP; + SMAPSupport = cpuid7.EBX.SMAP; + UMIPSupport = cpuid7.ECX.UMIP; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { - CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); - if (cpuid.EDX.PGE) - PGESupport = true; - if (cpuid.EDX.SSE) - SSESupport = true; + CPU::x86::Intel::CPUID0x00000001 cpuid1; + CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0; + cpuid1.Get(); + cpuid7_0.Get(); + PGESupport = cpuid1.EDX.PGE; + SSESupport = cpuid1.EDX.SSE; + SMEPSupport = cpuid7_0.EBX.SMEP; + SMAPSupport = cpuid7_0.EBX.SMAP; + UMIPSupport = cpuid7_0.ECX.UMIP; } if (Config.SIMD == false) @@ -251,7 +268,7 @@ namespace CPU cr4.OSXMMEXCPT = 1; CPUData *CoreData = GetCPU(Core); - CoreData->Data.FPU = (CPU::x64::FXState *)KernelAllocator.RequestPages(TO_PAGES(sizeof(CPU::x64::FXState))); + CoreData->Data.FPU = (CPU::x64::FXState *)KernelAllocator.RequestPages(TO_PAGES(sizeof(CPU::x64::FXState) + 1)); memset(CoreData->Data.FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState)))); CoreData->Data.FPU->mxcsr = 0b0001111110000000; CoreData->Data.FPU->mxcsrmask = 0b1111111110111111; @@ -261,47 +278,40 @@ namespace CPU SSEEnableAfter = true; } - if (!BSP) - KPrint("Enabling CPU cache."); - cr0.NW = 0; cr0.CD = 0; cr0.WP = 1; x64::writecr0(cr0); - // FIXME: I don't think this is reporting correctly. This has to be fixed asap. - debug("Enabling UMIP, SMEP & SMAP support..."); - uint32_t eax, ebx, ecx, edx; - x64::cpuid(0x1, &eax, &ebx, &ecx, &edx); - if (edx & (1 << 2)) // https://en.wikipedia.org/wiki/Control_register - { - if (!BSP) - KPrint("UMIP is supported."); - debug("UMIP is supported."); - // cr4.UMIP = 1; - } - if (edx & (1 << 7)) // https://en.wikipedia.org/wiki/Control_register#SMEP - // https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf - { - if (!BSP) - KPrint("SMEP is supported."); - debug("SMEP is supported."); - // cr4.SMEP = 1; - } - if (edx & (1 << 20)) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention - { - if (!BSP) - KPrint("SMAP is supported."); - debug("SMAP is supported."); - // cr4.SMAP = 1; - } if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 && strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) { - debug("Writing CR4..."); - x64::writecr4(cr4); - debug("Wrote CR4."); + // FIXME: I don't think this is reporting correctly. This has to be fixed asap. + debug("Enabling UMIP, SMEP & SMAP support..."); + if (UMIPSupport) + { + if (!BSP) + KPrint("UMIP is supported."); + debug("UMIP is supported."); + // cr4.UMIP = 1; + } + + if (SMEPSupport) + { + if (!BSP) + KPrint("SMEP is supported."); + debug("SMEP is supported."); + // cr4.SMEP = 1; + } + + if (SMAPSupport) + { + if (!BSP) + KPrint("SMAP is supported."); + debug("SMAP is supported."); + // cr4.SMAP = 1; + } } else { @@ -313,6 +323,11 @@ namespace CPU KPrint("QEMU (TCG) detected. Not using UMIP, SMEP & SMAP"); } } + + debug("Writing CR4..."); + x64::writecr4(cr4); + debug("Wrote CR4."); + debug("Enabling PAT support..."); x64::wrmsr(x64::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16)); if (!BSP++) @@ -352,7 +367,7 @@ namespace CPU // return SIMD_SSE; -#if defined(a64) || defined(a32) +#if defined(a86) static uint64_t SIMDType = SIMD_NONE; if (likely(SIMDType != SIMD_NONE)) @@ -434,7 +449,7 @@ namespace CPU if (unlikely(!SSEEnabled)) return false; -#if defined(a64) || defined(a32) +#if defined(a86) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index dbbf655..01233fc 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -375,7 +375,7 @@ namespace CrashHandler int tmpidx = SBIdx; SBIdx = atoi(arg); Display->SetBuffer(SBIdx); -#if defined(a64) || defined(a32) +#if defined(a86) for (int i = 0; i < 5000000; i++) inb(0x80); #endif // a64 || a32 @@ -415,7 +415,7 @@ namespace CrashHandler EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i])); else EHPrint("\eFF4CA9Outside Kernel"); -#if defined(a64) || defined(a32) +#if defined(a86) for (int i = 0; i < 20000; i++) inb(0x80); #endif // a64 || a32 @@ -624,7 +624,7 @@ namespace CrashHandler } else { -#if defined(a64) || defined(a32) +#if defined(a86) GlobalDescriptorTable::TaskStateSegment tss = GlobalDescriptorTable::tss[TSSIndex]; EHPrint("\eFAFAFAStack Pointer 0: \eAABB22%#lx\n", tss.StackPointer[0]); EHPrint("\eFAFAFAStack Pointer 1: \eAABB22%#lx\n", tss.StackPointer[1]); @@ -779,7 +779,7 @@ namespace CrashHandler SafeFunction void StopAllCores() { -#if defined(a64) || defined(a32) +#if defined(a86) /* FIXME: Can't send IPIs to other cores * because it causes another exception on * the other cores. diff --git a/Core/Crash/KBDrv.cpp b/Core/Crash/KBDrv.cpp index 80416aa..19a1e62 100644 --- a/Core/Crash/KBDrv.cpp +++ b/Core/Crash/KBDrv.cpp @@ -96,7 +96,7 @@ namespace CrashHandler { CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */ { -#if defined(a64) || defined(a32) +#if defined(a86) while (inb(0x64) & 0x1) inb(0x60); @@ -109,7 +109,7 @@ namespace CrashHandler outb(0x21, 0xFD); outb(0xA1, 0xFF); -#endif // defined(a64) || defined(a32) +#endif // defined(a86) CPU::Interrupts(CPU::Enable); // Just to be sure. } @@ -130,7 +130,7 @@ namespace CrashHandler SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) #endif { -#if defined(a64) || defined(a32) +#if defined(a86) UNUSED(Frame); uint8_t scanCode = inb(0x60); if (scanCode == KEY_D_TAB || @@ -184,7 +184,7 @@ namespace CrashHandler SafeFunction void HookKeyboard() { CrashKeyboardDriver kbd; // We don't want to allocate memory. -#if defined(a64) || defined(a32) +#if defined(a86) asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;"); #elif defined(aa64) asmv("KeyboardHookLoop: nop; b KeyboardHookLoop;"); diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp index d793f50..f23e97d 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/Core/Crash/Screens/Details.cpp @@ -87,7 +87,7 @@ namespace CrashHandler #elif defined(aa64) #endif -#if defined(a64) || defined(a32) +#if defined(a86) EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", data.cr0.raw, data.cr2.raw, data.cr3.raw, data.cr4.raw, data.cr8.raw); EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", data.dr0, data.dr1, data.dr2, data.dr3, data.dr6, data.dr7.raw); @@ -136,7 +136,7 @@ namespace CrashHandler #elif defined(aa64) #endif -#if defined(a64) || defined(a32) +#if defined(a86) EHPrint("\eA0F0F0DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s\n LDR2:%s GDR2:%s LDR3:%s GDR3:%s\n CDR0:%s SDR0:%s CDR1:%s SDR1:%s\n CDR2:%s SDR2:%s CDR3:%s SDR3:%s\n R:%#x\n", data.dr7.LocalDR0 ? "True " : "False", data.dr7.GlobalDR0 ? "True " : "False", data.dr7.LocalDR1 ? "True " : "False", data.dr7.GlobalDR1 ? "True " : "False", data.dr7.LocalDR2 ? "True " : "False", data.dr7.GlobalDR2 ? "True " : "False", data.dr7.LocalDR3 ? "True " : "False", data.dr7.GlobalDR3 ? "True " : "False", diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index f908f46..89e3958 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -99,7 +99,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) #elif defined(aa64) #endif -#if defined(a64) || defined(a32) +#if defined(a86) error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", @@ -113,7 +113,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("CR3: PWT:%s PCD:%s PDBR:%#llx", cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); -#endif // defined(a64) || defined(a32) +#endif // defined(a86) #if defined(a64) error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", @@ -133,9 +133,9 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) cr4.Reserved0, cr4.Reserved1); #endif -#if defined(a64) || defined(a32) +#if defined(a86) error("CR8: TPL:%d", cr8.TPL); -#endif // defined(a64) || defined(a32) +#endif // defined(a86) #if defined(a64) error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", @@ -156,7 +156,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) #elif defined(aa64) #endif -#if defined(a64) || defined(a32) +#if defined(a86) error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", diff --git a/Core/Disk.cpp b/Core/Disk.cpp index b4c79c5..ffff79d 100644 --- a/Core/Disk.cpp +++ b/Core/Disk.cpp @@ -28,21 +28,17 @@ namespace Disk { void Manager::FetchDisks(unsigned long DriverUID) { - KernelCallback *callback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback))); - memset(callback, 0, sizeof(KernelCallback)); - callback->Reason = FetchReason; - DriverManager->IOCB(DriverUID, (void *)callback); - this->AvailablePorts = callback->DiskCallback.Fetch.Ports; - this->BytesPerSector = callback->DiskCallback.Fetch.BytesPerSector; + KernelCallback callback{}; + callback.Reason = FetchReason; + DriverManager->IOCB(DriverUID, (void *)&callback); + this->AvailablePorts = callback.DiskCallback.Fetch.Ports; + this->BytesPerSector = callback.DiskCallback.Fetch.BytesPerSector; debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector); if (this->AvailablePorts <= 0) - { - KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback))); return; - } - uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector)); + uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector + 1)); for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++) { @@ -53,16 +49,15 @@ namespace Disk drive->MechanicalDisk = true; memset(RWBuffer, 0, this->BytesPerSector); - memset(callback, 0, sizeof(KernelCallback)); - callback->Reason = ReceiveReason; - callback->DiskCallback.RW = { + callback.Reason = ReceiveReason; + callback.DiskCallback.RW = { .Sector = 0, .SectorCount = 2, .Port = ItrPort, .Buffer = RWBuffer, .Write = false, }; - DriverManager->IOCB(DriverUID, (void *)callback); + DriverManager->IOCB(DriverUID, (void *)&callback); memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable)); /* @@ -77,16 +72,15 @@ namespace Disk for (uint32_t Block = 0; Block < Sectors; Block++) { memset(RWBuffer, 0, this->BytesPerSector); - memset(callback, 0, sizeof(KernelCallback)); - callback->Reason = ReceiveReason; - callback->DiskCallback.RW = { + callback.Reason = ReceiveReason; + callback.DiskCallback.RW = { .Sector = 2 + Block, .SectorCount = 1, .Port = ItrPort, .Buffer = RWBuffer, .Write = false, }; - DriverManager->IOCB(DriverUID, (void *)callback); + DriverManager->IOCB(DriverUID, (void *)&callback); for (uint32_t e = 0; e < Entries; e++) { @@ -160,8 +154,8 @@ namespace Disk drives.push_back(drive); } - - KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback))); + + KernelAllocator.FreePages(RWBuffer, TO_PAGES(this->BytesPerSector + 1)); } Manager::Manager() diff --git a/Core/Driver/Driver.cpp b/Core/Driver/Driver.cpp index 24565b0..2de3815 100644 --- a/Core/Driver/Driver.cpp +++ b/Core/Driver/Driver.cpp @@ -85,6 +85,7 @@ namespace Driver { if (!drv.InterruptHook[j]) break; + debug("Interrupt hook %#lx", drv.InterruptHook[j]); delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr; } if (drv.MemTrk) @@ -106,11 +107,12 @@ namespace Driver debug("Stopping and unloading driver %ld [%#lx]", drv.DriverUID, drv.Address); this->IOCB(drv.DriverUID, (void *)&callback); - for (size_t i = 0; i < sizeof(drv.InterruptHook) / sizeof(drv.InterruptHook[0]); i++) + for (size_t j = 0; j < sizeof(drv.InterruptHook) / sizeof(drv.InterruptHook[0]); j++) { - if (!drv.InterruptHook[i]) + if (!drv.InterruptHook[j]) break; - delete drv.InterruptHook[i], drv.InterruptHook[i] = nullptr; + debug("Interrupt hook %#lx", drv.InterruptHook[j]); + delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr; } delete drv.MemTrk, drv.MemTrk = nullptr; Drivers.remove(i); @@ -141,6 +143,7 @@ namespace Driver ((KernelAPI *)KAPIAddress)->Info.Offset = (unsigned long)fex; ((KernelAPI *)KAPIAddress)->Info.DriverUID = DriverUIDs++; + ((KernelAPI *)KAPIAddress)->Info.KernelDebug = DebuggerIsAttached; #ifdef DEBUG FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); @@ -273,7 +276,7 @@ namespace Driver SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */ if (!Handle.InterruptCallback) { -#if defined(a64) || defined(a32) +#if defined(a86) uint64_t IntNum = Frame->InterruptNumber - 32; #elif defined(aa64) uint64_t IntNum = Frame->InterruptNumber; @@ -332,7 +335,7 @@ namespace Driver DriverInterruptHook::DriverInterruptHook(int Interrupt, DriverFile Handle) : Interrupts::Handler(Interrupt) { this->Handle = Handle; -#if defined(a64) || defined(a32) +#if defined(a86) trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); #elif defined(aa64) trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); diff --git a/Core/Driver/DriverAPI.cpp b/Core/Driver/DriverAPI.cpp index 0e774b4..5e41f61 100644 --- a/Core/Driver/DriverAPI.cpp +++ b/Core/Driver/DriverAPI.cpp @@ -46,7 +46,7 @@ void DriverDisplayPrint(char *String) void *RequestPage(unsigned long Size) { - void *ret = KernelAllocator.RequestPages(Size); + void *ret = KernelAllocator.RequestPages(Size + 1); drvdbg("Allocated %ld pages (%#lx-%#lx)", Size, (unsigned long)ret, (unsigned long)ret + FROM_PAGES(Size)); return ret; } @@ -54,7 +54,7 @@ void *RequestPage(unsigned long Size) void FreePage(void *Page, unsigned long Size) { drvdbg("Freeing %ld pages (%#lx-%#lx)", Size, (unsigned long)Page, (unsigned long)Page + FROM_PAGES(Size)); - KernelAllocator.FreePages(Page, Size); + KernelAllocator.FreePages(Page, Size + 1); } void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags) @@ -164,6 +164,7 @@ KernelAPI KernelAPITemplate = { .Info = { .Offset = 0, .DriverUID = 0, + .KernelDebug = false, }, .Memory = { .PageSize = PAGE_SIZE, diff --git a/Core/Driver/DriverLoading/BindInput.cpp b/Core/Driver/DriverLoading/BindInput.cpp index 7804f23..084030b 100644 --- a/Core/Driver/DriverLoading/BindInput.cpp +++ b/Core/Driver/DriverLoading/BindInput.cpp @@ -59,7 +59,7 @@ namespace Driver DriverCode Driver::BindInputInput(Memory::MemMgr *mem, void *fex) { FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); - KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback) + 1)); fixme("Input driver: %s", fexExtended->Driver.Name); KCallback->RawPtr = nullptr; @@ -100,7 +100,7 @@ namespace Driver UNUSED(DrvExtHdr); UNUSED(IsElf); Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); - Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size)); + Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1)); memcpy(fex, (void *)DriverAddress, Size); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); @@ -111,7 +111,7 @@ namespace Driver result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]); kfree(result); #endif - KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI))); + KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1)); if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK) { diff --git a/Core/Driver/DriverLoading/BindInterrupt.cpp b/Core/Driver/DriverLoading/BindInterrupt.cpp index 4c7c17e..8c09a4f 100644 --- a/Core/Driver/DriverLoading/BindInterrupt.cpp +++ b/Core/Driver/DriverLoading/BindInterrupt.cpp @@ -455,7 +455,7 @@ namespace Driver { UNUSED(IsElf); Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); - Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size)); + Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1)); memcpy(fex, (void *)DriverAddress, Size); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); @@ -466,7 +466,7 @@ namespace Driver result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]); kfree(result); #endif - KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI))); + KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1)); if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK) { diff --git a/Core/Driver/DriverLoading/BindPCI.cpp b/Core/Driver/DriverLoading/BindPCI.cpp index 36489bf..4946c84 100644 --- a/Core/Driver/DriverLoading/BindPCI.cpp +++ b/Core/Driver/DriverLoading/BindPCI.cpp @@ -576,7 +576,7 @@ namespace Driver { debug("[%ld] VendorID: %#x; DeviceID: %#x", devices.size(), PCIDevice->VendorID, PCIDevice->DeviceID); Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); - Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size)); + Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1)); memcpy(fex, (void *)DriverAddress, Size); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); @@ -587,7 +587,7 @@ namespace Driver result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]); kfree(result); #endif - KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI))); + KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1)); if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK) { diff --git a/Core/InterruptsManager.cpp b/Core/InterruptsManager.cpp index 3e64817..37042e6 100644 --- a/Core/InterruptsManager.cpp +++ b/Core/InterruptsManager.cpp @@ -67,16 +67,14 @@ namespace Interrupts CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData); CoreData->ID = Core; CoreData->IsActive = true; - CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE); - CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; + CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE); + CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE; if (CoreData->Checksum != CPU_DATA_CHECKSUM) { KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM); CPU::Stop(); } debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE); - /* TODO: Implement a proper way to set the stack pointer. */ - // asmv("movq %0, %%rsp" ::"r"(CoreData->Stack)); InitializeSystemCalls(); #elif defined(a32) warn("i386 is not supported yet"); @@ -152,7 +150,7 @@ namespace Interrupts bool InterruptHandled = false; foreach (auto ev in RegisteredEvents) { -#if defined(a64) || defined(a32) +#if defined(a86) if ((ev.ID + CPU::x86::IRQ0) == static_cast(Frame->InterruptNumber)) #elif defined(aa64) if (ev.ID == static_cast(Frame->InterruptNumber)) diff --git a/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp b/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp index 2e145c9..4666b34 100644 --- a/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp +++ b/Core/Memory/HeapAllocators/Xalloc/XallocV1.cpp @@ -20,8 +20,8 @@ Xalloc_def; #define XALLOC_CONCAT(x, y) x##y -#define XStoP(x) (x / Xalloc_PAGE_SIZE + 1) -#define XPtoS(x) (x * Xalloc_PAGE_SIZE) +#define XStoP(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE) +#define XPtoS(d) ((d)*PAGE_SIZE) #define Xalloc_BlockChecksum 0xA110C extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages); @@ -70,14 +70,14 @@ namespace Xalloc Block(Xsize_t Size) { - this->Address = Xalloc_REQUEST_PAGES(XStoP(Size)); + this->Address = Xalloc_REQUEST_PAGES(XStoP(Size + 1)); this->Size = Size; Xmemset(this->Address, 0, Size); } ~Block() { - Xalloc_FREE_PAGES(this->Address, XStoP(this->Size)); + Xalloc_FREE_PAGES(this->Address, XStoP(this->Size + 1)); } /** @@ -120,7 +120,7 @@ namespace Xalloc { if (this->SMAPUsed) { -#if defined(a64) || defined(a32) +#if defined(a86) asm volatile("stac" :: : "cc"); #endif @@ -131,7 +131,7 @@ namespace Xalloc { if (this->SMAPUsed) { -#if defined(a64) || defined(a32) +#if defined(a86) asm volatile("clac" :: : "cc"); #endif @@ -209,7 +209,8 @@ namespace Xalloc { if (!CurrentBlock->Check()) { - Xalloc_err("Block %#lx checksum failed!", (Xuint64_t)CurrentBlock); + Xalloc_err("Block %#lx has an invalid checksum! (%#x != %#x)", + (Xuint64_t)CurrentBlock, CurrentBlock->Checksum, Xalloc_BlockChecksum); while (Xalloc_StopOnFail) ; } diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 4410d9a..222f6b7 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -48,7 +48,6 @@ using namespace Memory; Physical KernelAllocator; PageTable4 *KernelPageTable = nullptr; -PageTable4 *UserspaceKernelOnlyPageTable = nullptr; bool Page1GBSupport = false; bool PSESupport = false; @@ -102,9 +101,7 @@ NIF void MapFromZero(PageTable4 *PT, BootInfo *Info) else va.Map((void *)0, (void *)0, MemSize, PTFlag::RW); - void *NullAddress = KernelAllocator.RequestPage(); - memset(NullAddress, 0, PAGE_SIZE); // TODO: If the CPU instruction pointer hits this page, there should be function to handle it. (memcpy assembly code?) - va.Remap((void *)0, (void *)NullAddress, PTFlag::RW | PTFlag::US); + va.Unmap((void *)0); } NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info) @@ -171,7 +168,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info) for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); - KernelAllocator.LockPage((void *)BaseKernelMapAddress); + KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } @@ -179,7 +176,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info) for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); - KernelAllocator.LockPage((void *)BaseKernelMapAddress); + KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } @@ -187,7 +184,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info) for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G); - KernelAllocator.LockPage((void *)BaseKernelMapAddress); + KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } @@ -195,7 +192,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info) for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); - KernelAllocator.LockPage((void *)BaseKernelMapAddress); + KernelAllocator.ReservePage((void *)BaseKernelMapAddress); BaseKernelMapAddress += PAGE_SIZE; } @@ -203,7 +200,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info) for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE) { va.Map((void *)k, (void *)k, PTFlag::G); - KernelAllocator.LockPage((void *)k); + KernelAllocator.ReservePage((void *)k); } #ifdef DEBUG @@ -243,8 +240,8 @@ NIF void InitializeMemoryManagement(BootInfo *Info) #ifdef DEBUG for (uint64_t i = 0; i < Info->Memory.Entries; i++) { - uintptr_t Base = reinterpret_cast(Info->Memory.Entry[i].BaseAddress); - uintptr_t Length = Info->Memory.Entry[i].Length; + uintptr_t Base = r_cst(uintptr_t, Info->Memory.Entry[i].BaseAddress); + size_t Length = Info->Memory.Entry[i].Length; uintptr_t End = Base + Length; const char *Type = "Unknown"; @@ -293,12 +290,21 @@ NIF void InitializeMemoryManagement(BootInfo *Info) TO_MB(KernelAllocator.GetTotalMemory()), TO_MB(KernelAllocator.GetReservedMemory())); - trace("Initializing Virtual Memory Manager"); - KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); - memset(KernelPageTable, 0, PAGE_SIZE); + /* -- Debugging -- + size_t bmap_size = KernelAllocator.GetPageBitmap().Size; + for (size_t i = 0; i < bmap_size; i++) + { + bool idx = KernelAllocator.GetPageBitmap().Get(i); + if (idx == true) + debug("Page %04d: %#lx", i, i * PAGE_SIZE); + } - UserspaceKernelOnlyPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); - memset(UserspaceKernelOnlyPageTable, 0, PAGE_SIZE); + inf_loop debug("Alloc.: %#lx", KernelAllocator.RequestPage()); + */ + + trace("Initializing Virtual Memory Manager"); + KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1)); + memset(KernelPageTable, 0, PAGE_SIZE); if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { @@ -333,16 +339,11 @@ NIF void InitializeMemoryManagement(BootInfo *Info) MapFramebuffer(KernelPageTable, Info); MapKernel(KernelPageTable, Info); - memcpy(UserspaceKernelOnlyPageTable, KernelPageTable, sizeof(PageTable4)); - - trace("Applying new page table from address %p", KernelPageTable); + trace("Applying new page table from address %#lx", KernelPageTable); #ifdef DEBUG - debug("Kernel:"); tracepagetable(KernelPageTable); - debug("Userspace:"); - tracepagetable(UserspaceKernelOnlyPageTable); #endif -#if defined(a64) || defined(a32) +#if defined(a86) asmv("mov %0, %%cr3" ::"r"(KernelPageTable)); #elif defined(aa64) asmv("msr ttbr0_el1, %0" ::"r"(KernelPageTable)); @@ -372,7 +373,7 @@ void *malloc(size_t Size) { case MemoryAllocatorType::Pages: { - ret = KernelAllocator.RequestPages(TO_PAGES(Size)); + ret = KernelAllocator.RequestPages(TO_PAGES(Size + 1)); memset(ret, 0, Size); break; } @@ -425,7 +426,7 @@ void *calloc(size_t n, size_t Size) { case MemoryAllocatorType::Pages: { - ret = KernelAllocator.RequestPages(TO_PAGES(n * Size)); + ret = KernelAllocator.RequestPages(TO_PAGES(n * Size + 1)); memset(ret, 0, n * Size); break; } @@ -478,7 +479,7 @@ void *realloc(void *Address, size_t Size) { case unlikely(MemoryAllocatorType::Pages): { - ret = KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak + ret = KernelAllocator.RequestPages(TO_PAGES(Size + 1)); // WARNING: Potential memory leak memset(ret, 0, Size); break; } diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index a7f777c..f037d73 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -295,7 +295,7 @@ namespace Memory if (unlikely(Address == nullptr)) warn("Trying to reserve null address."); - uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; + uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; if (unlikely(PageBitmap[Index] == true)) return; @@ -313,7 +313,18 @@ namespace Memory warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); for (size_t t = 0; t < PageCount; t++) - this->ReservePage((void *)((uintptr_t)Address + (t * PAGE_SIZE))); + { + uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; + + if (unlikely(PageBitmap[Index] == true)) + return; + + if (PageBitmap.Set(Index, true)) + { + FreeMemory -= PAGE_SIZE; + ReservedMemory += PAGE_SIZE; + } + } } void Physical::UnreservePage(void *Address) @@ -321,7 +332,7 @@ namespace Memory if (unlikely(Address == nullptr)) warn("Trying to unreserve null address."); - uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; + uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; if (unlikely(PageBitmap[Index] == false)) return; @@ -341,7 +352,20 @@ namespace Memory warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); for (size_t t = 0; t < PageCount; t++) - this->UnreservePage((void *)((uintptr_t)Address + (t * PAGE_SIZE))); + { + uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; + + if (unlikely(PageBitmap[Index] == false)) + return; + + if (PageBitmap.Set(Index, false)) + { + FreeMemory += PAGE_SIZE; + ReservedMemory -= PAGE_SIZE; + if (PageBitmapIndex > Index) + PageBitmapIndex = Index; + } + } } void Physical::Init(BootInfo *Info) @@ -349,6 +373,7 @@ namespace Memory SmartLock(this->MemoryLock); uint64_t MemorySize = Info->Memory.Size; + debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize)); TotalMemory = MemorySize; FreeMemory = MemorySize; @@ -381,8 +406,9 @@ namespace Memory CPU::Stop(); } + /* TODO: Read swap config and make the configure the bitmap size correctly */ size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1; - trace("Initializing Bitmap at %llp-%llp (%lld Bytes)", + debug("Initializing Bitmap at %llp-%llp (%lld Bytes)", LargestFreeMemorySegment, (void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize), BitmapSize); @@ -392,16 +418,27 @@ namespace Memory for (size_t i = 0; i < BitmapSize; i++) *(uint8_t *)(PageBitmap.Buffer + i) = 0; - trace("Reserving pages..."); + debug("Reserving pages..."); for (uint64_t i = 0; i < Info->Memory.Entries; i++) { if (Info->Memory.Entry[i].Type != Usable) this->ReservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length)); } - trace("Locking bitmap pages..."); - this->ReservePages(0, 0x100); - this->LockPages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); + /* Making sure that the lower memory area is properly reserved. */ + this->ReservePages(0, 0x200); + for (uint64_t i = 0; i < Info->Memory.Entries; i++) + { + if (Info->Memory.Entry[i].Type == Usable) + this->UnreservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length)); + } + + debug("Reserving pages for SMP..."); + this->ReservePage((void *)0x0); /* Trampoline stack, gdt, idt, etc... */ + this->ReservePage((void *)0x2000); /* TRAMPOLINE_START */ + + debug("Reserving bitmap pages..."); + this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); } Physical::Physical() {} diff --git a/Core/Memory/StackGuard.cpp b/Core/Memory/StackGuard.cpp index acef567..e0f613f 100644 --- a/Core/Memory/StackGuard.cpp +++ b/Core/Memory/StackGuard.cpp @@ -28,7 +28,7 @@ namespace Memory if (this->UserMode) { - void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE)); + void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); memset(AllocatedStack, 0, USER_STACK_SIZE); debug("AllocatedStack: %p", AllocatedStack); @@ -52,7 +52,7 @@ namespace Memory } else { - this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); + this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)); memset(this->StackBottom, 0, STACK_SIZE); debug("StackBottom: %p", this->StackBottom); @@ -70,7 +70,7 @@ namespace Memory StackGuard::~StackGuard() { fixme("Temporarily disabled stack guard deallocation"); - // KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size)); + // KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size + 1)); // debug("Freed stack at %p", this->StackBottom); } @@ -85,7 +85,7 @@ namespace Memory } else { - void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE)); + void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1)); debug("AllocatedStack: %p", AllocatedStack); memset(AllocatedStack, 0, USER_STACK_SIZE); for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index 7c20d3e..a758c71 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -131,8 +131,8 @@ namespace Memory PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr; if (!PML4->Present) { - PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr))); - memset(PDPTEPtr, 0, PAGE_SIZE); + PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr) + 1)); + memset(PDPTEPtr, 0, sizeof(PageDirectoryPointerTableEntryPtr)); PML4->Present = true; PML4->SetAddress((uintptr_t)PDPTEPtr >> 12); } @@ -153,8 +153,8 @@ namespace Memory PageDirectoryEntryPtr *PDEPtr = nullptr; if (!PDPTE->Present) { - PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr))); - memset(PDEPtr, 0, PAGE_SIZE); + PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr) + 1)); + memset(PDEPtr, 0, sizeof(PageDirectoryEntryPtr)); PDPTE->Present = true; PDPTE->SetAddress((uintptr_t)PDEPtr >> 12); } @@ -175,8 +175,8 @@ namespace Memory PageTableEntryPtr *PTEPtr = nullptr; if (!PDE->Present) { - PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr))); - memset(PTEPtr, 0, PAGE_SIZE); + PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr) + 1)); + memset(PTEPtr, 0, sizeof(PageTableEntryPtr)); PDE->Present = true; PDE->SetAddress((uintptr_t)PTEPtr >> 12); } @@ -217,7 +217,7 @@ namespace Memory (byte & 0x01 ? '1' : '0') if (!this->Check(VirtualAddress, (PTFlag)Flags, Type)) // quick workaround just to see where it fails - warn("Failed to map %#lx - %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags)); + warn("Failed to map v:%#lx p:%#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags)); #endif } diff --git a/Core/Power.cpp b/Core/Power.cpp index 1000834..c1cb86c 100644 --- a/Core/Power.cpp +++ b/Core/Power.cpp @@ -77,7 +77,7 @@ namespace Power Power::Power() { - this->acpi = new ACPI::ACPI(bInfo); + this->acpi = new ACPI::ACPI; this->madt = new ACPI::MADT(((ACPI::ACPI *)acpi)->MADT); trace("Power manager initialized"); } diff --git a/Core/Random.cpp b/Core/Random.cpp index b1aabcf..c59f0f2 100644 --- a/Core/Random.cpp +++ b/Core/Random.cpp @@ -41,7 +41,7 @@ namespace Random if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) RDRANDFlag = 0; -#if defined(a64) || defined(a32) +#if defined(a86) if (RDRANDFlag) { uint16_t RDRANDValue = 0; @@ -74,7 +74,7 @@ namespace Random if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) RDRANDFlag = 0; -#if defined(a64) || defined(a32) +#if defined(a86) if (RDRANDFlag) { uint32_t RDRANDValue = 0; @@ -107,7 +107,7 @@ namespace Random if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) RDRANDFlag = 0; -#if defined(a64) || defined(a32) +#if defined(a86) if (RDRANDFlag) { uint64_t RDRANDValue = 0; diff --git a/Core/StackGuard.cpp b/Core/StackGuard.cpp index 1ce5944..2a139f9 100644 --- a/Core/StackGuard.cpp +++ b/Core/StackGuard.cpp @@ -60,7 +60,7 @@ EXTERNC __weak __noreturn __no_stack_protector void __stack_chk_fail(void) debug("Current stack check guard value: %#lx", __stack_chk_guard); KPrint("\eFF0000Stack smashing detected!"); -#if defined(a64) || defined(a32) +#if defined(a86) void *Stack = nullptr; #if defined(a64) asmv("movq %%rsp, %0" @@ -87,7 +87,7 @@ EXTERNC __weak __noreturn __no_stack_protector void __chk_fail(void) error("Buffer overflow detected!"); KPrint("\eFF0000Buffer overflow detected!"); -#if defined(a64) || defined(a32) +#if defined(a86) while (1) asmv("cli; hlt"); #elif defined(aa64) diff --git a/Core/SystemManagementBIOS.cpp b/Core/SystemManagementBIOS.cpp index b15754d..a58caa4 100644 --- a/Core/SystemManagementBIOS.cpp +++ b/Core/SystemManagementBIOS.cpp @@ -21,22 +21,20 @@ #include "../kernel.h" -/* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf */ - namespace SMBIOS { bool CheckSMBIOS() { - if (bInfo->SMBIOSPtr != nullptr && bInfo->SMBIOSPtr < (void *)0xffffffffffff0000) + if (bInfo.SMBIOSPtr != nullptr && bInfo.SMBIOSPtr < (void *)0xFFFFFFFFFFFF0000) { - debug("SMBIOS is available (%#lx).", bInfo->SMBIOSPtr); + debug("SMBIOS is available (%#lx).", bInfo.SMBIOSPtr); return true; } - debug("SMBIOS is not available. (%#lx)", bInfo->SMBIOSPtr); + debug("SMBIOS is not available. (%#lx)", bInfo.SMBIOSPtr); return false; } - SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; } + SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; } static inline int SMBIOSTableLength(SMBIOSHeader *Hdr) { @@ -52,7 +50,7 @@ namespace SMBIOS if (!CheckSMBIOS()) return nullptr; - SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; + SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; debug("Getting SMBIOS header for type %d", Type); struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress; diff --git a/Core/Time.cpp b/Core/Time.cpp index f373087..acb66fe 100644 --- a/Core/Time.cpp +++ b/Core/Time.cpp @@ -24,7 +24,7 @@ namespace Time Clock ReadClock() { Clock tm; -#if defined(a64) || defined(a32) +#if defined(a86) uint32_t t = 0; outb(0x70, 0x00); t = inb(0x71); diff --git a/Core/Timer.cpp b/Core/Timer.cpp index 7da0439..0f40c1c 100644 --- a/Core/Timer.cpp +++ b/Core/Timer.cpp @@ -33,7 +33,7 @@ namespace Time { void time::Sleep(uint64_t Milliseconds) { -#if defined(a64) || defined(a32) +#if defined(a86) uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk; #ifdef DEBUG uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue); @@ -52,7 +52,7 @@ namespace Time uint64_t time::GetCounter() { -#if defined(a64) || defined(a32) +#if defined(a86) return mminq(&((HPET *)hpet)->MainCounterValue); #elif defined(aa64) #endif @@ -60,7 +60,7 @@ namespace Time uint64_t time::CalculateTarget(uint64_t Milliseconds) { -#if defined(a64) || defined(a32) +#if defined(a86) return mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk; #elif defined(aa64) #endif @@ -75,7 +75,7 @@ namespace Time ACPI::ACPI *acpi = (ACPI::ACPI *)this->acpi; if (acpi->HPET) { - Memory::Virtual().Map((void *)acpi->HPET->Address.Address, + Memory::Virtual().Remap((void *)acpi->HPET->Address.Address, (void *)acpi->HPET->Address.Address, Memory::PTFlag::RW | Memory::PTFlag::PCD); this->hpet = (void *)acpi->HPET->Address.Address; diff --git a/Core/UndefinedBehaviorSanitization.c b/Core/UndefinedBehaviorSanitization.c index ee23b7b..b5529f2 100644 --- a/Core/UndefinedBehaviorSanitization.c +++ b/Core/UndefinedBehaviorSanitization.c @@ -386,7 +386,8 @@ bool UBSANMsg(const char *file, uint32_t line, uint32_t column) { /* This can be ignored (unaligned memory access) */ if (strstr(file, "AdvancedConfigurationAndPowerInterface.cpp") && - (line == 34 && column == 47)) + ((line == 34 && column == 47) || + (line == 36 && column == 47))) return false; /* This can be ignored (unaligned memory access) */ @@ -401,6 +402,9 @@ bool UBSANMsg(const char *file, uint32_t line, uint32_t column) (line == 63 && column == 30)) return false; + if (strstr(file, "liballoc_1_1.c")) + return false; + /* This can be ignored (store address x with insufficient space for object of type 'y') */ if (strstr(file, "Task.cpp") && line > 500) return false; diff --git a/Core/UniversalAsynchronousReceiverTransmitter.cpp b/Core/UniversalAsynchronousReceiverTransmitter.cpp index 95645b1..737fd0b 100644 --- a/Core/UniversalAsynchronousReceiverTransmitter.cpp +++ b/Core/UniversalAsynchronousReceiverTransmitter.cpp @@ -23,7 +23,7 @@ volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; std::vector RegisteredEvents; -#if defined(a64) || defined(a32) +#if defined(a86) NIF __always_inline inline uint8_t NoProfiler_inportb(uint16_t Port) { uint8_t Result; @@ -56,7 +56,7 @@ namespace UniversalAsynchronousReceiverTransmitter SafeFunction NIF UART::UART(SerialPorts Port) { -#if defined(a64) || defined(a32) +#if defined(a86) if (Port == COMNULL) return; @@ -125,7 +125,7 @@ namespace UniversalAsynchronousReceiverTransmitter SafeFunction NIF void UART::Write(uint8_t Char) { -#if defined(a64) || defined(a32) +#if defined(a86) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & SERIAL_BUFFER_EMPTY) == 0) ; NoProfiler_outportb(Port, Char); @@ -137,7 +137,7 @@ namespace UniversalAsynchronousReceiverTransmitter SafeFunction NIF uint8_t UART::Read() { -#if defined(a64) || defined(a32) +#if defined(a86) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & 1) == 0) ; return NoProfiler_inportb(Port); @@ -146,7 +146,7 @@ namespace UniversalAsynchronousReceiverTransmitter { if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) { -#if defined(a64) || defined(a32) +#if defined(a86) e->OnReceived(NoProfiler_inportb(Port)); #endif } diff --git a/Core/Video/Display.cpp b/Core/Video/Display.cpp index 2675920..7ac1e05 100644 --- a/Core/Video/Display.cpp +++ b/Core/Video/Display.cpp @@ -50,7 +50,7 @@ namespace Video size_t Size = this->framebuffer.Pitch * Height; - this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); + this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size + 1)); memset(this->Buffers[Index].Buffer, 0, Size); this->Buffers[Index].Width = Width; @@ -102,7 +102,7 @@ namespace Video return; } - KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size)); + KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size + 1)); this->Buffers[Index].Buffer = nullptr; this->Buffers[Index].Checksum = 0; debug("Buffer %d deleted", Index); diff --git a/Core/Video/Font.cpp b/Core/Video/Font.cpp index 2e8efe0..20cd305 100644 --- a/Core/Video/Font.cpp +++ b/Core/Video/Font.cpp @@ -33,7 +33,7 @@ namespace Video { this->Info.PSF2Font = new PSF2_FONT; - PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1); + PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(TO_PAGES(FontDataLength + 1)); memcpy((void *)font2, Start, FontDataLength); Memory::Virtual().Map((void *)font2, (void *)font2, FontDataLength, Memory::PTFlag::RW); @@ -41,7 +41,7 @@ namespace Video if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3) { error("Font2 magic mismatch."); - KernelAllocator.FreePages((void *)font2, FontDataLength / PAGE_SIZE + 1); + KernelAllocator.FreePages((void *)font2, TO_PAGES(FontDataLength + 1)); return; } diff --git a/DAPI.hpp b/DAPI.hpp index 8a0a573..b218fc7 100644 --- a/DAPI.hpp +++ b/DAPI.hpp @@ -86,6 +86,7 @@ struct KernelAPI { unsigned long Offset; unsigned long DriverUID; + char KernelDebug; } Info; struct KAPIMemory diff --git a/Execute/Elf/BaseLoad.cpp b/Execute/Elf/BaseLoad.cpp index c6131e4..1d8771e 100644 --- a/Execute/Elf/BaseLoad.cpp +++ b/Execute/Elf/BaseLoad.cpp @@ -159,7 +159,7 @@ namespace Execute size_t ExFileSize = ExFile->node->Length; /* Allocate elf in memory */ - void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize)); + void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize + 1)); /* Copy the file to the allocated memory */ memcpy(ElfFile, (void *)ExFile->node->Address, ExFileSize); debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize); diff --git a/Execute/Elf/Parse.cpp b/Execute/Elf/Parse.cpp index 4de97ff..40a3397 100644 --- a/Execute/Elf/Parse.cpp +++ b/Execute/Elf/Parse.cpp @@ -172,7 +172,7 @@ namespace Execute if (ELFGetDynamicTag(ElfFile, DT_TEXTREL)) { fixme("Text relocation is not(?) tested yet!"); - MemoryImage = (uint8_t *)mem->RequestPages(TO_PAGES(Length), true); + MemoryImage = (uint8_t *)mem->RequestPages(TO_PAGES(Length + 1), true); memset(MemoryImage, 0, Length); return {MemoryImage, 0x0}; } @@ -196,14 +196,14 @@ namespace Execute if (ItrPhdr.p_type == PT_LOAD && ItrPhdr.p_vaddr == 0) { debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length)); - MemoryImage = mem->RequestPages(TO_PAGES(Length), true); + MemoryImage = mem->RequestPages(TO_PAGES(Length + 1), true); memset(MemoryImage, 0, Length); return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress}; } } debug("Allocating %ld pages for image", TO_PAGES(Length)); - MemoryImage = mem->RequestPages(TO_PAGES(Length)); + MemoryImage = mem->RequestPages(TO_PAGES(Length + 1)); memset(MemoryImage, 0, Length); if (FirstProgramHeaderVirtualAddress != 0) diff --git a/Execute/Elf/Rel.cpp b/Execute/Elf/Rel.cpp index 26ae9f2..8fdab7f 100644 --- a/Execute/Elf/Rel.cpp +++ b/Execute/Elf/Rel.cpp @@ -48,7 +48,7 @@ namespace Execute continue; if (Section->sh_flags & SHF_ALLOC) { - void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size)); + void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size + 1)); memset(Buffer, 0, Section->sh_size); Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US); diff --git a/Execute/Elf/SharedObjects.cpp b/Execute/Elf/SharedObjects.cpp index baee1aa..63ef35e 100644 --- a/Execute/Elf/SharedObjects.cpp +++ b/Execute/Elf/SharedObjects.cpp @@ -89,7 +89,7 @@ namespace Execute sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */ sl.RefCount = 0; - void *LibFile = mem->RequestPages(TO_PAGES(Length), true); + void *LibFile = mem->RequestPages(TO_PAGES(Length + 1), true); debug("LibFile: %#lx", LibFile); memcpy(LibFile, (void *)ElfImage, Length); Memory::Virtual().Map(LibFile, LibFile, Length, Memory::RW | Memory::US | Memory::G); diff --git a/Execute/Spawn.cpp b/Execute/Spawn.cpp index 165beb7..90a4070 100644 --- a/Execute/Spawn.cpp +++ b/Execute/Spawn.cpp @@ -58,7 +58,7 @@ namespace Execute cwk_path_get_basename(Path, &BaseName, nullptr); PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User); - void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length)); + void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length + 1)); memcpy(BaseImage, (void *)ExFile->node->Address, ExFile->node->Length); Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile->node->Length, Memory::PTFlag::RW | Memory::PTFlag::US); diff --git a/Fex.hpp b/Fex.hpp index a718024..cf0c58e 100644 --- a/Fex.hpp +++ b/Fex.hpp @@ -71,7 +71,8 @@ enum FexDriverType FexDriverType_Storage, FexDriverType_FileSystem, FexDriverType_Input, - FexDriverType_Audio + FexDriverType_Audio, + FexDriverType_ACPI, /* ... */ }; diff --git a/GUI/GraphicalUserInterface.cpp b/GUI/GraphicalUserInterface.cpp index 0605e80..fc09197 100644 --- a/GUI/GraphicalUserInterface.cpp +++ b/GUI/GraphicalUserInterface.cpp @@ -618,7 +618,7 @@ namespace GraphicalUserInterface this->BackBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->BackBuffer->Pitch = Display->GetPitch(); this->BackBuffer->Size = Display->GetBuffer(200)->Size; - this->BackBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->BackBuffer->Size)); + this->BackBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->BackBuffer->Size + 1)); memset(this->BackBuffer->Data, 0, this->BackBuffer->Size); this->DesktopBuffer = new ScreenBitmap; @@ -627,7 +627,7 @@ namespace GraphicalUserInterface this->DesktopBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->DesktopBuffer->Pitch = Display->GetPitch(); this->DesktopBuffer->Size = Display->GetBuffer(200)->Size; - this->DesktopBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->DesktopBuffer->Size)); + this->DesktopBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->DesktopBuffer->Size + 1)); memset(this->DesktopBuffer->Data, 0, this->DesktopBuffer->Size); this->OverlayBuffer = new ScreenBitmap; @@ -636,7 +636,7 @@ namespace GraphicalUserInterface this->OverlayBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->OverlayBuffer->Pitch = Display->GetPitch(); this->OverlayBuffer->Size = Display->GetBuffer(200)->Size; - this->OverlayBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->OverlayBuffer->Size)); + this->OverlayBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->OverlayBuffer->Size + 1)); memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size); this->CursorBuffer = new ScreenBitmap; @@ -645,7 +645,7 @@ namespace GraphicalUserInterface this->CursorBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->CursorBuffer->Pitch = Display->GetPitch(); this->CursorBuffer->Size = this->CursorBuffer->Width * this->CursorBuffer->Height * (this->CursorBuffer->BitsPerPixel / 8); - this->CursorBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->CursorBuffer->Size)); + this->CursorBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->CursorBuffer->Size + 1)); memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size); this->IsRunning = true; diff --git a/GUI/WidgetEvents.cpp b/GUI/WidgetEvents.cpp index 54d2b0a..bb849f6 100644 --- a/GUI/WidgetEvents.cpp +++ b/GUI/WidgetEvents.cpp @@ -73,7 +73,7 @@ namespace GraphicalUserInterface LastWidth = ((Window *)this->ParentWindow)->GetPosition().Width; LastHeight = ((Window *)this->ParentWindow)->GetPosition().Height; - this->mem->FreePages(this->Buffer->Data, TO_PAGES(this->Buffer->Size)); + this->mem->FreePages(this->Buffer->Data, TO_PAGES(this->Buffer->Size + 1)); this->Buffer->Data = nullptr; delete this->Buffer, this->Buffer = nullptr; @@ -83,7 +83,7 @@ namespace GraphicalUserInterface this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Size = this->Buffer->Pitch * LastHeight; - this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size)); + this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size + 1)); memset(this->Buffer->Data, 0, this->Buffer->Size); this->NeedRedraw = true; diff --git a/GUI/Widgets.cpp b/GUI/Widgets.cpp index acee212..03ea85d 100644 --- a/GUI/Widgets.cpp +++ b/GUI/Widgets.cpp @@ -34,7 +34,7 @@ namespace GraphicalUserInterface { Handle WidgetCollection::CreatePanel(Rect rect, uint32_t Color) { - PanelObject *panel = (PanelObject *)this->mem->RequestPages(TO_PAGES(sizeof(PanelObject))); + PanelObject *panel = (PanelObject *)this->mem->RequestPages(TO_PAGES(sizeof(PanelObject) + 1)); panel->Handle.Type[0] = 'P'; panel->Handle.Type[1] = 'N'; @@ -54,7 +54,7 @@ namespace GraphicalUserInterface Handle WidgetCollection::CreateLabel(Rect rect, const char *Text) { - LabelObject *label = (LabelObject *)this->mem->RequestPages(TO_PAGES(sizeof(LabelObject))); + LabelObject *label = (LabelObject *)this->mem->RequestPages(TO_PAGES(sizeof(LabelObject) + 1)); label->Handle.Type[0] = 'L'; label->Handle.Type[1] = 'B'; @@ -74,7 +74,7 @@ namespace GraphicalUserInterface Handle WidgetCollection::CreateButton(Rect rect, const char *Text, uintptr_t OnClick) { - ButtonObject *button = (ButtonObject *)this->mem->RequestPages(TO_PAGES(sizeof(ButtonObject))); + ButtonObject *button = (ButtonObject *)this->mem->RequestPages(TO_PAGES(sizeof(ButtonObject) + 1)); button->Handle.Type[0] = 'B'; button->Handle.Type[1] = 'T'; @@ -126,7 +126,7 @@ namespace GraphicalUserInterface this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Size = this->Buffer->Pitch * ((Window *)this->ParentWindow)->GetPosition().Height; - this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size)); + this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size + 1)); memset(this->Buffer->Data, 0, this->Buffer->Size); this->CurrentFont = new Video::Font(&_binary_Files_tamsyn_font_1_11_Tamsyn10x20r_psf_start, &_binary_Files_tamsyn_font_1_11_Tamsyn10x20r_psf_end, Video::FontType::PCScreenFont2); diff --git a/GUI/Window.cpp b/GUI/Window.cpp index 2347e18..226007b 100644 --- a/GUI/Window.cpp +++ b/GUI/Window.cpp @@ -66,7 +66,7 @@ namespace GraphicalUserInterface this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Size = this->Buffer->Pitch * rect.Height; - this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size)); + this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size + 1)); memset(this->Buffer->Data, 0, this->Buffer->Size); this->ParentGUI = ParentGUI; this->Position = rect; diff --git a/GUI/WindowEvents.cpp b/GUI/WindowEvents.cpp index 7393ea9..08507d0 100644 --- a/GUI/WindowEvents.cpp +++ b/GUI/WindowEvents.cpp @@ -31,7 +31,7 @@ namespace GraphicalUserInterface void Window::OnResize(Event *e) { // TODO: Optimize this - this->mem->FreePages(this->Buffer->Data, TO_PAGES(this->Buffer->Size)); + this->mem->FreePages(this->Buffer->Data, TO_PAGES(this->Buffer->Size + 1)); this->Buffer->Data = nullptr; delete this->Buffer, this->Buffer = nullptr; @@ -41,7 +41,7 @@ namespace GraphicalUserInterface this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Size = this->Buffer->Pitch * e->Resize.Height; - this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size)); + this->Buffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->Buffer->Size + 1)); memset(this->Buffer->Data, 0, this->Buffer->Size); this->OnPaint(e); } diff --git a/KThread.cpp b/KThread.cpp index 02faf0f..be82894 100644 --- a/KThread.cpp +++ b/KThread.cpp @@ -103,7 +103,7 @@ void TaskMgr() { for (short j = 0; j < 200; j++) { - uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo->Framebuffer[0].BitsPerPixel / 8)); + uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); *Pixel = 0x222222; } } diff --git a/Kernel.cpp b/Kernel.cpp index afb4e2c..a747318 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -1,18 +1,18 @@ /* - This file is part of Fennix Kernel. + This file is part of Fennix Kernel. - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . */ #include "kernel.h" @@ -70,6 +70,8 @@ LockClass mExtTrkLock; * - [ ] Fix memcpy, memset and memcmp functions (they are not working properly with SIMD). * - [ ] Support Aarch64. * - [ ] Fully support i386. + * - [ ] SMP trampoline shouldn't be hardcoded at 0x2000. + * - [ ] Rework the stack guard. * * ISSUES: * - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) @@ -146,6 +148,13 @@ LockClass mExtTrkLock; * - CPUID lists: * https://www.amd.com/system/files/TechDocs/40332.pdf * + * - SMBIOS: + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf + * + * - UMIP, SMAP and SMEP: + * https://en.wikipedia.org/wiki/Control_register + * https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf + * https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention */ #ifdef a64 @@ -176,7 +185,7 @@ using VirtualFileSystem::FileStatus; using VirtualFileSystem::Node; using VirtualFileSystem::NodeFlags; -BootInfo *bInfo = nullptr; +__aligned(16) BootInfo bInfo{}; Video::Display *Display = nullptr; SymbolResolver::Symbols *KernelSymbolTable = nullptr; Power::Power *PowerManager = nullptr; @@ -233,11 +242,11 @@ EXTERNC void KPrint(const char *Format, ...) EXTERNC NIF void Main(BootInfo *Info) { BootClock = Time::ReadClock(); - bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); - memcpy(bInfo, Info, sizeof(BootInfo)); + // bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo) + 1)); + memcpy(&bInfo, Info, sizeof(BootInfo)); debug("BootInfo structure is at %p", bInfo); - Display = new Video::Display(bInfo->Framebuffer[0]); + Display = new Video::Display(bInfo.Framebuffer[0]); printf("\eFFFFFF%s - %s [\e058C19%s\eFFFFFF]\n", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); /**************************************************************************************/ KPrint("Time: \e8888FF%02d:%02d:%02d %02d/%02d/%02d UTC", @@ -249,7 +258,7 @@ EXTERNC NIF void Main(BootInfo *Info) Interrupts::Initialize(0); KPrint("Reading Kernel Parameters"); - ParseConfig((char *)bInfo->Kernel.CommandLine, &Config); + ParseConfig((char *)bInfo.Kernel.CommandLine, &Config); if (Config.BootAnimation) { @@ -268,8 +277,8 @@ EXTERNC NIF void Main(BootInfo *Info) KPrint("Initializing CPU Features"); CPU::InitializeFeatures(0); - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) - KPrint("\eFFA500TCG Virtual Machine detected."); + if (DebuggerIsAttached) + KPrint("\eFFA500Kernel debugger detected."); KPrint("Loading Kernel Symbols"); KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase); @@ -385,22 +394,22 @@ EXTERNC NIF void Main(BootInfo *Info) for (size_t i = 0; i < MAX_MODULES; i++) { - if (!bInfo->Modules[i].Address) + if (!bInfo.Modules[i].Address) continue; - if (strcmp(bInfo->Modules[i].CommandLine, "initrd") == 0) + if (strcmp(bInfo.Modules[i].CommandLine, "initrd") == 0) { - debug("Found initrd at %p", bInfo->Modules[i].Address); + debug("Found initrd at %p", bInfo.Modules[i].Address); static char initrd = 0; if (!initrd++) - new VirtualFileSystem::USTAR((uintptr_t)bInfo->Modules[i].Address, vfs); + new VirtualFileSystem::USTAR((uintptr_t)bInfo.Modules[i].Address, vfs); } - if (strcmp(bInfo->Modules[i].CommandLine, "bootanim") == 0 && Config.BootAnimation) + if (strcmp(bInfo.Modules[i].CommandLine, "bootanim") == 0 && Config.BootAnimation) { - debug("Found bootanim at %p", bInfo->Modules[i].Address); + debug("Found bootanim at %p", bInfo.Modules[i].Address); static char bootanim = 0; if (!bootanim++) - new VirtualFileSystem::USTAR((uintptr_t)bInfo->Modules[i].Address, bootanim_vfs); + new VirtualFileSystem::USTAR((uintptr_t)bInfo.Modules[i].Address, bootanim_vfs); } } @@ -462,15 +471,18 @@ EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info) { trace("Hello, World!"); + if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) + { + debug("\n\n----------------------------------------\nDEBUGGER DETECTED\n----------------------------------------\n\n"); + DebuggerIsAttached = true; + } + // https://wiki.osdev.org/Calling_Global_Constructors for (CallPtr *func = __init_array_start; func != __init_array_end; func++) (*func)(); InitializeMemoryManagement(Info); - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) - DebuggerIsAttached = true; - #ifdef DEBUG /* I had to do this because KernelAllocator * is a global constructor but we need diff --git a/LICENSE b/LICENSE index b2e6cbe..314c596 100644 --- a/LICENSE +++ b/LICENSE @@ -631,7 +631,9 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - A kernel that serves as the core of an operating system, managing hardware resources and providing essential services to user-level applications. + A kernel that serves as the core of an operating system, managing + hardware resources and providing essential services to user-level + applications. Copyright (C) 2023 EnderIce2 This program is free software: you can redistribute it and/or modify diff --git a/Library/Convert.cpp b/Library/Convert.cpp index a1d2bc3..9e9ed74 100644 --- a/Library/Convert.cpp +++ b/Library/Convert.cpp @@ -749,7 +749,7 @@ EXTERNC void __chk_fail(void) __noreturn; __noreturn __always_inline static inline void __convert_chk_fail(void) { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("int3"); #else #warning "Not implemented!" diff --git a/Makefile b/Makefile index ecf756d..af6e4f2 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ ifeq ($(OSARCH), amd64) CFLAGS += -fno-pic -fno-pie \ -mno-red-zone -march=core2 -pipe \ - -mcmodel=kernel -fno-builtin -Da64 + -mcmodel=kernel -fno-builtin -Da64 -Da86 CFLAG_STACK_PROTECTOR := -fstack-protector-all LDFLAGS += -TArchitecture/amd64/linker.ld \ -fno-pic -fno-pie \ @@ -81,7 +81,7 @@ else ifeq ($(OSARCH), i386) CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \ -mno-red-zone -march=pentium -pipe -msoft-float \ - -fno-builtin -Da32 + -fno-builtin -Da32 -Da86 CFLAG_STACK_PROTECTOR := -fstack-protector-all LDFLAGS += -TArchitecture/i386/linker.ld \ -fno-pic -fno-pie \ diff --git a/Network/NetworkController.cpp b/Network/NetworkController.cpp index 73aac21..67c1219 100644 --- a/Network/NetworkController.cpp +++ b/Network/NetworkController.cpp @@ -68,12 +68,12 @@ namespace NetworkInterfaceManager void NetworkInterface::FetchNetworkCards(unsigned long DriverUID) { - KernelCallback *cb = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + KernelCallback *cb = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback) + 1)); memset(cb, 0, sizeof(KernelCallback)); cb->Reason = FetchReason; DriverManager->IOCB(DriverUID, (void *)cb); - DeviceInterface *Iface = (DeviceInterface *)mem->RequestPages(TO_PAGES(sizeof(DeviceInterface))); + DeviceInterface *Iface = (DeviceInterface *)mem->RequestPages(TO_PAGES(sizeof(DeviceInterface) + 1)); strcpy(Iface->Name, cb->NetworkCallback.Fetch.Name); Iface->ID = this->CardIDs++; Iface->MAC.FromHex(cb->NetworkCallback.Fetch.MAC); @@ -198,7 +198,7 @@ namespace NetworkInterfaceManager void NetworkInterface::Send(DeviceInterface *Interface, uint8_t *Data, uint64_t Length) { - void *DataToBeSent = mem->RequestPages(TO_PAGES(Length)); + void *DataToBeSent = mem->RequestPages(TO_PAGES(Length + 1)); memcpy(DataToBeSent, Data, Length); KernelCallback *cb = (KernelCallback *)Interface->DriverCallBackAddress; @@ -209,7 +209,7 @@ namespace NetworkInterfaceManager cb->NetworkCallback.Send.Length = Length; DriverManager->IOCB(Interface->DriverID, (void *)cb); - mem->FreePages(DataToBeSent, TO_PAGES(Length)); + mem->FreePages(DataToBeSent, TO_PAGES(Length + 1)); foreach (auto var in RegisteredEvents) var->OnInterfaceSent(Interface, Data, Length); } diff --git a/Profiling/cyg.cpp b/Profiling/cyg.cpp index 5c50318..ba5c3b3 100644 --- a/Profiling/cyg.cpp +++ b/Profiling/cyg.cpp @@ -43,7 +43,7 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_enter(void *Function, void *Cal return; while (Wait) -#if defined(a64) || defined(a32) +#if defined(a86) asmv("pause"); #elif defined(aa64) asmv("yield"); @@ -80,7 +80,7 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_exit(void *Function, void *Call return; while (Wait) -#if defined(a64) || defined(a32) +#if defined(a86) asmv("pause"); #elif defined(aa64) asmv("yield"); diff --git a/Recovery/RecoveryMain.cpp b/Recovery/RecoveryMain.cpp index fc05534..1be973c 100644 --- a/Recovery/RecoveryMain.cpp +++ b/Recovery/RecoveryMain.cpp @@ -78,7 +78,7 @@ namespace Recovery return; } - void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm->node->Length)); + void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm->node->Length + 1)); memcpy(PCMRaw, (void *)pcm->node->Address, pcm->node->Length); KernelCallback callback; @@ -89,7 +89,7 @@ namespace Recovery debug("Playing audio..."); int status = DriverManager->IOCB(AudioDrv.DriverUID, (void *)&callback); debug("Audio played! %d", status); - KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm->node->Length)); + KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm->node->Length + 1)); vfs->Close(pcm); TEXIT(0); } diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index 5e4473d..3acf52e 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -88,7 +88,7 @@ static uintptr_t sys_request_pages(SyscallsFrame *Frame, size_t Count) if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) return SYSCALL_ACCESS_DENIED; UNUSED(Frame); - return (uintptr_t)TaskManager->GetCurrentThread()->Memory->RequestPages(Count, true); + return (uintptr_t)TaskManager->GetCurrentThread()->Memory->RequestPages(Count + 1, true); } static int sys_free_pages(SyscallsFrame *Frame, uintptr_t Address, size_t Count) @@ -96,7 +96,7 @@ static int sys_free_pages(SyscallsFrame *Frame, uintptr_t Address, size_t Count) /* Allow everyone to free pages */ if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) return SYSCALL_ACCESS_DENIED; - TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count); + TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count + 1); UNUSED(Frame); return SYSCALL_OK; } diff --git a/Tasking/InterProcessCommunication.cpp b/Tasking/InterProcessCommunication.cpp index 1a29e2a..b68954c 100644 --- a/Tasking/InterProcessCommunication.cpp +++ b/Tasking/InterProcessCommunication.cpp @@ -27,7 +27,7 @@ namespace InterProcessCommunication IPCHandle *IPC::Create(IPCType Type, char UniqueToken[16]) { SmartLock(this->IPCLock); - IPCHandle *Hnd = (IPCHandle *)mem->RequestPages(TO_PAGES(sizeof(IPCHandle))); + IPCHandle *Hnd = (IPCHandle *)mem->RequestPages(TO_PAGES(sizeof(IPCHandle) + 1)); Hnd->ID = NextID++; Hnd->Node = vfs->Create(UniqueToken, VirtualFileSystem::NodeFlags::FILE, IPCNode); @@ -48,7 +48,7 @@ namespace InterProcessCommunication if (Handles[i]->ID == ID) { vfs->Delete(Handles[i]->Node); - mem->FreePages(Handles[i], TO_PAGES(sizeof(IPCHandle))); + mem->FreePages(Handles[i], TO_PAGES(sizeof(IPCHandle) + 1)); Handles.remove(i); debug("Destroyed IPC with ID %d", ID); return IPCSuccess; @@ -71,7 +71,7 @@ namespace InterProcessCommunication if (Hnd->Buffer != nullptr || Hnd->Length != 0) return IPCAlreadyAllocated; - Hnd->Buffer = (uint8_t *)mem->RequestPages(TO_PAGES(Size)); + Hnd->Buffer = (uint8_t *)mem->RequestPages(TO_PAGES(Size + 1)); Hnd->Length = Size; return IPCSuccess; } @@ -89,7 +89,7 @@ namespace InterProcessCommunication if (Hnd->Buffer == nullptr || Hnd->Length == 0) return IPCNotAllocated; - mem->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length)); + mem->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length + 1)); Hnd->Buffer = nullptr; Hnd->Length = 0; return IPCSuccess; diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index f269c9a..c3ee5a9 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -58,7 +58,7 @@ namespace Tasking // ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); } -#if defined(a64) || defined(a32) +#if defined(a86) __naked __used __no_stack_protector NIF void IdleProcessLoop() { asmv("IdleLoop:\n" @@ -140,7 +140,7 @@ namespace Tasking delete ListProcess[i]->ELFSymbolTable, ListProcess[i]->ELFSymbolTable = nullptr; SecurityManager.DestroyToken(ListProcess[i]->Security.UniqueToken); if (ListProcess[i]->Security.TrustLevel == TaskTrustLevel::User) - KernelAllocator.FreePages((void *)ListProcess[i]->PageTable, TO_PAGES(PAGE_SIZE)); + KernelAllocator.FreePages((void *)ListProcess[i]->PageTable, TO_PAGES(sizeof(Memory::PageTable4) + 1)); // Remove the process from parent's children list if (ListProcess[i]->Parent) @@ -293,7 +293,7 @@ namespace Tasking // TaskingScheduler_OneShot(1); // IRQ16 TaskingLock.Unlock(); -#if defined(a64) || defined(a32) +#if defined(a86) asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */ #elif defined(aa64) asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */ @@ -330,7 +330,7 @@ namespace Tasking { SecurityManager.DestroyToken(Process->Security.UniqueToken); if (Process->Security.TrustLevel == TaskTrustLevel::User) - KernelAllocator.FreePages((void *)Process->PageTable, TO_PAGES(PAGE_SIZE)); + KernelAllocator.FreePages((void *)Process->PageTable, TO_PAGES(sizeof(Memory::PageTable4) + 1)); if (Process->Parent) for (size_t j = 0; j < Process->Parent->Children.size(); j++) @@ -408,7 +408,7 @@ namespace Tasking Thread->ExitCode = 0xdead; Thread->Status = TaskStatus::Ready; Thread->Memory = new Memory::MemMgr(Parent->PageTable, Parent->memDirectory); - Thread->FPU = (CPU::x64::FXState *)Thread->Memory->RequestPages(TO_PAGES(sizeof(CPU::x64::FXState))); + Thread->FPU = (CPU::x64::FXState *)Thread->Memory->RequestPages(TO_PAGES(sizeof(CPU::x64::FXState) + 1)); memset(Thread->FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState)))); Thread->Security.TrustLevel = Parent->Security.TrustLevel; @@ -721,9 +721,8 @@ namespace Tasking #if defined(a64) if (!DoNotCreatePageTable) { - Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); - memcpy(Process->PageTable, (void *)UserspaceKernelOnlyPageTable, PAGE_SIZE); - Memory::Virtual(Process->PageTable).Map((void *)Process->PageTable, (void *)Process->PageTable, Memory::PTFlag::RW); // Make sure the page table is mapped. + Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(sizeof(Memory::PageTable4) + 1)); + memcpy(Process->PageTable, (void *)KernelPageTable, PAGE_SIZE); } #elif defined(a32) #elif defined(aa64) diff --git a/Tests/CPUID.cpp b/Tests/CPUID.cpp new file mode 100644 index 0000000..c6c409b --- /dev/null +++ b/Tests/CPUID.cpp @@ -0,0 +1,155 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#ifdef DEBUG + +#include +#include +#include + +extern bool DebuggerIsAttached; + +__constructor void TestCPUIDStructs() +{ + if (!DebuggerIsAttached) + return; + + if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) + { + CPU::x86::AMD::CPUID0x00000000 cpuid0; + CPU::x86::AMD::CPUID0x00000001 cpuid1; + CPU::x86::AMD::CPUID0x00000005 cpuid5; + CPU::x86::AMD::CPUID0x00000006 cpuid6; + CPU::x86::AMD::CPUID0x00000007 cpuid7; + CPU::x86::AMD::CPUID0x0000000B_ECX_0 cpuidB_C_0; + CPU::x86::AMD::CPUID0x0000000B_ECX_1 cpuidB_C_1; + CPU::x86::AMD::CPUID0x0000000D_ECX_0 cpuidD_C_0; + CPU::x86::AMD::CPUID0x0000000D_ECX_1 cpuidD_C_1; + CPU::x86::AMD::CPUID0x0000000D_ECX_2 cpuidD_C_2; + CPU::x86::AMD::CPUID0x0000000D_ECX_11 cpuidD_C_11; + CPU::x86::AMD::CPUID0x0000000D_ECX_12 cpuidD_C_12; + CPU::x86::AMD::CPUID0x0000000D_ECX_3E cpuidD_C_3E; + CPU::x86::AMD::CPUID0x80000000 cpuid80000000; + CPU::x86::AMD::CPUID0x80000001 cpuid80000001; + CPU::x86::AMD::CPUID0x80000002 cpuid80000002; + CPU::x86::AMD::CPUID0x80000003 cpuid80000003; + CPU::x86::AMD::CPUID0x80000004 cpuid80000004; + CPU::x86::AMD::CPUID0x80000005 cpuid80000005; + CPU::x86::AMD::CPUID0x80000006 cpuid80000006; + CPU::x86::AMD::CPUID0x80000007 cpuid80000007; + CPU::x86::AMD::CPUID0x80000008 cpuid80000008; + CPU::x86::AMD::CPUID0x8000000A cpuid8000000A; + CPU::x86::AMD::CPUID0x80000019 cpuid80000019; + CPU::x86::AMD::CPUID0x8000001A cpuid8000001A; + CPU::x86::AMD::CPUID0x8000001B cpuid8000001B; + CPU::x86::AMD::CPUID0x8000001C cpuid8000001C; + CPU::x86::AMD::CPUID0x8000001D cpuid8000001D; + CPU::x86::AMD::CPUID0x8000001E cpuid8000001E; + CPU::x86::AMD::CPUID0x8000001F cpuid8000001F; + CPU::x86::AMD::CPUID0x80000020 cpuid80000020; + CPU::x86::AMD::CPUID0x80000021 cpuid80000021; + CPU::x86::AMD::CPUID0x80000022 cpuid80000022; + CPU::x86::AMD::CPUID0x80000023 cpuid80000023; + CPU::x86::AMD::CPUID0x80000026 cpuid80000026; + + cpuid0.Get(); + cpuid1.Get(); + cpuid5.Get(); + cpuid6.Get(); + cpuid7.Get(); + cpuidB_C_0.Get(); + cpuidB_C_1.Get(); + cpuidD_C_0.Get(); + cpuidD_C_1.Get(); + cpuidD_C_2.Get(); + cpuidD_C_11.Get(); + cpuidD_C_12.Get(); + cpuidD_C_3E.Get(); + cpuid80000000.Get(); + cpuid80000001.Get(); + cpuid80000002.Get(); + cpuid80000003.Get(); + cpuid80000004.Get(); + cpuid80000005.Get(); + cpuid80000006.Get(); + cpuid80000007.Get(); + cpuid80000008.Get(); + cpuid8000000A.Get(); + cpuid80000019.Get(); + cpuid8000001A.Get(); + cpuid8000001B.Get(); + cpuid8000001C.Get(); + cpuid8000001D.Get(); + cpuid8000001E.Get(); + cpuid8000001F.Get(); + cpuid80000020.Get(); + cpuid80000021.Get(); + cpuid80000022.Get(); + cpuid80000023.Get(); + cpuid80000026.Get(); + + // asmv("int3"); + } + else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) + { + CPU::x86::Intel::CPUID0x00000000 cpuid0; + CPU::x86::Intel::CPUID0x00000001 cpuid1; + CPU::x86::Intel::CPUID0x00000002 cpuid2; + CPU::x86::Intel::CPUID0x00000003 cpuid3; + CPU::x86::Intel::CPUID0x00000004_1 cpuid4_1; + CPU::x86::Intel::CPUID0x00000005 cpuid5; + CPU::x86::Intel::CPUID0x00000006 cpuid6; + CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0; + CPU::x86::Intel::CPUID0x00000007_1 cpuid7_1; + CPU::x86::Intel::CPUID0x0000000A cpuidA; + CPU::x86::Intel::CPUID0x00000015 cpuid15; + CPU::x86::Intel::CPUID0x00000016 cpuid16; + CPU::x86::Intel::CPUID0x80000000 cpuid80000000; + CPU::x86::Intel::CPUID0x80000001 cpuid80000001; + CPU::x86::Intel::CPUID0x80000002 cpuid80000002; + CPU::x86::Intel::CPUID0x80000003 cpuid80000003; + CPU::x86::Intel::CPUID0x80000004 cpuid80000004; + CPU::x86::Intel::CPUID0x80000006 cpuid80000006; + CPU::x86::Intel::CPUID0x80000008 cpuid80000008; + CPU::x86::Intel::CPUID0x8000000A cpuid8000000A; + + cpuid0.Get(); + cpuid1.Get(); + cpuid2.Get(); + cpuid3.Get(); + cpuid4_1.Get(); + cpuid5.Get(); + cpuid6.Get(); + cpuid7_0.Get(); + cpuid7_1.Get(); + cpuidA.Get(); + cpuid15.Get(); + cpuid16.Get(); + cpuid80000000.Get(); + cpuid80000001.Get(); + cpuid80000002.Get(); + cpuid80000003.Get(); + cpuid80000004.Get(); + cpuid80000006.Get(); + cpuid80000008.Get(); + cpuid8000000A.Get(); + + // asmv("int3"); + } +} + +#endif // DEBUG diff --git a/Tests/Marco.cpp b/Tests/Marco.cpp index 0bb5f7e..6e224b2 100644 --- a/Tests/Marco.cpp +++ b/Tests/Marco.cpp @@ -15,6 +15,8 @@ along with Fennix Kernel. If not, see . */ +#ifdef DEBUG + #include #include #include @@ -23,54 +25,71 @@ __constructor void TestMacros() { { int a = TO_PAGES(4096); - int b = FROM_PAGES(2); + int b = FROM_PAGES(1); debug("a: 4096 -> %d", a); debug("b: a -> %d", b); + if (a != 1) + { + error("t1: TO_PAGES is not equal to 1"); + inf_loop; + } + + if (b != 4096) + { + error("t1: FROM_PAGES is not equal to 4096"); + inf_loop; + } + } + + { + int a = TO_PAGES(4097); + int b = FROM_PAGES(2); + + debug("a: 4097 -> %d", a); + debug("b: a -> %d", b); + if (a != 2) { - error("TO_PAGES is not equal to 2"); - while (1) - ; + error("t2: TO_PAGES is not equal to 2"); + inf_loop; } if (b != 8192) { - error("FROM_PAGES is not equal to 8192"); - while (1) - ; + error("t2: FROM_PAGES is not equal to 8192"); + inf_loop; } } debug("-------------------------"); { - uint64_t actual = PAGE_SIZE; - uint64_t expected = 1; + uint64_t bytes = PAGE_SIZE; + uint64_t pgs = 1; for (int i = 0; i < 128; i++) { - uint64_t a = TO_PAGES(actual); - uint64_t b = FROM_PAGES(expected); + uint64_t cnv_to_pgs = TO_PAGES(bytes); + uint64_t cnv_from_pgs = FROM_PAGES(pgs); - /* TODO: This is a workaround for now. */ - if (a != expected + 1) + if (cnv_to_pgs != pgs) { - error("TO_PAGES is not equal to %d (actual: %d)", expected, a); - while (1) - ; + error("TO_PAGES is not equal to %d (pages: %d)", pgs, cnv_to_pgs); + inf_loop; } - if (b != actual) + if (cnv_from_pgs != bytes) { - error("FROM_PAGES is not equal to %d (actual: %d)", actual, b); - while (1) - ; + error("FROM_PAGES is not equal to %d (bytes: %d)", bytes, cnv_from_pgs); + inf_loop; } - actual += PAGE_SIZE; - expected++; + bytes += PAGE_SIZE; + pgs++; } } -} \ No newline at end of file +} + +#endif // DEBUG diff --git a/Tests/MemoryOperations.cpp b/Tests/MemoryOperations.cpp index eddc980..a38b716 100644 --- a/Tests/MemoryOperations.cpp +++ b/Tests/MemoryOperations.cpp @@ -38,32 +38,29 @@ __constructor void TestMemoryOperations() char str2[] = "World"; memcpy_unsafe(arr2, arr1, sizeof(arr1)); - debug("memcpy: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d\n", + debug("memcpy: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d", arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]); if (memcmp(arr1, arr2, sizeof(arr1)) != 0) { - error("memcpy failed!\n"); - while (1) - ; + error("memcpy failed!"); + inf_loop; } memset_unsafe(arr2, 0, sizeof(arr2)); - debug("memset: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d\n", + debug("memset: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d", arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]); if (memcmp(arr1, arr2, sizeof(arr1)) == 0) { - error("memset failed!\n"); - while (1) - ; + error("memset failed!"); + inf_loop; } memmove_unsafe(str1 + 3, str1, strlen(str1) + 1); - debug("memmove: str1=%s\n", str1); + debug("memmove: str1=%s", str1); if (strcmp(str1, "HelHello") != 0) { - error("memmove failed!\n"); - while (1) - ; + error("memmove failed!"); + inf_loop; } char carr[1024]; @@ -82,7 +79,7 @@ __constructor void TestMemoryOperations() { if (carr[i] != 'a') { - error("memcpy failed!\n"); + error("memcpy failed!"); while (1) ; } @@ -97,7 +94,7 @@ __constructor void TestMemoryOperations() { if (carr[i] != 'b') { - error("memcpy failed!\n"); + error("memcpy failed!"); while (1) ; } @@ -113,7 +110,7 @@ __constructor void TestMemoryOperations() { if (carr[i] != 'c') { - error("memcpy failed!\n"); + error("memcpy failed!"); while (1) ; } @@ -128,7 +125,7 @@ __constructor void TestMemoryOperations() { if (carr[i] != 'd') { - error("memset failed!\n"); + error("memset failed!"); while (1) ; } diff --git a/Tests/RandomNumberGenerator.cpp b/Tests/RandomNumberGenerator.cpp index 10eb40f..bfab23b 100644 --- a/Tests/RandomNumberGenerator.cpp +++ b/Tests/RandomNumberGenerator.cpp @@ -40,7 +40,7 @@ __constructor void TestRandom() if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) RDRANDFlag = 0; -#if defined(a64) || defined(a32) +#if defined(a86) if (RDRANDFlag) { uint64_t RDSEEDValue = 0; diff --git a/Tests/String.cpp b/Tests/String.cpp index f62d22b..6f646e9 100644 --- a/Tests/String.cpp +++ b/Tests/String.cpp @@ -31,8 +31,7 @@ void TestString() else { error("String comparison doesn't work! \"%s\"", hw.c_str()); - while (1) - ; + inf_loop; } std::string hi("Hi"); @@ -45,8 +44,7 @@ void TestString() else { error("String indexing doesn't work! \"%s\" \"%s\"", chi, hi.c_str()); - while (1) - ; + inf_loop; } hi << " there!"; @@ -55,8 +53,7 @@ void TestString() else { error("String concatenation doesn't work! \"%s\"", hi.c_str()); - while (1) - ; + inf_loop; } hi << " " << hw; @@ -65,8 +62,7 @@ void TestString() else { error("String concatenation doesn't work! \"%s\"", hi.c_str()); - while (1) - ; + inf_loop; } std::string eq0("Hello, world!"); @@ -78,8 +74,7 @@ void TestString() else { error("String equality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq1.c_str()); - while (1) - ; + inf_loop; } if (eq0 != eq2) @@ -87,8 +82,7 @@ void TestString() else { error("String inequality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq2.c_str()); - while (1) - ; + inf_loop; } char chw[14]; @@ -105,8 +99,7 @@ void TestString() else { error("String iteration doesn't work! \"%s\" \"%s\" %d", chw, hw.c_str(), i); - while (1) - ; + inf_loop; } std::string a("Hello"); @@ -119,8 +112,7 @@ void TestString() else { error("String addition doesn't work! \"%s\"", c.c_str()); - while (1) - ; + inf_loop; } } diff --git a/include/boot/binfo.h b/include/boot/binfo.h index 8464548..9b32263 100644 --- a/include/boot/binfo.h +++ b/include/boot/binfo.h @@ -54,7 +54,6 @@ struct BootInfo __UINT32_TYPE__ Height; __UINT64_TYPE__ Pitch; __UINT16_TYPE__ BitsPerPixel; - __UINT8_TYPE__ MemoryModel; __UINT8_TYPE__ RedMaskSize; __UINT8_TYPE__ RedMaskShift; __UINT8_TYPE__ GreenMaskSize; diff --git a/include/cpu.hpp b/include/cpu.hpp index cc011eb..1cdcaf5 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -143,7 +143,7 @@ namespace CPU { do { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("pause"); #elif defined(aa64) asmv("yield"); @@ -154,7 +154,7 @@ namespace CPU /** * @brief Stop the CPU (infinite loop) */ -#if defined(a64) || defined(a32) +#if defined(a86) SafeFunction __noreturn __naked __used inline void Stop() { asmv("CPUStopLoop:\n" @@ -178,7 +178,7 @@ namespace CPU { do { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("hlt"); #elif defined(aa64) asmv("wfe"); diff --git a/include/cpu/membar.hpp b/include/cpu/membar.hpp index 1ab128f..cf95860 100644 --- a/include/cpu/membar.hpp +++ b/include/cpu/membar.hpp @@ -26,7 +26,7 @@ namespace CPU { SafeFunction static inline void Barrier() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("" :: : "memory"); #elif defined(aa64) @@ -37,7 +37,7 @@ namespace CPU SafeFunction static inline void Fence() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("mfence" :: : "memory"); #elif defined(aa64) @@ -48,7 +48,7 @@ namespace CPU SafeFunction static inline void StoreFence() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("sfence" :: : "memory"); #elif defined(aa64) @@ -59,7 +59,7 @@ namespace CPU SafeFunction static inline void LoadFence() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("lfence" :: : "memory"); #elif defined(aa64) diff --git a/include/cpu/x86/cpuid_amd.hpp b/include/cpu/x86/cpuid_amd.hpp index 691abb2..164573a 100644 --- a/include/cpu/x86/cpuid_amd.hpp +++ b/include/cpu/x86/cpuid_amd.hpp @@ -38,12 +38,12 @@ namespace CPU /** @brief Basic CPU information */ struct CPUID0x00000000 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x0)); #endif // a64 || a32 } @@ -91,9 +91,9 @@ namespace CPU /** @brief Additional CPU information */ struct CPUID0x00000001 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "a"(0x1)); @@ -207,12 +207,12 @@ namespace CPU /** @brief Monitor and MWait Features */ struct CPUID0x00000005 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x5)); #endif // a64 || a32 } @@ -264,12 +264,12 @@ namespace CPU /** @brief Power Management Related Features */ struct CPUID0x00000006 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x6)); #endif // a64 || a32 } @@ -320,12 +320,12 @@ namespace CPU /** @brief Structured Extended Feature Identifiers */ struct CPUID0x00000007 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x7)); #endif // a64 || a32 } @@ -408,12 +408,12 @@ namespace CPU /** @brief Thread Level - Extended Topology Enumeration */ struct CPUID0x0000000B_ECX_0 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xB), "c"(0x0)); #endif // a64 || a32 } @@ -465,12 +465,12 @@ namespace CPU /** @brief Core Level - Extended Topology Enumeration */ struct CPUID0x0000000B_ECX_1 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xB), "c"(0x1)); #endif // a64 || a32 } @@ -522,12 +522,12 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_0 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xD), "c"(0x0)); #endif // a64 || a32 } @@ -575,12 +575,12 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_1 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xD), "c"(0x1)); #endif // a64 || a32 } @@ -645,12 +645,12 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_2 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xD), "c"(0x2)); #endif // a64 || a32 } @@ -698,12 +698,66 @@ namespace CPU /** @brief Processor Extended State Emulation */ struct CPUID0x0000000D_ECX_11 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xD), "c"(0x11)); +#endif // a64 || a32 + } + + /** @brief Processor Extended State Emulation */ + union + { + struct + { + uint32_t CetSupervisorSize : 32; + }; + cpuid_t raw; + } EAX; + + /** @brief Processor Extended State Emulation */ + union + { + struct + { + uint32_t CetSupervisorOffset : 32; + }; + cpuid_t raw; + } EBX; + + /** @brief Processor Extended State Emulation */ + union + { + struct + { + uint32_t Reserved : 31; + uint32_t US : 1; + }; + cpuid_t raw; + } ECX; + + /** @brief Processor Extended State Emulation */ + union + { + struct + { + uint32_t Unused : 32; + }; + cpuid_t raw; + } EDX; + }; + + /** @brief Processor Extended State Emulation */ + struct CPUID0x0000000D_ECX_12 + { + __always_inline inline void Get() + { +#if defined(a86) + asmv("cpuid" + : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) + : "a"(0xD), "c"(0x12)); #endif // a64 || a32 } @@ -750,14 +804,14 @@ namespace CPU }; /** @brief Processor Extended State Enumeration */ - struct CPUID0x0000000D_ECX_3H + struct CPUID0x0000000D_ECX_3E { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xD), "c"(0x3E)); #endif // a64 || a32 } @@ -805,12 +859,12 @@ namespace CPU /** @brief Maximum Extended Function Number and Vendor String */ struct CPUID0x80000000 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000000)); #endif // a64 || a32 } @@ -858,12 +912,12 @@ namespace CPU /** @brief Extended Processor and Processor Feature Identifiers */ struct CPUID0x80000001 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000001)); #endif // a64 || a32 } @@ -979,12 +1033,12 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000002 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000002)); #endif // a64 || a32 } @@ -1028,12 +1082,12 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000003 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000003)); #endif // a64 || a32 } @@ -1077,12 +1131,12 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000004 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000004)); #endif // a64 || a32 } @@ -1126,12 +1180,12 @@ namespace CPU /** @brief L1 Cache and TLB Information */ struct CPUID0x80000005 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000005)); #endif // a64 || a32 } @@ -1191,12 +1245,12 @@ namespace CPU /** @brief L2 Cache and TLB and L3 Cache Information */ struct CPUID0x80000006 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000006)); #endif // a64 || a32 } @@ -1257,12 +1311,12 @@ namespace CPU /** @brief Processor Power Management and RAS Capabilities */ struct CPUID0x80000007 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000007)); #endif // a64 || a32 } @@ -1326,12 +1380,12 @@ namespace CPU /** @brief Processor Capacity Parameters and Extended Feature Identification */ struct CPUID0x80000008 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000008)); #endif // a64 || a32 } @@ -1413,12 +1467,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000000A { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000000A)); #endif // a64 || a32 } @@ -1466,12 +1520,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000019 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000019)); #endif // a64 || a32 } @@ -1519,12 +1573,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001A { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001A)); #endif // a64 || a32 } @@ -1572,12 +1626,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001B { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001B)); #endif // a64 || a32 } @@ -1625,12 +1679,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001C { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001C)); #endif // a64 || a32 } @@ -1678,12 +1732,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001D { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001D)); #endif // a64 || a32 } @@ -1731,12 +1785,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001E { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001E)); #endif // a64 || a32 } @@ -1784,12 +1838,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001F { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000001F)); #endif // a64 || a32 } @@ -1837,12 +1891,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000020 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000020)); #endif // a64 || a32 } @@ -1890,12 +1944,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000021 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000021)); #endif // a64 || a32 } @@ -1943,12 +1997,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000022 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000022)); #endif // a64 || a32 } @@ -1996,12 +2050,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000023 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000023)); #endif // a64 || a32 } @@ -2049,12 +2103,12 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000026 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000026)); #endif // a64 || a32 } diff --git a/include/cpu/x86/cpuid_intel.hpp b/include/cpu/x86/cpuid_intel.hpp index 9c493b6..607977b 100644 --- a/include/cpu/x86/cpuid_intel.hpp +++ b/include/cpu/x86/cpuid_intel.hpp @@ -38,12 +38,12 @@ namespace CPU /** @brief Basic CPU information */ struct CPUID0x00000000 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x0)); #endif // a64 || a32 } @@ -84,9 +84,9 @@ namespace CPU /** @brief Additional CPU information */ struct CPUID0x00000001 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "a"(0x1)); @@ -206,12 +206,12 @@ namespace CPU /** @brief CPU cache and TLB */ struct CPUID0x00000002 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x2)); #endif // a64 || a32 } @@ -267,12 +267,12 @@ namespace CPU /** @brief CPU serial number */ struct CPUID0x00000003 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x3)); #endif // a64 || a32 } @@ -316,12 +316,12 @@ namespace CPU /** @brief Cache information */ struct CPUID0x00000004_1 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x4), "c"(0x1)); /* FIXME */ #endif // a64 || a32 } @@ -373,12 +373,12 @@ namespace CPU /** @brief MONITOR information */ struct CPUID0x00000005 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x5)); #endif // a64 || a32 } @@ -431,12 +431,12 @@ namespace CPU /** @brief Thermal and power management information */ struct CPUID0x00000006 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x6)); #endif // a64 || a32 } @@ -483,12 +483,12 @@ namespace CPU /** @brief Extended feature flags enumeration */ struct CPUID0x00000007_0 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x7), "c"(0x0)); /* FIXME */ #endif // a64 || a32 } @@ -709,12 +709,12 @@ namespace CPU /** @brief Extended feature flags enumeration */ struct CPUID0x00000007_1 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x7), "c"(0x1)); /* FIXME */ #endif // a64 || a32 } @@ -815,12 +815,12 @@ namespace CPU /** @brief Performance monitors */ struct CPUID0x0000000A { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0xA)); #endif // a64 || a32 } @@ -876,12 +876,12 @@ namespace CPU /** @brief Get CPU frequency information */ struct CPUID0x00000015 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x15)); #endif // a64 || a32 } @@ -937,12 +937,12 @@ namespace CPU /** @brief Get CPU frequency information */ struct CPUID0x00000016 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x16)); #endif // a64 || a32 } @@ -998,12 +998,12 @@ namespace CPU /** @brief Extended CPU information */ struct CPUID0x80000000 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000000)); #endif // a64 || a32 } @@ -1048,12 +1048,12 @@ namespace CPU /** @brief Extended CPU information */ struct CPUID0x80000001 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000001)); #endif // a64 || a32 } @@ -1105,12 +1105,12 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000002 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000002)); #endif // a64 || a32 } @@ -1155,12 +1155,12 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000003 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000003)); #endif // a64 || a32 } @@ -1205,12 +1205,12 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000004 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000004)); #endif // a64 || a32 } @@ -1255,12 +1255,12 @@ namespace CPU /** @brief CPU cache line information */ struct CPUID0x80000006 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000006)); #endif // a64 || a32 } @@ -1314,12 +1314,12 @@ namespace CPU /** @brief Virtual and physical memory size */ struct CPUID0x80000008 { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x80000008)); #endif // a64 || a32 } @@ -1366,12 +1366,12 @@ namespace CPU /** @brief Secure virtual machine parameters */ struct CPUID0x8000000A { - void Get() + __always_inline inline void Get() { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("cpuid" : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); + : "a"(0x8000000A)); #endif // a64 || a32 } diff --git a/include/display.hpp b/include/display.hpp index 11624aa..64c0b71 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -109,7 +109,7 @@ namespace Video { private: BootInfo::FramebufferInfo framebuffer; - Font *CurrentFont; + Font *CurrentFont = nullptr; ScreenBuffer Buffers[256]; bool ColorIteration = false; int ColorPickerIteration = 0; diff --git a/include/driver.hpp b/include/driver.hpp index 31c8f65..0919359 100644 --- a/include/driver.hpp +++ b/include/driver.hpp @@ -52,7 +52,7 @@ namespace Driver void *Address = nullptr; void *InterruptCallback = nullptr; Memory::MemMgr *MemTrk = nullptr; - DriverInterruptHook *InterruptHook[16] = {nullptr}; + DriverInterruptHook *InterruptHook[16]{}; }; class DriverInterruptHook : public Interrupts::Handler diff --git a/include/intrin.hpp b/include/intrin.hpp index 39b30fb..953a73d 100644 --- a/include/intrin.hpp +++ b/include/intrin.hpp @@ -21,7 +21,7 @@ #include #include -#if defined(a64) || defined(a32) +#if defined(a86) #define MMX_FN_ATTR __always_inline __target("mmx") #define SSE_FN_ATTR __always_inline __target("sse") #define SSE2_FN_ATTR __always_inline __target("sse2") @@ -86,7 +86,7 @@ namespace SMAP { void _clac(void) { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("clac" :: : "cc"); #endif // a64 || a32 @@ -94,7 +94,7 @@ namespace SMAP void _stac(void) { -#if defined(a64) || defined(a32) +#if defined(a86) asmv("stac" :: : "cc"); #endif // a64 || a32 @@ -103,7 +103,7 @@ namespace SMAP namespace MMX { -#if defined(a64) || defined(a32) +#if defined(a86) typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8))); typedef long long __v1di __attribute__((__vector_size__(8))); @@ -120,7 +120,7 @@ namespace MMX namespace SSE { -#if defined(a64) || defined(a32) +#if defined(a86) typedef int __v4si __attribute__((__vector_size__(16))); typedef unsigned int __v4su __attribute__((__vector_size__(16))); typedef float __v4sf __attribute__((__vector_size__(16))); @@ -144,7 +144,7 @@ namespace SSE namespace SSE2 { -#if defined(a64) || defined(a32) +#if defined(a86) typedef double __v2df __attribute__((__vector_size__(16))); typedef long long __v2di __attribute__((__vector_size__(16))); @@ -205,19 +205,19 @@ namespace SSE2 namespace SSE3 { -#if defined(a64) || defined(a32) +#if defined(a86) #endif // a64 || a32 } namespace SSSE3 { -#if defined(a64) || defined(a32) +#if defined(a86) #endif // a64 || a32 } namespace SSE4_1 { -#if defined(a64) || defined(a32) +#if defined(a86) typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16))); ST_IN SSE4_1_FN_ATTR __m128i _mm_cvtepu8_epi32(__m128i a); @@ -229,19 +229,19 @@ namespace SSE4_1 namespace SSE4_2 { -#if defined(a64) || defined(a32) +#if defined(a86) #endif // a64 || a32 } namespace AVX { -#if defined(a64) || defined(a32) +#if defined(a86) #endif // a64 || a32 } namespace AVX2 { -#if defined(a64) || defined(a32) +#if defined(a86) #endif // a64 || a32 } diff --git a/include/io.h b/include/io.h index 92204f9..ab127f7 100644 --- a/include/io.h +++ b/include/io.h @@ -20,7 +20,7 @@ #include -#if defined(a64) || defined(a32) +#if defined(a86) #ifdef __cplusplus extern "C" @@ -232,6 +232,6 @@ extern "C" #define outw(Port, Data) outportw(Port, Data) #define outl(Port, Data) outportl(Port, Data) -#endif // defined(a64) || defined(a32) +#endif // defined(a86) #endif // !__FENNIX_KERNEL_IO_H__ diff --git a/include/memory.hpp b/include/memory.hpp index 31f6e08..b3d2845 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -62,7 +62,7 @@ extern uintptr_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end; #define USER_STACK_SIZE 0x2000 // 8kb // To pages -#define TO_PAGES(d) ((d) / PAGE_SIZE + 1) +#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE) // From pages #define FROM_PAGES(d) ((d)*PAGE_SIZE) @@ -436,6 +436,18 @@ namespace Memory struct PageTable4 { PageMapLevel4 Entries[511]; + + /** + * @brief Update CR3 with this PageTable4 + */ + void Update() + { +#if defined(a86) + asmv("mov %0, %%cr3" ::"r"(this)); +#elif defined(aa64) + asmv("msr ttbr0_el1, %0" ::"r"(this)); +#endif + } } __aligned(0x1000); struct __packed PageMapLevel5 @@ -460,11 +472,6 @@ namespace Memory uint64_t PageBitmapIndex = 0; Bitmap PageBitmap; - void ReservePage(void *Address); - void ReservePages(void *Address, size_t PageCount); - void UnreservePage(void *Address); - void UnreservePages(void *Address, size_t PageCount); - public: Bitmap GetPageBitmap() { return PageBitmap; } @@ -549,6 +556,11 @@ namespace Memory */ void LockPages(void *Address, size_t PageCount); + void ReservePage(void *Address); + void ReservePages(void *Address, size_t PageCount); + void UnreservePage(void *Address); + void UnreservePages(void *Address, size_t PageCount); + /** * @brief Request page * @@ -869,7 +881,6 @@ void operator delete[](void *Pointer, long unsigned int Size); extern Memory::Physical KernelAllocator; extern Memory::PageTable4 *KernelPageTable; -extern Memory::PageTable4 *UserspaceKernelOnlyPageTable; #endif // __cplusplus diff --git a/include/smp.hpp b/include/smp.hpp index 1c7aac9..324aa44 100644 --- a/include/smp.hpp +++ b/include/smp.hpp @@ -45,7 +45,7 @@ struct CPUData uintptr_t TempStack; /* gs+0x8 */ /** @brief Used by CPU */ - uintptr_t Stack; + uintptr_t Stack; /* gs+0x10 */ /** @brief CPU ID. */ int ID; diff --git a/include/types.h b/include/types.h index b95df2a..2ef2f12 100644 --- a/include/types.h +++ b/include/types.h @@ -44,6 +44,9 @@ #define true 1 #define false 0 +#define inf_loop while (1) +#define ilp inf_loop; /* Used for debugging */ + #ifdef __cplusplus #define foreach for #define in : diff --git a/kernel.h b/kernel.h index e9c0f7b..77edfc1 100644 --- a/kernel.h +++ b/kernel.h @@ -36,7 +36,7 @@ #include #endif -extern struct BootInfo *bInfo; +extern struct BootInfo bInfo; extern bool DebuggerIsAttached; #ifdef __cplusplus