QoL and bug fixes

This commit is contained in:
Alex 2023-04-10 03:11:46 +03:00
parent 25aa9ff6a6
commit b4dbf2c281
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
83 changed files with 1438 additions and 1025 deletions

View File

@ -13,6 +13,7 @@
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"", "GIT_COMMIT_SHORT=\"0000000\"",
"a64", "a64",
"a86",
"DEBUG=\"1\"" "DEBUG=\"1\""
], ],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc", "compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc",
@ -82,6 +83,7 @@
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"", "GIT_COMMIT_SHORT=\"0000000\"",
"a32", "a32",
"a86",
"DEBUG=\"1\"" "DEBUG=\"1\""
], ],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc", "compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",

2
.vscode/launch.json vendored
View File

@ -2,7 +2,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Attach to a running QEMU instance", "name": "Attach to a running VM instance",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/kernel.fsys", "program": "${workspaceRoot}/kernel.fsys",

View File

@ -20,6 +20,8 @@
#include <debug.h> #include <debug.h>
#include <io.h> #include <io.h>
#include "../../kernel.h"
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
namespace ACPI namespace ACPI
@ -28,20 +30,20 @@ namespace ACPI
{ {
for (uint64_t t = 0; t < ((ACPIHeader->Length - sizeof(ACPI::ACPIHeader)) / (XSDTSupported ? 8 : 4)); t++) 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; ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDTSupported) if (XSDTSupported)
SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8))); SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8)));
else else
SDTHdr = (ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 4))); 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]) if (SDTHdr->Signature[i] != Signature[i])
break; break;
if (i == 3) 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; return SDTHdr;
} }
} }
@ -55,86 +57,86 @@ namespace ACPI
if (!Header) if (!Header)
return; return;
HPET = (HPETHeader *)FindTable(XSDT, (char *)"HPET"); HPET = (HPETHeader *)FindTable(Header, (char *)"HPET");
FADT = (FADTHeader *)FindTable(XSDT, (char *)"FACP"); FADT = (FADTHeader *)FindTable(Header, (char *)"FACP");
MCFG = (MCFGHeader *)FindTable(XSDT, (char *)"MCFG"); MCFG = (MCFGHeader *)FindTable(Header, (char *)"MCFG");
BGRT = (BGRTHeader *)FindTable(XSDT, (char *)"BGRT"); BGRT = (BGRTHeader *)FindTable(Header, (char *)"BGRT");
SRAT = (SRATHeader *)FindTable(XSDT, (char *)"SRAT"); SRAT = (SRATHeader *)FindTable(Header, (char *)"SRAT");
TPM2 = (TPM2Header *)FindTable(XSDT, (char *)"TPM2"); TPM2 = (TPM2Header *)FindTable(Header, (char *)"TPM2");
TCPA = (TCPAHeader *)FindTable(XSDT, (char *)"TCPA"); TCPA = (TCPAHeader *)FindTable(Header, (char *)"TCPA");
WAET = (WAETHeader *)FindTable(XSDT, (char *)"WAET"); WAET = (WAETHeader *)FindTable(Header, (char *)"WAET");
MADT = (MADTHeader *)FindTable(XSDT, (char *)"APIC"); MADT = (MADTHeader *)FindTable(Header, (char *)"APIC");
HEST = (HESTHeader *)FindTable(XSDT, (char *)"HEST"); HEST = (HESTHeader *)FindTable(Header, (char *)"HEST");
FindTable(XSDT, (char *)"BERT"); FindTable(Header, (char *)"BERT");
FindTable(XSDT, (char *)"CPEP"); FindTable(Header, (char *)"CPEP");
FindTable(XSDT, (char *)"DSDT"); FindTable(Header, (char *)"DSDT");
FindTable(XSDT, (char *)"ECDT"); FindTable(Header, (char *)"ECDT");
FindTable(XSDT, (char *)"EINJ"); FindTable(Header, (char *)"EINJ");
FindTable(XSDT, (char *)"ERST"); FindTable(Header, (char *)"ERST");
FindTable(XSDT, (char *)"FACS"); FindTable(Header, (char *)"FACS");
FindTable(XSDT, (char *)"MSCT"); FindTable(Header, (char *)"MSCT");
FindTable(XSDT, (char *)"MPST"); FindTable(Header, (char *)"MPST");
FindTable(XSDT, (char *)"OEMx"); FindTable(Header, (char *)"OEMx");
FindTable(XSDT, (char *)"PMTT"); FindTable(Header, (char *)"PMTT");
FindTable(XSDT, (char *)"PSDT"); FindTable(Header, (char *)"PSDT");
FindTable(XSDT, (char *)"RASF"); FindTable(Header, (char *)"RASF");
FindTable(XSDT, (char *)"RSDT"); FindTable(Header, (char *)"RSDT");
FindTable(XSDT, (char *)"SBST"); FindTable(Header, (char *)"SBST");
FindTable(XSDT, (char *)"SLIT"); FindTable(Header, (char *)"SLIT");
FindTable(XSDT, (char *)"SSDT"); FindTable(Header, (char *)"SSDT");
FindTable(XSDT, (char *)"XSDT"); FindTable(Header, (char *)"XSDT");
FindTable(XSDT, (char *)"DRTM"); FindTable(Header, (char *)"DRTM");
FindTable(XSDT, (char *)"FPDT"); FindTable(Header, (char *)"FPDT");
FindTable(XSDT, (char *)"GTDT"); FindTable(Header, (char *)"GTDT");
FindTable(XSDT, (char *)"PCCT"); FindTable(Header, (char *)"PCCT");
FindTable(XSDT, (char *)"S3PT"); FindTable(Header, (char *)"S3PT");
FindTable(XSDT, (char *)"MATR"); FindTable(Header, (char *)"MATR");
FindTable(XSDT, (char *)"MSDM"); FindTable(Header, (char *)"MSDM");
FindTable(XSDT, (char *)"WPBT"); FindTable(Header, (char *)"WPBT");
FindTable(XSDT, (char *)"OSDT"); FindTable(Header, (char *)"OSDT");
FindTable(XSDT, (char *)"RSDP"); FindTable(Header, (char *)"RSDP");
FindTable(XSDT, (char *)"NFIT"); FindTable(Header, (char *)"NFIT");
FindTable(XSDT, (char *)"ASF!"); FindTable(Header, (char *)"ASF!");
FindTable(XSDT, (char *)"BOOT"); FindTable(Header, (char *)"BOOT");
FindTable(XSDT, (char *)"CSRT"); FindTable(Header, (char *)"CSRT");
FindTable(XSDT, (char *)"DBG2"); FindTable(Header, (char *)"DBG2");
FindTable(XSDT, (char *)"DBGP"); FindTable(Header, (char *)"DBGP");
FindTable(XSDT, (char *)"DMAR"); FindTable(Header, (char *)"DMAR");
FindTable(XSDT, (char *)"IBFT"); FindTable(Header, (char *)"IBFT");
FindTable(XSDT, (char *)"IORT"); FindTable(Header, (char *)"IORT");
FindTable(XSDT, (char *)"IVRS"); FindTable(Header, (char *)"IVRS");
FindTable(XSDT, (char *)"LPIT"); FindTable(Header, (char *)"LPIT");
FindTable(XSDT, (char *)"MCHI"); FindTable(Header, (char *)"MCHI");
FindTable(XSDT, (char *)"MTMR"); FindTable(Header, (char *)"MTMR");
FindTable(XSDT, (char *)"SLIC"); FindTable(Header, (char *)"SLIC");
FindTable(XSDT, (char *)"SPCR"); FindTable(Header, (char *)"SPCR");
FindTable(XSDT, (char *)"SPMI"); FindTable(Header, (char *)"SPMI");
FindTable(XSDT, (char *)"UEFI"); FindTable(Header, (char *)"UEFI");
FindTable(XSDT, (char *)"VRTC"); FindTable(Header, (char *)"VRTC");
FindTable(XSDT, (char *)"WDAT"); FindTable(Header, (char *)"WDAT");
FindTable(XSDT, (char *)"WDDT"); FindTable(Header, (char *)"WDDT");
FindTable(XSDT, (char *)"WDRT"); FindTable(Header, (char *)"WDRT");
FindTable(XSDT, (char *)"ATKG"); FindTable(Header, (char *)"ATKG");
FindTable(XSDT, (char *)"GSCI"); FindTable(Header, (char *)"GSCI");
FindTable(XSDT, (char *)"IEIT"); FindTable(Header, (char *)"IEIT");
FindTable(XSDT, (char *)"HMAT"); FindTable(Header, (char *)"HMAT");
FindTable(XSDT, (char *)"CEDT"); FindTable(Header, (char *)"CEDT");
FindTable(XSDT, (char *)"AEST"); FindTable(Header, (char *)"AEST");
} }
ACPI::ACPI(BootInfo *Info) ACPI::ACPI()
{ {
trace("Initializing ACPI"); trace("Initializing ACPI");
if (Info->RSDP->Revision >= 2 && Info->RSDP->XSDTAddress) if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress)
{ {
debug("XSDT supported"); debug("XSDT supported");
XSDTSupported = true; XSDTSupported = true;
XSDT = (ACPIHeader *)(Info->RSDP->XSDTAddress); XSDT = (ACPIHeader *)(bInfo.RSDP->XSDTAddress);
} }
else else
{ {
debug("RSDT supported"); debug("RSDT supported");
XSDT = (ACPIHeader *)(uintptr_t)Info->RSDP->RSDTAddress; XSDT = (ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress;
} }
this->SearchTables(XSDT); this->SearchTables(XSDT);

View File

@ -68,12 +68,28 @@ __naked __used __no_stack_protector void InitLimine()
: :
: "r"((uintptr_t)TempStackPtr - 0xFFFF800000000000)); : "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"); asmv("jmp InitLimineAfterStack");
} }
SafeFunction NIF void InitLimineAfterStack() SafeFunction NIF void InitLimineAfterStack()
{ {
struct BootInfo binfo; struct BootInfo binfo = {};
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response; struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response;
info("Bootloader: %s %s", BootloaderInfoResponse->name, BootloaderInfoResponse->version); info("Bootloader: %s %s", BootloaderInfoResponse->name, BootloaderInfoResponse->version);
@ -82,8 +98,7 @@ SafeFunction NIF void InitLimineAfterStack()
if (TerminalResponse == NULL || TerminalResponse->terminal_count < 1) if (TerminalResponse == NULL || TerminalResponse->terminal_count < 1)
{ {
warn("No terminal available."); warn("No terminal available.");
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
TerminalResponse->write(TerminalResponse->terminals[0], "\033[37mPlease wait... ", 20); TerminalResponse->write(TerminalResponse->terminals[0], "\033[37mPlease wait... ", 20);
@ -97,67 +112,79 @@ SafeFunction NIF void InitLimineAfterStack()
if (FrameBufferResponse == NULL || FrameBufferResponse->framebuffer_count < 1) 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); (FrameBufferResponse == NULL) ? 0 : FrameBufferResponse->framebuffer_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No framebuffer available", 24); TerminalResponse->write(TerminalResponse->terminals[0], "No framebuffer available", 24);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
if (MemmapResponse == NULL || MemmapResponse->entry_count < 1) 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); (MemmapResponse == NULL) ? 0 : MemmapResponse->entry_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No memory map available", 23); TerminalResponse->write(TerminalResponse->terminals[0], "No memory map available", 23);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
if (KernelAddressResponse == NULL) 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); TerminalResponse->write(TerminalResponse->terminals[0], "No kernel address available", 27);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
if (RsdpResponse == NULL || RsdpResponse->address == 0) 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); (RsdpResponse == NULL) ? 0 : RsdpResponse->address);
TerminalResponse->write(TerminalResponse->terminals[0], "No RSDP address available", 25); TerminalResponse->write(TerminalResponse->terminals[0], "No RSDP address available", 25);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
if (KernelFileResponse == NULL || KernelFileResponse->kernel_file == NULL) 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); (KernelFileResponse == NULL) ? 0 : KernelFileResponse->kernel_file);
TerminalResponse->write(TerminalResponse->terminals[0], "No kernel file available", 24); TerminalResponse->write(TerminalResponse->terminals[0], "No kernel file available", 24);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
if (ModuleResponse == NULL || ModuleResponse->module_count < 1) 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); (ModuleResponse == NULL) ? 0 : ModuleResponse->module_count);
TerminalResponse->write(TerminalResponse->terminals[0], "No module information available", 31); TerminalResponse->write(TerminalResponse->terminals[0], "No module information available", 31);
while (1) inf_loop asmv("hlt");
asmv("hlt");
} }
/* Actual parsing starts here */
for (uint64_t i = 0; i < FrameBufferResponse->framebuffer_count; i++) for (uint64_t i = 0; i < FrameBufferResponse->framebuffer_count; i++)
{ {
struct limine_framebuffer *framebuffer = FrameBufferResponse->framebuffers[i]; struct limine_framebuffer *framebuffer = FrameBufferResponse->framebuffers[i];
switch (framebuffer->memory_model)
{
case LIMINE_FRAMEBUFFER_RGB:
binfo.Framebuffer[i].Type = RGB; binfo.Framebuffer[i].Type = RGB;
binfo.Framebuffer[i].BaseAddress = (void *)((uint64_t)framebuffer->address - 0xFFFF800000000000); 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].Width = (uint32_t)framebuffer->width;
binfo.Framebuffer[i].Height = (uint32_t)framebuffer->height; binfo.Framebuffer[i].Height = (uint32_t)framebuffer->height;
binfo.Framebuffer[i].Pitch = (uint32_t)framebuffer->pitch; binfo.Framebuffer[i].Pitch = (uint32_t)framebuffer->pitch;
binfo.Framebuffer[i].BitsPerPixel = framebuffer->bpp; binfo.Framebuffer[i].BitsPerPixel = framebuffer->bpp;
binfo.Framebuffer[i].MemoryModel = framebuffer->memory_model;
binfo.Framebuffer[i].RedMaskSize = framebuffer->red_mask_size; binfo.Framebuffer[i].RedMaskSize = framebuffer->red_mask_size;
binfo.Framebuffer[i].RedMaskShift = framebuffer->red_mask_shift; binfo.Framebuffer[i].RedMaskShift = framebuffer->red_mask_shift;
binfo.Framebuffer[i].GreenMaskSize = framebuffer->green_mask_size; 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].BlueMaskShift = framebuffer->blue_mask_shift;
binfo.Framebuffer[i].ExtendedDisplayIdentificationData = framebuffer->edid; binfo.Framebuffer[i].ExtendedDisplayIdentificationData = framebuffer->edid;
binfo.Framebuffer[i].EDIDSize = framebuffer->edid_size; 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", debug("Framebuffer %d: %dx%d %d bpp", i,
(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); 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; binfo.Memory.Entries = MemmapResponse->entry_count;
@ -181,6 +223,12 @@ SafeFunction NIF void InitLimineAfterStack()
} }
struct limine_memmap_entry *entry = MemmapResponse->entries[i]; 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; binfo.Memory.Size += entry->length;
switch (entry->type) 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].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xFFFF800000000000);
binfo.Modules[i].Size = ModuleResponse->modules[i]->size;
strncpy(binfo.Modules[i].Path, strncpy(binfo.Modules[i].Path,
ModuleResponse->modules[i]->path, ModuleResponse->modules[i]->path,
strlen(ModuleResponse->modules[i]->path) + 1); strlen(ModuleResponse->modules[i]->path) + 1);
strncpy(binfo.Modules[i].CommandLine, strncpy(binfo.Modules[i].CommandLine,
ModuleResponse->modules[i]->cmdline, ModuleResponse->modules[i]->cmdline,
strlen(ModuleResponse->modules[i]->cmdline) + 1); 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, debug("Module %d:\nAddress: %#lx\nPath: \"%s\"\nCommand Line: \"%s\"\nSize: %ld",
(uint64_t)ModuleResponse->modules[i]->address - 0xFFFF800000000000, ModuleResponse->modules[i]->path, i,
ModuleResponse->modules[i]->cmdline, ModuleResponse->modules[i]->size); 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); binfo.RSDP = (struct RSDPInfo *)((uintptr_t)RsdpResponse->address - 0xFFFF800000000000);
trace("RSDP: %p(%p) [Signature: %.8s] [OEM: %.6s]", debug("RSDP: %#lx [Signature: \"%.8s\"] [OEM: \"%.6s\"]",
RsdpResponse->address, binfo.RSDP, binfo.RSDP->Signature, binfo.RSDP->OEMID); binfo.RSDP, binfo.RSDP->Signature, binfo.RSDP->OEMID);
debug("SMBIOS: %p %p", SmbiosResponse->entry_32, SmbiosResponse->entry_64); if (SmbiosResponse->entry_64 != NULL)
if (SmbiosResponse->entry_32 != NULL) binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_64 - 0xFFFF800000000000);
binfo.SMBIOSPtr = (void *)((uint64_t)SmbiosResponse->entry_32 - 0xFFFF800000000000); else if (SmbiosResponse->entry_32 != NULL)
else if (SmbiosResponse->entry_64 != NULL) binfo.SMBIOSPtr = (void *)((uintptr_t)SmbiosResponse->entry_32 - 0xFFFF800000000000);
binfo.SMBIOSPtr = (void *)((uint64_t)SmbiosResponse->entry_64 - 0xFFFF800000000000);
else else
binfo.SMBIOSPtr = NULL; 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.PhysicalBase = (void *)KernelAddressResponse->physical_base;
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_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, strncpy(binfo.Kernel.CommandLine,
KernelFileResponse->kernel_file->cmdline, KernelFileResponse->kernel_file->cmdline,
strlen(KernelFileResponse->kernel_file->cmdline) + 1); strlen(KernelFileResponse->kernel_file->cmdline) + 1);
binfo.Kernel.Size = KernelFileResponse->kernel_file->size;
trace("Kernel physical address: %p", KernelAddressResponse->physical_base); debug("Kernel physical address: %#lx", binfo.Kernel.PhysicalBase);
trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base); debug("Kernel virtual address: %#lx", binfo.Kernel.VirtualBase);
strncpy(binfo.Bootloader.Name, strncpy(binfo.Bootloader.Name,
BootloaderInfoResponse->name, BootloaderInfoResponse->name,
strlen(BootloaderInfoResponse->name) + 1); strlen(BootloaderInfoResponse->name) + 1);
strncpy(binfo.Bootloader.Version, strncpy(binfo.Bootloader.Version,
BootloaderInfoResponse->version, BootloaderInfoResponse->version,
strlen(BootloaderInfoResponse->version) + 1); strlen(BootloaderInfoResponse->version) + 1);
// Call kernel entry point
Entry(&binfo); Entry(&binfo);
} }

View File

@ -29,7 +29,7 @@ extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
extern "C" void SystemCallHandlerStub(); 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" asmv("swapgs\n"

View File

@ -198,7 +198,7 @@ namespace ACPI
void *FindTable(ACPIHeader *ACPIHeader, char *Signature); void *FindTable(ACPIHeader *ACPIHeader, char *Signature);
void SearchTables(ACPIHeader *Header); void SearchTables(ACPIHeader *Header);
ACPI(BootInfo *Info); ACPI();
~ACPI(); ~ACPI();
}; };

View File

@ -48,10 +48,12 @@ namespace APIC
uint32_t APIC::Read(uint32_t Register) uint32_t APIC::Read(uint32_t Register)
{ {
#ifdef DEBUG
if (Register != APIC_ICRLO && if (Register != APIC_ICRLO &&
Register != APIC_ICRHI && Register != APIC_ICRHI &&
Register != APIC_ID) Register != APIC_ID)
debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0); debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported) if (x2APICSupported)
{ {
if (Register != APIC_ICRHI) if (Register != APIC_ICRHI)
@ -70,6 +72,7 @@ namespace APIC
void APIC::Write(uint32_t Register, uint32_t Value) void APIC::Write(uint32_t Register, uint32_t Value)
{ {
#ifdef DEBUG
if (Register != APIC_EOI && if (Register != APIC_EOI &&
Register != APIC_TDCR && Register != APIC_TDCR &&
Register != APIC_TIMER && Register != APIC_TIMER &&
@ -77,6 +80,7 @@ namespace APIC
Register != APIC_ICRLO && Register != APIC_ICRLO &&
Register != APIC_ICRHI) Register != APIC_ICRHI)
debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0); debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported) if (x2APICSupported)
{ {
if (Register != APIC_ICRHI) if (Register != APIC_ICRHI)
@ -129,8 +133,8 @@ namespace APIC
SmartCriticalSection(APICLock); SmartCriticalSection(APICLock);
if (x2APICSupported) if (x2APICSupported)
{ {
fixme("Not implemented for x2APIC"); wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
// wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32); this->WaitForIPI();
} }
else else
{ {
@ -145,8 +149,11 @@ namespace APIC
SmartCriticalSection(APICLock); SmartCriticalSection(APICLock);
if (x2APICSupported) if (x2APICSupported)
{ {
fixme("Not implemented for x2APIC"); InterruptCommandRegisterLow icr = {.raw = 0};
// wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32); icr.DeliveryMode = INIT;
icr.Level = Assert;
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
} }
else else
{ {
@ -164,8 +171,12 @@ namespace APIC
SmartCriticalSection(APICLock); SmartCriticalSection(APICLock);
if (x2APICSupported) if (x2APICSupported)
{ {
warn("Not tested for x2APIC"); InterruptCommandRegisterLow icr = {.raw = 0};
wrmsr(MSR_X2APIC_ICR, ((uint64_t)CPU) << 32 | StartupAddress); 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 else
{ {
@ -254,6 +265,7 @@ namespace APIC
uint64_t BaseHigh = BaseStruct.ApicBaseHi; uint64_t BaseHigh = BaseStruct.ApicBaseHi;
this->APICBaseAddress = BaseLow << 12u | BaseHigh << 32u; this->APICBaseAddress = BaseLow << 12u | BaseHigh << 32u;
trace("APIC Address: %#lx", this->APICBaseAddress); trace("APIC Address: %#lx", this->APICBaseAddress);
Memory::Virtual().Map((void *)this->APICBaseAddress, (void *)this->APICBaseAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD);
bool x2APICSupported = false; bool x2APICSupported = false;
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
@ -270,7 +282,11 @@ namespace APIC
{ {
CPU::x86::Intel::CPUID0x00000001 cpuid; CPU::x86::Intel::CPUID0x00000001 cpuid;
cpuid.Get(); cpuid.Get();
x2APICSupported = cpuid.ECX.x2APIC; if (cpuid.ECX.x2APIC)
{
// x2APICSupported = cpuid.ECX.x2APIC;
fixme("x2APIC is supported");
}
} }
if (x2APICSupported) if (x2APICSupported)

View File

@ -115,8 +115,8 @@ namespace GlobalDescriptorTable
.TaskStateSegment = {}, .TaskStateSegment = {},
}; };
GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; GlobalDescriptorTableEntries GDTEntries[MAX_CPU] __aligned(16);
GlobalDescriptorTableDescriptor gdt[MAX_CPU]; GlobalDescriptorTableDescriptor gdt[MAX_CPU] __aligned(16);
TaskStateSegment tss[MAX_CPU] = { TaskStateSegment tss[MAX_CPU] = {
0, 0,
@ -154,12 +154,14 @@ namespace GlobalDescriptorTable
"movw %%ax, %%es\n" :: "movw %%ax, %%es\n" ::
: "memory", "rax"); : "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); 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]; uintptr_t Base = (uintptr_t)&tss[Core];
uint64_t Limit = Base + sizeof(TaskStateSegment); size_t Limit = Base + sizeof(TaskStateSegment);
gdt[Core].Entries->TaskStateSegment.Length = Limit & 0xFFFF; gdt[Core].Entries->TaskStateSegment.Length = Limit & 0xFFFF;
gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF; gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF;
gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF; gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF;
@ -170,12 +172,15 @@ namespace GlobalDescriptorTable
tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment); tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment);
tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE; 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; for (size_t i = 0; i < sizeof(tss[Core].InterruptStackTable) / sizeof(tss[Core].InterruptStackTable[7]); i++)
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); void *NewStack = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
memset((void *)(tss[Core].InterruptStackTable[1] - STACK_SIZE), 0, STACK_SIZE);
memset((void *)(tss[Core].InterruptStackTable[2] - STACK_SIZE), 0, STACK_SIZE); 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); CPU::x64::ltr(GDT_TSS);

View File

@ -23,6 +23,7 @@
#include <io.h> #include <io.h>
#include "gdt.hpp" #include "gdt.hpp"
#include "../../../kernel.h"
/* conversion from uint64_t {aka long unsigned int} to unsigned char:2 may change value */ /* conversion from uint64_t {aka long unsigned int} to unsigned char:2 may change value */
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
@ -41,24 +42,25 @@ namespace InterruptDescriptorTable
void SetEntry(uint8_t Index, void SetEntry(uint8_t Index,
void (*Base)(), void (*Base)(),
InterruptDescriptorTableFlags Attribute,
uint8_t InterruptStackTable, uint8_t InterruptStackTable,
InterruptDescriptorTableFlags Ring, InterruptGateType Gate,
InterruptRingType Ring,
bool Present,
uint16_t SegmentSelector) uint16_t SegmentSelector)
{ {
Entries[Index].BaseLow = s_cst(uint16_t, ((uint64_t)Base & 0xFFFF)); 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].BaseHigh = s_cst(uint64_t, ((uint64_t)Base >> 16 /* & 0xFFFF */));
Entries[Index].SegmentSelector = SegmentSelector; Entries[Index].SegmentSelector = SegmentSelector;
Entries[Index].Flags = Attribute; Entries[Index].Flags = Gate;
Entries[Index].Reserved1 = 0; Entries[Index].Reserved1 = 0;
Entries[Index].Reserved2 = 0; Entries[Index].Reserved2 = 0;
Entries[Index].Reserved3 = 0; Entries[Index].Reserved3 = 0;
Entries[Index].InterruptStackTable = InterruptStackTable; Entries[Index].InterruptStackTable = InterruptStackTable;
Entries[Index].Ring = Ring; 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" asm("cld\n"
@ -102,7 +104,7 @@ namespace InterruptDescriptorTable
"iretq"); // pop CS RIP RFLAGS SS RSP "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" asm("cld\n"
@ -149,21 +151,21 @@ namespace InterruptDescriptorTable
#pragma region Exceptions #pragma region Exceptions
#define EXCEPTION_HANDLER(num) \ #define EXCEPTION_HANDLER(num) \
__naked __used __no_stack_protector static void InterruptHandler_##num() \ __naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \
{ \ { \
asm("pushq $0\npushq $" #num "\n" \ asm("pushq $0\npushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \ "jmp ExceptionHandlerStub"); \
} }
#define EXCEPTION_ERROR_HANDLER(num) \ #define EXCEPTION_ERROR_HANDLER(num) \
__naked __used __no_stack_protector static void InterruptHandler_##num() \ __naked __used __no_stack_protector __aligned(16) static void InterruptHandler_##num() \
{ \ { \
asm("pushq $" #num "\n" \ asm("pushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \ "jmp ExceptionHandlerStub"); \
} }
#define INTERRUPT_HANDLER(num) \ #define INTERRUPT_HANDLER(num) \
__naked __used __no_stack_protector void InterruptHandler_##num() \ __naked __used __no_stack_protector __aligned(16) void InterruptHandler_##num() \
{ \ { \
asm("pushq $0\npushq $" #num "\n" \ asm("pushq $0\npushq $" #num "\n" \
"jmp InterruptHandlerStub\n"); \ "jmp InterruptHandlerStub\n"); \
@ -472,271 +474,280 @@ namespace InterruptDescriptorTable
/* ISR */ /* ISR */
SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); #ifdef DEBUG
SetEntry(0x1, InterruptHandler_0x1, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); if (!DebuggerIsAttached)
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); #endif
SetEntry(0x4, InterruptHandler_0x4, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x0, InterruptHandler_0x0, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5, InterruptHandler_0x5, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x1, InterruptHandler_0x1, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6, InterruptHandler_0x6, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2, InterruptHandler_0x2, 2, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7, InterruptHandler_0x7, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, 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(0x8, InterruptHandler_0x8, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4, InterruptHandler_0x4, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9, InterruptHandler_0x9, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5, InterruptHandler_0x5, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa, InterruptHandler_0xa, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6, InterruptHandler_0x6, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb, InterruptHandler_0xb, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7, InterruptHandler_0x7, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc, InterruptHandler_0xc, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8, InterruptHandler_0x8, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd, InterruptHandler_0xd, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9, InterruptHandler_0x9, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe, InterruptHandler_0xe, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa, InterruptHandler_0xa, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf, InterruptHandler_0xf, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb, InterruptHandler_0xb, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x10, InterruptHandler_0x10, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc, InterruptHandler_0xc, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x11, InterruptHandler_0x11, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd, InterruptHandler_0xd, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x12, InterruptHandler_0x12, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe, InterruptHandler_0xe, 3, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x13, InterruptHandler_0x13, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf, InterruptHandler_0xf, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x14, InterruptHandler_0x14, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x10, InterruptHandler_0x10, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x15, InterruptHandler_0x15, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x11, InterruptHandler_0x11, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x16, InterruptHandler_0x16, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x12, InterruptHandler_0x12, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x17, InterruptHandler_0x17, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x13, InterruptHandler_0x13, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x18, InterruptHandler_0x18, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x14, InterruptHandler_0x14, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x19, InterruptHandler_0x19, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x15, InterruptHandler_0x15, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1a, InterruptHandler_0x1a, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x16, InterruptHandler_0x16, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1b, InterruptHandler_0x1b, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x17, InterruptHandler_0x17, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1c, InterruptHandler_0x1c, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x18, InterruptHandler_0x18, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1d, InterruptHandler_0x1d, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x19, InterruptHandler_0x19, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1e, InterruptHandler_0x1e, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x1a, InterruptHandler_0x1a, 1, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x1f, InterruptHandler_0x1f, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, 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 */ /* IRQ */
SetEntry(0x20, InterruptHandler_0x20, 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, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x21, InterruptHandler_0x21, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x22, InterruptHandler_0x22, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x22, InterruptHandler_0x22, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x23, InterruptHandler_0x23, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x23, InterruptHandler_0x23, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x24, InterruptHandler_0x24, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x24, InterruptHandler_0x24, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x25, InterruptHandler_0x25, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x25, InterruptHandler_0x25, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x26, InterruptHandler_0x26, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x26, InterruptHandler_0x26, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x27, InterruptHandler_0x27, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x27, InterruptHandler_0x27, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x28, InterruptHandler_0x28, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x28, InterruptHandler_0x28, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x29, InterruptHandler_0x29, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x29, InterruptHandler_0x29, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2a, InterruptHandler_0x2a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2a, InterruptHandler_0x2a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2b, InterruptHandler_0x2b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2b, InterruptHandler_0x2b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2c, InterruptHandler_0x2c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2c, InterruptHandler_0x2c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2d, InterruptHandler_0x2d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2d, InterruptHandler_0x2d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2e, InterruptHandler_0x2e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2e, InterruptHandler_0x2e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x2f, InterruptHandler_0x2f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x2f, InterruptHandler_0x2f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
/* Reserved by OS */ /* Reserved by OS */
SetEntry(0x30, InterruptHandler_0x30, 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, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x31, InterruptHandler_0x31, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x32, InterruptHandler_0x32, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x32, InterruptHandler_0x32, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x33, InterruptHandler_0x33, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x33, InterruptHandler_0x33, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x34, InterruptHandler_0x34, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x34, InterruptHandler_0x34, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x35, InterruptHandler_0x35, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x35, InterruptHandler_0x35, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x36, InterruptHandler_0x36, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x36, InterruptHandler_0x36, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x37, InterruptHandler_0x37, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x37, InterruptHandler_0x37, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x38, InterruptHandler_0x38, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x38, InterruptHandler_0x38, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x39, InterruptHandler_0x39, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x39, InterruptHandler_0x39, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3a, InterruptHandler_0x3a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3a, InterruptHandler_0x3a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3b, InterruptHandler_0x3b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3b, InterruptHandler_0x3b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3c, InterruptHandler_0x3c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3c, InterruptHandler_0x3c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x3d, InterruptHandler_0x3d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3d, InterruptHandler_0x3d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
/* Free */ /* Free */
SetEntry(0x3e, InterruptHandler_0x3e, 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, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x3f, InterruptHandler_0x3f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x40, InterruptHandler_0x40, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x40, InterruptHandler_0x40, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x41, InterruptHandler_0x41, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x41, InterruptHandler_0x41, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x42, InterruptHandler_0x42, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x42, InterruptHandler_0x42, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x43, InterruptHandler_0x43, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x43, InterruptHandler_0x43, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x44, InterruptHandler_0x44, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x44, InterruptHandler_0x44, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x45, InterruptHandler_0x45, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x45, InterruptHandler_0x45, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x46, InterruptHandler_0x46, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x46, InterruptHandler_0x46, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x47, InterruptHandler_0x47, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x47, InterruptHandler_0x47, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x48, InterruptHandler_0x48, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x48, InterruptHandler_0x48, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x49, InterruptHandler_0x49, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x49, InterruptHandler_0x49, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4a, InterruptHandler_0x4a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4a, InterruptHandler_0x4a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4b, InterruptHandler_0x4b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4b, InterruptHandler_0x4b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4c, InterruptHandler_0x4c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4c, InterruptHandler_0x4c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4d, InterruptHandler_0x4d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4d, InterruptHandler_0x4d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4e, InterruptHandler_0x4e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4e, InterruptHandler_0x4e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x4f, InterruptHandler_0x4f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x4f, InterruptHandler_0x4f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x50, InterruptHandler_0x50, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x50, InterruptHandler_0x50, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x51, InterruptHandler_0x51, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x51, InterruptHandler_0x51, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x52, InterruptHandler_0x52, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x52, InterruptHandler_0x52, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x53, InterruptHandler_0x53, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x53, InterruptHandler_0x53, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x54, InterruptHandler_0x54, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x54, InterruptHandler_0x54, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x55, InterruptHandler_0x55, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x55, InterruptHandler_0x55, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x56, InterruptHandler_0x56, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x56, InterruptHandler_0x56, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x57, InterruptHandler_0x57, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x57, InterruptHandler_0x57, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x58, InterruptHandler_0x58, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x58, InterruptHandler_0x58, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x59, InterruptHandler_0x59, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x59, InterruptHandler_0x59, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5a, InterruptHandler_0x5a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5a, InterruptHandler_0x5a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5b, InterruptHandler_0x5b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5b, InterruptHandler_0x5b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5c, InterruptHandler_0x5c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5c, InterruptHandler_0x5c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5d, InterruptHandler_0x5d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5d, InterruptHandler_0x5d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5e, InterruptHandler_0x5e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5e, InterruptHandler_0x5e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x5f, InterruptHandler_0x5f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x5f, InterruptHandler_0x5f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x60, InterruptHandler_0x60, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x60, InterruptHandler_0x60, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x61, InterruptHandler_0x61, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x61, InterruptHandler_0x61, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x62, InterruptHandler_0x62, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x62, InterruptHandler_0x62, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x63, InterruptHandler_0x63, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x63, InterruptHandler_0x63, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x64, InterruptHandler_0x64, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x64, InterruptHandler_0x64, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x65, InterruptHandler_0x65, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x65, InterruptHandler_0x65, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x66, InterruptHandler_0x66, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x66, InterruptHandler_0x66, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x67, InterruptHandler_0x67, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x67, InterruptHandler_0x67, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x68, InterruptHandler_0x68, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x68, InterruptHandler_0x68, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x69, InterruptHandler_0x69, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x69, InterruptHandler_0x69, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6a, InterruptHandler_0x6a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6a, InterruptHandler_0x6a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6b, InterruptHandler_0x6b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6b, InterruptHandler_0x6b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6c, InterruptHandler_0x6c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6c, InterruptHandler_0x6c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6d, InterruptHandler_0x6d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6d, InterruptHandler_0x6d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6e, InterruptHandler_0x6e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6e, InterruptHandler_0x6e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x6f, InterruptHandler_0x6f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x6f, InterruptHandler_0x6f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x70, InterruptHandler_0x70, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x70, InterruptHandler_0x70, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x71, InterruptHandler_0x71, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x71, InterruptHandler_0x71, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x72, InterruptHandler_0x72, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x72, InterruptHandler_0x72, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x73, InterruptHandler_0x73, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x73, InterruptHandler_0x73, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x74, InterruptHandler_0x74, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x74, InterruptHandler_0x74, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x75, InterruptHandler_0x75, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x75, InterruptHandler_0x75, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x76, InterruptHandler_0x76, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x76, InterruptHandler_0x76, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x77, InterruptHandler_0x77, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x77, InterruptHandler_0x77, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x78, InterruptHandler_0x78, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x78, InterruptHandler_0x78, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x79, InterruptHandler_0x79, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x79, InterruptHandler_0x79, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7a, InterruptHandler_0x7a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7a, InterruptHandler_0x7a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7b, InterruptHandler_0x7b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7b, InterruptHandler_0x7b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7c, InterruptHandler_0x7c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7c, InterruptHandler_0x7c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7d, InterruptHandler_0x7d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7d, InterruptHandler_0x7d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7e, InterruptHandler_0x7e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7e, InterruptHandler_0x7e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x7f, InterruptHandler_0x7f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x7f, InterruptHandler_0x7f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x80, InterruptHandler_0x80, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x80, InterruptHandler_0x80, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x81, InterruptHandler_0x81, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x81, InterruptHandler_0x81, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x82, InterruptHandler_0x82, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x82, InterruptHandler_0x82, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x83, InterruptHandler_0x83, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x83, InterruptHandler_0x83, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x84, InterruptHandler_0x84, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x84, InterruptHandler_0x84, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x85, InterruptHandler_0x85, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x85, InterruptHandler_0x85, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x86, InterruptHandler_0x86, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x86, InterruptHandler_0x86, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x87, InterruptHandler_0x87, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x87, InterruptHandler_0x87, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x88, InterruptHandler_0x88, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x88, InterruptHandler_0x88, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x89, InterruptHandler_0x89, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x89, InterruptHandler_0x89, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8a, InterruptHandler_0x8a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8a, InterruptHandler_0x8a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8b, InterruptHandler_0x8b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8b, InterruptHandler_0x8b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8c, InterruptHandler_0x8c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8c, InterruptHandler_0x8c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8d, InterruptHandler_0x8d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8d, InterruptHandler_0x8d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8e, InterruptHandler_0x8e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8e, InterruptHandler_0x8e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x8f, InterruptHandler_0x8f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x8f, InterruptHandler_0x8f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x90, InterruptHandler_0x90, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x90, InterruptHandler_0x90, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x91, InterruptHandler_0x91, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x91, InterruptHandler_0x91, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x92, InterruptHandler_0x92, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x92, InterruptHandler_0x92, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x93, InterruptHandler_0x93, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x93, InterruptHandler_0x93, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x94, InterruptHandler_0x94, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x94, InterruptHandler_0x94, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x95, InterruptHandler_0x95, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x95, InterruptHandler_0x95, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x96, InterruptHandler_0x96, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x96, InterruptHandler_0x96, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x97, InterruptHandler_0x97, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x97, InterruptHandler_0x97, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x98, InterruptHandler_0x98, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x98, InterruptHandler_0x98, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x99, InterruptHandler_0x99, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x99, InterruptHandler_0x99, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9a, InterruptHandler_0x9a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9a, InterruptHandler_0x9a, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9b, InterruptHandler_0x9b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9b, InterruptHandler_0x9b, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9c, InterruptHandler_0x9c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9c, InterruptHandler_0x9c, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9d, InterruptHandler_0x9d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9d, InterruptHandler_0x9d, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9e, InterruptHandler_0x9e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9e, InterruptHandler_0x9e, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0x9f, InterruptHandler_0x9f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x9f, InterruptHandler_0x9f, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa0, InterruptHandler_0xa0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa0, InterruptHandler_0xa0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa1, InterruptHandler_0xa1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa1, InterruptHandler_0xa1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa2, InterruptHandler_0xa2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa2, InterruptHandler_0xa2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa3, InterruptHandler_0xa3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa3, InterruptHandler_0xa3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa4, InterruptHandler_0xa4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa4, InterruptHandler_0xa4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa5, InterruptHandler_0xa5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa5, InterruptHandler_0xa5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa6, InterruptHandler_0xa6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa6, InterruptHandler_0xa6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa7, InterruptHandler_0xa7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa7, InterruptHandler_0xa7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa8, InterruptHandler_0xa8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa8, InterruptHandler_0xa8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xa9, InterruptHandler_0xa9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xa9, InterruptHandler_0xa9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xaa, InterruptHandler_0xaa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xaa, InterruptHandler_0xaa, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xab, InterruptHandler_0xab, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xab, InterruptHandler_0xab, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xac, InterruptHandler_0xac, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xac, InterruptHandler_0xac, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xad, InterruptHandler_0xad, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xad, InterruptHandler_0xad, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xae, InterruptHandler_0xae, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xae, InterruptHandler_0xae, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xaf, InterruptHandler_0xaf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xaf, InterruptHandler_0xaf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb0, InterruptHandler_0xb0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb0, InterruptHandler_0xb0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb1, InterruptHandler_0xb1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb1, InterruptHandler_0xb1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb2, InterruptHandler_0xb2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb2, InterruptHandler_0xb2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb3, InterruptHandler_0xb3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb3, InterruptHandler_0xb3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb4, InterruptHandler_0xb4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb4, InterruptHandler_0xb4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb5, InterruptHandler_0xb5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb5, InterruptHandler_0xb5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb6, InterruptHandler_0xb6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb6, InterruptHandler_0xb6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb7, InterruptHandler_0xb7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb7, InterruptHandler_0xb7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb8, InterruptHandler_0xb8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb8, InterruptHandler_0xb8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xb9, InterruptHandler_0xb9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xb9, InterruptHandler_0xb9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xba, InterruptHandler_0xba, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xba, InterruptHandler_0xba, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbb, InterruptHandler_0xbb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xbb, InterruptHandler_0xbb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbc, InterruptHandler_0xbc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xbc, InterruptHandler_0xbc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbd, InterruptHandler_0xbd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xbd, InterruptHandler_0xbd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbe, InterruptHandler_0xbe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xbe, InterruptHandler_0xbe, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xbf, InterruptHandler_0xbf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xbf, InterruptHandler_0xbf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc0, InterruptHandler_0xc0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc0, InterruptHandler_0xc0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc1, InterruptHandler_0xc1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc1, InterruptHandler_0xc1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc2, InterruptHandler_0xc2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc2, InterruptHandler_0xc2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc3, InterruptHandler_0xc3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc3, InterruptHandler_0xc3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc4, InterruptHandler_0xc4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc4, InterruptHandler_0xc4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc5, InterruptHandler_0xc5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc5, InterruptHandler_0xc5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc6, InterruptHandler_0xc6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc6, InterruptHandler_0xc6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc7, InterruptHandler_0xc7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc7, InterruptHandler_0xc7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc8, InterruptHandler_0xc8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc8, InterruptHandler_0xc8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xc9, InterruptHandler_0xc9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xc9, InterruptHandler_0xc9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xca, InterruptHandler_0xca, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xca, InterruptHandler_0xca, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcb, InterruptHandler_0xcb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xcb, InterruptHandler_0xcb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcc, InterruptHandler_0xcc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xcc, InterruptHandler_0xcc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcd, InterruptHandler_0xcd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xcd, InterruptHandler_0xcd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xce, InterruptHandler_0xce, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xce, InterruptHandler_0xce, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xcf, InterruptHandler_0xcf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xcf, InterruptHandler_0xcf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd0, InterruptHandler_0xd0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd0, InterruptHandler_0xd0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd1, InterruptHandler_0xd1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd1, InterruptHandler_0xd1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd2, InterruptHandler_0xd2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd2, InterruptHandler_0xd2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd3, InterruptHandler_0xd3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd3, InterruptHandler_0xd3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd4, InterruptHandler_0xd4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd4, InterruptHandler_0xd4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd5, InterruptHandler_0xd5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd5, InterruptHandler_0xd5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd6, InterruptHandler_0xd6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd6, InterruptHandler_0xd6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd7, InterruptHandler_0xd7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd7, InterruptHandler_0xd7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd8, InterruptHandler_0xd8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd8, InterruptHandler_0xd8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xd9, InterruptHandler_0xd9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xd9, InterruptHandler_0xd9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xda, InterruptHandler_0xda, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xda, InterruptHandler_0xda, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdb, InterruptHandler_0xdb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xdb, InterruptHandler_0xdb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdc, InterruptHandler_0xdc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xdc, InterruptHandler_0xdc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdd, InterruptHandler_0xdd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xdd, InterruptHandler_0xdd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xde, InterruptHandler_0xde, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xde, InterruptHandler_0xde, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xdf, InterruptHandler_0xdf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xdf, InterruptHandler_0xdf, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe0, InterruptHandler_0xe0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe0, InterruptHandler_0xe0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe1, InterruptHandler_0xe1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe1, InterruptHandler_0xe1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe2, InterruptHandler_0xe2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe2, InterruptHandler_0xe2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe3, InterruptHandler_0xe3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe3, InterruptHandler_0xe3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe4, InterruptHandler_0xe4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe4, InterruptHandler_0xe4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe5, InterruptHandler_0xe5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe5, InterruptHandler_0xe5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe6, InterruptHandler_0xe6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe6, InterruptHandler_0xe6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe7, InterruptHandler_0xe7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe7, InterruptHandler_0xe7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe8, InterruptHandler_0xe8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe8, InterruptHandler_0xe8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xe9, InterruptHandler_0xe9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xe9, InterruptHandler_0xe9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xea, InterruptHandler_0xea, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xea, InterruptHandler_0xea, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xeb, InterruptHandler_0xeb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xeb, InterruptHandler_0xeb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xec, InterruptHandler_0xec, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xec, InterruptHandler_0xec, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xed, InterruptHandler_0xed, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xed, InterruptHandler_0xed, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xee, InterruptHandler_0xee, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xee, InterruptHandler_0xee, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xef, InterruptHandler_0xef, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xef, InterruptHandler_0xef, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf0, InterruptHandler_0xf0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf0, InterruptHandler_0xf0, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf1, InterruptHandler_0xf1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf1, InterruptHandler_0xf1, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf2, InterruptHandler_0xf2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf2, InterruptHandler_0xf2, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf3, InterruptHandler_0xf3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf3, InterruptHandler_0xf3, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf4, InterruptHandler_0xf4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf4, InterruptHandler_0xf4, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf5, InterruptHandler_0xf5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf5, InterruptHandler_0xf5, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf6, InterruptHandler_0xf6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf6, InterruptHandler_0xf6, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf7, InterruptHandler_0xf7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf7, InterruptHandler_0xf7, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf8, InterruptHandler_0xf8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf8, InterruptHandler_0xf8, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xf9, InterruptHandler_0xf9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xf9, InterruptHandler_0xf9, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfa, InterruptHandler_0xfa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xfa, InterruptHandler_0xfa, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfb, InterruptHandler_0xfb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xfb, InterruptHandler_0xfb, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfc, InterruptHandler_0xfc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xfc, InterruptHandler_0xfc, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfd, InterruptHandler_0xfd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xfd, InterruptHandler_0xfd, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xfe, InterruptHandler_0xfe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xfe, InterruptHandler_0xfe, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
SetEntry(0xff, InterruptHandler_0xff, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0xff, InterruptHandler_0xff, 0, TRAP_32BIT, RING0, true, GDT_KERNEL_CODE);
CPU::x64::lidt(&idtd); CPU::x64::lidt(&idtd);
} }
} }

View File

@ -13,8 +13,16 @@
; You should have received a copy of the GNU General Public License ; You should have received a copy of the GNU General Public License
; along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>. ; along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
; 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] [bits 16]
TRAMPOLINE_BASE equ 0x2000
extern StartCPU extern StartCPU
global _trampoline_start global _trampoline_start
@ -26,11 +34,11 @@ _trampoline_start:
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
mov ss, ax mov ss, ax
o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_BASE] o32 lgdt [ProtectedMode_gdtr - _trampoline_start + TRAMPOLINE_START]
mov eax, cr0 mov eax, cr0
or al, 0x1 or al, 0x1
mov cr0, eax mov cr0, eax
jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_BASE) jmp 0x8:(Trampoline32 - _trampoline_start + TRAMPOLINE_START)
[bits 32] [bits 32]
section .text section .text
@ -39,7 +47,7 @@ Trampoline32:
mov ds, bx mov ds, bx
mov es, bx mov es, bx
mov ss, bx mov ss, bx
mov eax, dword [0x500] mov eax, dword [TRAMPOLINE_PAGE_TABLE]
mov cr3, eax mov cr3, eax
mov eax, cr4 mov eax, cr4
or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5). or eax, 1 << 5 ; Set the PAE-bit, which is the 6th bit (bit 5).
@ -52,8 +60,8 @@ Trampoline32:
mov eax, cr0 mov eax, cr0
or eax, 1 << 31 or eax, 1 << 31
mov cr0, eax mov cr0, eax
lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_BASE] lgdt [LongMode_gdtr - _trampoline_start + TRAMPOLINE_START]
jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_BASE) jmp 0x8:(Trampoline64 - _trampoline_start + TRAMPOLINE_START)
[bits 64] [bits 64]
Trampoline64: Trampoline64:
@ -64,9 +72,9 @@ Trampoline64:
mov ax, 0x0 mov ax, 0x0
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
lgdt [0x580] lgdt [TRAMPOLINE_GDT]
lidt [0x590] lidt [TRAMPOLINE_IDT]
mov rsp, [0x570] mov rsp, [TRAMPOLINE_STACK]
mov rbp, 0x0 ; Terminate stack traces here. mov rbp, 0x0 ; Terminate stack traces here.
; Reset RFLAGS. ; Reset RFLAGS.
push 0x0 push 0x0
@ -91,7 +99,7 @@ vcode64:
align 16 align 16
LongMode_gdtr: LongMode_gdtr:
dw LongModeGDTEnd - LongModeGDTStart - 1 dw LongModeGDTEnd - LongModeGDTStart - 1
dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_BASE dq LongModeGDTStart - _trampoline_start + TRAMPOLINE_START
align 16 align 16
LongModeGDTStart: LongModeGDTStart:
@ -103,7 +111,7 @@ LongModeGDTEnd:
align 16 align 16
ProtectedMode_gdtr: ProtectedMode_gdtr:
dw ProtectedModeGDTEnd - ProtectedModeGDTStart - 1 dw ProtectedModeGDTEnd - ProtectedModeGDTStart - 1
dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_BASE dd ProtectedModeGDTStart - _trampoline_start + TRAMPOLINE_START
align 16 align 16
ProtectedModeGDTStart: ProtectedModeGDTStart:

View File

@ -17,8 +17,9 @@
#include <smp.hpp> #include <smp.hpp>
#include <ints.hpp>
#include <memory.hpp> #include <memory.hpp>
#include <atomic.hpp>
#include <ints.hpp>
#include <assert.h> #include <assert.h>
#include <cpu.hpp> #include <cpu.hpp>
@ -28,6 +29,7 @@
extern "C" uint64_t _trampoline_start, _trampoline_end; extern "C" uint64_t _trampoline_start, _trampoline_end;
/* https://wiki.osdev.org/Memory_Map_(x86) */
enum SMPTrampolineAddress enum SMPTrampolineAddress
{ {
PAGE_TABLE = 0x500, PAGE_TABLE = 0x500,
@ -39,7 +41,7 @@ enum SMPTrampolineAddress
TRAMPOLINE_START = 0x2000 TRAMPOLINE_START = 0x2000
}; };
volatile bool CPUEnabled = false; Atomic<bool> CPUEnabled = false;
#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
static __aligned(PAGE_SIZE) CPUData CPUs[MAX_CPU] = {0}; static __aligned(PAGE_SIZE) CPUData CPUs[MAX_CPU] = {0};
@ -73,10 +75,11 @@ extern "C" void StartCPU()
Interrupts::Initialize(CoreID); Interrupts::Initialize(CoreID);
Interrupts::Enable(CoreID); Interrupts::Enable(CoreID);
Interrupts::InitializeTimer(CoreID); Interrupts::InitializeTimer(CoreID);
asmv("mov %0, %%rsp" ::"r"((&CPUs[CoreID])->Stack));
CPU::Interrupts(CPU::Enable); CPU::Interrupts(CPU::Enable);
KPrint("\e058C19CPU \e8888FF%d \e058C19is online", CoreID); KPrint("\e058C19CPU \e8888FF%d \e058C19is online", CoreID);
CPUEnabled = true; CPUEnabled.Store(true, MemoryOrder::Release);
CPU::Halt(true); CPU::Halt(true);
} }
@ -95,42 +98,43 @@ namespace SMP
CPUCores = Cores; 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++) for (int i = 0; i < Cores; i++)
{ {
debug("Initializing CPU %d", i); debug("Initializing CPU %d", i);
if ((((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24) != ((ACPI::MADT *)madt)->lapic[i]->ACPIProcessorId) 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; VPOKE(int, CORE) = i;
asmv("sgdt [0x580]\n" ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24));
"sidt [0x590]\n"); ((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500);
VPOKE(uint64_t, START_ADDR) = (uintptr_t)&StartCPU;
((APIC::APIC *)Interrupts::apic[0])->SendInitIPI(((ACPI::MADT *)madt)->lapic[i]->APICId); ((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); ((APIC::APIC *)Interrupts::apic[0])->SendStartupIPI(((ACPI::MADT *)madt)->lapic[i]->APICId, TRAMPOLINE_START);
while (!CPUEnabled) while (!CPUEnabled.Load(MemoryOrder::Acquire))
CPU::Pause(); CPU::Pause();
CPUEnabled.Store(false, MemoryOrder::Release);
trace("CPU %d loaded.", ((ACPI::MADT *)madt)->lapic[i]->APICId); trace("CPU %d loaded.", ((ACPI::MADT *)madt)->lapic[i]->APICId);
KernelAllocator.FreePages((void *)*reinterpret_cast<long *>(STACK), TO_PAGES(STACK_SIZE));
CPUEnabled = false;
} }
else else
KPrint("\e058C19CPU \e8888FF%d \e058C19is the BSP", ((ACPI::MADT *)madt)->lapic[i]->APICId); 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);
} }
} }

View File

@ -32,42 +32,42 @@ namespace GlobalDescriptorTable
/** @brief Access bit. /** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed. * @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. /** @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 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. * @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. /** @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 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. * @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. /** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors. * @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors. * @details This bit must be 0 for data-segment and system descriptors.
*/ */
uint8_t E : 1; uint64_t E : 1;
/** @brief Descriptor type. /** @brief Descriptor type.
* @details This bit must be 0 for system descriptors. * @details This bit must be 0 for system descriptors.
* @details This bit must be 1 for code or data segment descriptor. * @details This bit must be 1 for code or data segment descriptor.
*/ */
uint8_t S : 1; uint64_t S : 1;
/** @brief Descriptor privilege level. /** @brief Descriptor privilege level.
* @details This field determines the privilege level of the segment. * @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode. * @details 0 = kernel mode, 3 = user mode.
*/ */
uint8_t DPL : 2; uint64_t DPL : 2;
/** @brief Present bit. /** @brief Present bit.
* @details This bit must be 1 for all valid descriptors. * @details This bit must be 1 for all valid descriptors.
*/ */
uint8_t P : 1; uint64_t P : 1;
} __packed; } __packed;
uint8_t Raw; uint8_t Raw;
}; };
@ -78,13 +78,13 @@ namespace GlobalDescriptorTable
struct struct
{ {
/** @brief Unknown. */ /** @brief Unknown. */
uint8_t Unknown : 5; uint64_t Unknown : 5;
/** @brief Long mode. /** @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 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. * @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; } __packed;
uint8_t Raw; uint8_t Raw;
}; };
@ -105,7 +105,7 @@ namespace GlobalDescriptorTable
typedef struct _TaskStateSegment typedef struct _TaskStateSegment
{ {
uint32_t Reserved0 __aligned(0x10); uint32_t Reserved0 __aligned(16);
uint64_t StackPointer[3]; uint64_t StackPointer[3];
uint64_t Reserved1; uint64_t Reserved1;
uint64_t InterruptStackTable[7]; uint64_t InterruptStackTable[7];

View File

@ -22,19 +22,22 @@
namespace InterruptDescriptorTable namespace InterruptDescriptorTable
{ {
typedef enum _InterruptDescriptorTableFlags typedef enum _InterruptGateType
{ {
FlagGate_TASK = 0b101, TASK = 0b101,
FlagGate_16BIT_INT = 0b110, INT_16BIT = 0b110,
FlagGate_16BIT_TRAP = 0b111, TRAP_16BIT = 0b111,
FlagGate_32BIT_INT = 0b1110, INT_32BIT = 0b1110,
FlagGate_32BIT_TRAP = 0b1111, TRAP_32BIT = 0b1111,
FlagGate_RING0 = 0b0, } InterruptGateType;
FlagGate_RING1 = 0b1,
FlagGate_RING2 = 0b10, typedef enum _InterruptRingType
FlagGate_RING3 = 0b11, {
FlagGate_PRESENT = 0b1, // Not sure if this is correct. RING0 = 0b0,
} InterruptDescriptorTableFlags; RING1 = 0b1,
RING2 = 0b10,
RING3 = 0b11,
} InterruptRingType;
typedef struct _InterruptDescriptorTableEntry typedef struct _InterruptDescriptorTableEntry
{ {
@ -42,7 +45,7 @@ namespace InterruptDescriptorTable
uint64_t SegmentSelector : 16; uint64_t SegmentSelector : 16;
uint64_t InterruptStackTable : 3; uint64_t InterruptStackTable : 3;
uint64_t Reserved1 : 5; uint64_t Reserved1 : 5;
InterruptDescriptorTableFlags Flags : 4; uint64_t Flags : 4;
uint64_t Reserved2 : 1; uint64_t Reserved2 : 1;
uint64_t Ring : 2; uint64_t Ring : 2;
uint64_t Present : 1; uint64_t Present : 1;
@ -56,7 +59,14 @@ namespace InterruptDescriptorTable
InterruptDescriptorTableEntry *Entries; InterruptDescriptorTableEntry *Entries;
} __packed InterruptDescriptorTableDescriptor; } __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); void Init(int Core);
} }

View File

@ -199,7 +199,6 @@ void ProcessMB2(unsigned long Info)
mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height;
mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch;
mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp;
mb2binfo.Framebuffer[fb_count].MemoryModel = fb->common.framebuffer_type;
switch (fb->common.framebuffer_type) switch (fb->common.framebuffer_type)
{ {
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:

View File

@ -105,7 +105,7 @@ namespace GlobalDescriptorTable
typedef struct _TaskStateSegment typedef struct _TaskStateSegment
{ {
uint32_t Reserved0 __aligned(0x10); uint32_t Reserved0 __aligned(16);
uint64_t StackPointer[3]; uint64_t StackPointer[3];
uint64_t Reserved1; uint64_t Reserved1;
uint64_t InterruptStackTable[7]; uint64_t InterruptStackTable[7];

View File

@ -30,19 +30,21 @@ namespace CPU
char *Vendor() char *Vendor()
{ {
static char Vendor[13]; static char Vendor[13] = {0};
if (Vendor[0] != 0)
return Vendor;
#if defined(a64) #if defined(a64)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x64::cpuid(0x0, &eax, &ebx, &ecx, &edx); x64::cpuid(0x0, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Vendor + 0, &ebx, 4); memcpy(Vendor + 0, &ebx, 4);
memcpy_unsafe(Vendor + 4, &edx, 4); memcpy(Vendor + 4, &edx, 4);
memcpy_unsafe(Vendor + 8, &ecx, 4); memcpy(Vendor + 8, &ecx, 4);
#elif defined(a32) #elif defined(a32)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x32::cpuid(0x0, &eax, &ebx, &ecx, &edx); x32::cpuid(0x0, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Vendor + 0, &ebx, 4); memcpy(Vendor + 0, &ebx, 4);
memcpy_unsafe(Vendor + 4, &edx, 4); memcpy(Vendor + 4, &edx, 4);
memcpy_unsafe(Vendor + 8, &ecx, 4); memcpy(Vendor + 8, &ecx, 4);
#elif defined(aa64) #elif defined(aa64)
asmv("mrs %0, MIDR_EL1" asmv("mrs %0, MIDR_EL1"
: "=r"(Vendor[0])); : "=r"(Vendor[0]));
@ -52,41 +54,43 @@ namespace CPU
char *Name() char *Name()
{ {
static char Name[49]; static char Name[49] = {0};
if (Name[0] != 0)
return Name;
#if defined(a64) #if defined(a64)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x64::cpuid(0x80000002, &eax, &ebx, &ecx, &edx); x64::cpuid(0x80000002, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 0, &eax, 4); memcpy(Name + 0, &eax, 4);
memcpy_unsafe(Name + 4, &ebx, 4); memcpy(Name + 4, &ebx, 4);
memcpy_unsafe(Name + 8, &ecx, 4); memcpy(Name + 8, &ecx, 4);
memcpy_unsafe(Name + 12, &edx, 4); memcpy(Name + 12, &edx, 4);
x64::cpuid(0x80000003, &eax, &ebx, &ecx, &edx); x64::cpuid(0x80000003, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 16, &eax, 4); memcpy(Name + 16, &eax, 4);
memcpy_unsafe(Name + 20, &ebx, 4); memcpy(Name + 20, &ebx, 4);
memcpy_unsafe(Name + 24, &ecx, 4); memcpy(Name + 24, &ecx, 4);
memcpy_unsafe(Name + 28, &edx, 4); memcpy(Name + 28, &edx, 4);
x64::cpuid(0x80000004, &eax, &ebx, &ecx, &edx); x64::cpuid(0x80000004, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 32, &eax, 4); memcpy(Name + 32, &eax, 4);
memcpy_unsafe(Name + 36, &ebx, 4); memcpy(Name + 36, &ebx, 4);
memcpy_unsafe(Name + 40, &ecx, 4); memcpy(Name + 40, &ecx, 4);
memcpy_unsafe(Name + 44, &edx, 4); memcpy(Name + 44, &edx, 4);
#elif defined(a32) #elif defined(a32)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x32::cpuid(0x80000002, &eax, &ebx, &ecx, &edx); x32::cpuid(0x80000002, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 0, &eax, 4); memcpy(Name + 0, &eax, 4);
memcpy_unsafe(Name + 4, &ebx, 4); memcpy(Name + 4, &ebx, 4);
memcpy_unsafe(Name + 8, &ecx, 4); memcpy(Name + 8, &ecx, 4);
memcpy_unsafe(Name + 12, &edx, 4); memcpy(Name + 12, &edx, 4);
x32::cpuid(0x80000003, &eax, &ebx, &ecx, &edx); x32::cpuid(0x80000003, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 16, &eax, 4); memcpy(Name + 16, &eax, 4);
memcpy_unsafe(Name + 20, &ebx, 4); memcpy(Name + 20, &ebx, 4);
memcpy_unsafe(Name + 24, &ecx, 4); memcpy(Name + 24, &ecx, 4);
memcpy_unsafe(Name + 28, &edx, 4); memcpy(Name + 28, &edx, 4);
x32::cpuid(0x80000004, &eax, &ebx, &ecx, &edx); x32::cpuid(0x80000004, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Name + 32, &eax, 4); memcpy(Name + 32, &eax, 4);
memcpy_unsafe(Name + 36, &ebx, 4); memcpy(Name + 36, &ebx, 4);
memcpy_unsafe(Name + 40, &ecx, 4); memcpy(Name + 40, &ecx, 4);
memcpy_unsafe(Name + 44, &edx, 4); memcpy(Name + 44, &edx, 4);
#elif defined(aa64) #elif defined(aa64)
asmv("mrs %0, MIDR_EL1" asmv("mrs %0, MIDR_EL1"
: "=r"(Name[0])); : "=r"(Name[0]));
@ -96,19 +100,21 @@ namespace CPU
char *Hypervisor() char *Hypervisor()
{ {
static char Hypervisor[13]; static char Hypervisor[13] = {0};
if (Hypervisor[0] != 0)
return Hypervisor;
#if defined(a64) #if defined(a64)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Hypervisor + 0, &ebx, 4); memcpy(Hypervisor + 0, &ebx, 4);
memcpy_unsafe(Hypervisor + 4, &ecx, 4); memcpy(Hypervisor + 4, &ecx, 4);
memcpy_unsafe(Hypervisor + 8, &edx, 4); memcpy(Hypervisor + 8, &edx, 4);
#elif defined(a32) #elif defined(a32)
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx); x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
memcpy_unsafe(Hypervisor + 0, &ebx, 4); memcpy(Hypervisor + 0, &ebx, 4);
memcpy_unsafe(Hypervisor + 4, &ecx, 4); memcpy(Hypervisor + 4, &ecx, 4);
memcpy_unsafe(Hypervisor + 8, &edx, 4); memcpy(Hypervisor + 8, &edx, 4);
#elif defined(aa64) #elif defined(aa64)
asmv("mrs %0, MIDR_EL1" asmv("mrs %0, MIDR_EL1"
: "=r"(Hypervisor[0])); : "=r"(Hypervisor[0]));
@ -141,7 +147,7 @@ namespace CPU
} }
case Enable: case Enable:
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("sti"); asmv("sti");
#elif defined(aa64) #elif defined(aa64)
asmv("msr daifclr, #2"); asmv("msr daifclr, #2");
@ -150,7 +156,7 @@ namespace CPU
} }
case Disable: case Disable:
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cli"); asmv("cli");
#elif defined(aa64) #elif defined(aa64)
asmv("msr daifset, #2"); asmv("msr daifset, #2");
@ -195,30 +201,41 @@ namespace CPU
void InitializeFeatures(long Core) void InitializeFeatures(long Core)
{ {
#if defined(a64)
bool PGESupport = false; bool PGESupport = false;
bool SSESupport = false; bool SSESupport = false;
#if defined(a64) bool UMIPSupport = false;
bool SMEPSupport = false;
bool SMAPSupport = false;
static int BSP = 0; static int BSP = 0;
x64::CR0 cr0 = x64::readcr0(); x64::CR0 cr0 = x64::readcr0();
x64::CR4 cr4 = x64::readcr4(); x64::CR4 cr4 = x64::readcr4();
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{ {
CPU::x86::AMD::CPUID0x00000001 cpuid; CPU::x86::AMD::CPUID0x00000001 cpuid1;
cpuid.Get(); CPU::x86::AMD::CPUID0x00000007 cpuid7;
if (cpuid.EDX.PGE) cpuid1.Get();
PGESupport = true; cpuid7.Get();
if (cpuid.EDX.SSE)
SSESupport = true; 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) else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
{ {
CPU::x86::Intel::CPUID0x00000001 cpuid; CPU::x86::Intel::CPUID0x00000001 cpuid1;
cpuid.Get(); CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0;
if (cpuid.EDX.PGE) cpuid1.Get();
PGESupport = true; cpuid7_0.Get();
if (cpuid.EDX.SSE) PGESupport = cpuid1.EDX.PGE;
SSESupport = true; SSESupport = cpuid1.EDX.SSE;
SMEPSupport = cpuid7_0.EBX.SMEP;
SMAPSupport = cpuid7_0.EBX.SMAP;
UMIPSupport = cpuid7_0.ECX.UMIP;
} }
if (Config.SIMD == false) if (Config.SIMD == false)
@ -251,7 +268,7 @@ namespace CPU
cr4.OSXMMEXCPT = 1; cr4.OSXMMEXCPT = 1;
CPUData *CoreData = GetCPU(Core); 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)))); memset(CoreData->Data.FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState))));
CoreData->Data.FPU->mxcsr = 0b0001111110000000; CoreData->Data.FPU->mxcsr = 0b0001111110000000;
CoreData->Data.FPU->mxcsrmask = 0b1111111110111111; CoreData->Data.FPU->mxcsrmask = 0b1111111110111111;
@ -261,47 +278,40 @@ namespace CPU
SSEEnableAfter = true; SSEEnableAfter = true;
} }
if (!BSP)
KPrint("Enabling CPU cache.");
cr0.NW = 0; cr0.NW = 0;
cr0.CD = 0; cr0.CD = 0;
cr0.WP = 1; cr0.WP = 1;
x64::writecr0(cr0); x64::writecr0(cr0);
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
{
// FIXME: I don't think this is reporting correctly. This has to be fixed asap. // FIXME: I don't think this is reporting correctly. This has to be fixed asap.
debug("Enabling UMIP, SMEP & SMAP support..."); debug("Enabling UMIP, SMEP & SMAP support...");
uint32_t eax, ebx, ecx, edx; if (UMIPSupport)
x64::cpuid(0x1, &eax, &ebx, &ecx, &edx);
if (edx & (1 << 2)) // https://en.wikipedia.org/wiki/Control_register
{ {
if (!BSP) if (!BSP)
KPrint("UMIP is supported."); KPrint("UMIP is supported.");
debug("UMIP is supported."); debug("UMIP is supported.");
// cr4.UMIP = 1; // 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 (SMEPSupport)
{ {
if (!BSP) if (!BSP)
KPrint("SMEP is supported."); KPrint("SMEP is supported.");
debug("SMEP is supported."); debug("SMEP is supported.");
// cr4.SMEP = 1; // cr4.SMEP = 1;
} }
if (edx & (1 << 20)) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
if (SMAPSupport)
{ {
if (!BSP) if (!BSP)
KPrint("SMAP is supported."); KPrint("SMAP is supported.");
debug("SMAP is supported."); debug("SMAP is supported.");
// cr4.SMAP = 1; // 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.");
} }
else else
{ {
@ -313,6 +323,11 @@ namespace CPU
KPrint("QEMU (TCG) detected. Not using UMIP, SMEP & SMAP"); KPrint("QEMU (TCG) detected. Not using UMIP, SMEP & SMAP");
} }
} }
debug("Writing CR4...");
x64::writecr4(cr4);
debug("Wrote CR4.");
debug("Enabling PAT support..."); debug("Enabling PAT support...");
x64::wrmsr(x64::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16)); x64::wrmsr(x64::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16));
if (!BSP++) if (!BSP++)
@ -352,7 +367,7 @@ namespace CPU
// return SIMD_SSE; // return SIMD_SSE;
#if defined(a64) || defined(a32) #if defined(a86)
static uint64_t SIMDType = SIMD_NONE; static uint64_t SIMDType = SIMD_NONE;
if (likely(SIMDType != SIMD_NONE)) if (likely(SIMDType != SIMD_NONE))
@ -434,7 +449,7 @@ namespace CPU
if (unlikely(!SSEEnabled)) if (unlikely(!SSEEnabled))
return false; return false;
#if defined(a64) || defined(a32) #if defined(a86)
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{ {
CPU::x86::AMD::CPUID0x00000001 cpuid; CPU::x86::AMD::CPUID0x00000001 cpuid;

View File

@ -375,7 +375,7 @@ namespace CrashHandler
int tmpidx = SBIdx; int tmpidx = SBIdx;
SBIdx = atoi(arg); SBIdx = atoi(arg);
Display->SetBuffer(SBIdx); Display->SetBuffer(SBIdx);
#if defined(a64) || defined(a32) #if defined(a86)
for (int i = 0; i < 5000000; i++) for (int i = 0; i < 5000000; i++)
inb(0x80); inb(0x80);
#endif // a64 || a32 #endif // a64 || a32
@ -415,7 +415,7 @@ namespace CrashHandler
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i])); EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i]));
else else
EHPrint("\eFF4CA9Outside Kernel"); EHPrint("\eFF4CA9Outside Kernel");
#if defined(a64) || defined(a32) #if defined(a86)
for (int i = 0; i < 20000; i++) for (int i = 0; i < 20000; i++)
inb(0x80); inb(0x80);
#endif // a64 || a32 #endif // a64 || a32
@ -624,7 +624,7 @@ namespace CrashHandler
} }
else else
{ {
#if defined(a64) || defined(a32) #if defined(a86)
GlobalDescriptorTable::TaskStateSegment tss = GlobalDescriptorTable::tss[TSSIndex]; GlobalDescriptorTable::TaskStateSegment tss = GlobalDescriptorTable::tss[TSSIndex];
EHPrint("\eFAFAFAStack Pointer 0: \eAABB22%#lx\n", tss.StackPointer[0]); EHPrint("\eFAFAFAStack Pointer 0: \eAABB22%#lx\n", tss.StackPointer[0]);
EHPrint("\eFAFAFAStack Pointer 1: \eAABB22%#lx\n", tss.StackPointer[1]); EHPrint("\eFAFAFAStack Pointer 1: \eAABB22%#lx\n", tss.StackPointer[1]);
@ -779,7 +779,7 @@ namespace CrashHandler
SafeFunction void StopAllCores() SafeFunction void StopAllCores()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
/* FIXME: Can't send IPIs to other cores /* FIXME: Can't send IPIs to other cores
* because it causes another exception on * because it causes another exception on
* the other cores. * the other cores.

View File

@ -96,7 +96,7 @@ namespace CrashHandler
{ {
CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */ CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
{ {
#if defined(a64) || defined(a32) #if defined(a86)
while (inb(0x64) & 0x1) while (inb(0x64) & 0x1)
inb(0x60); inb(0x60);
@ -109,7 +109,7 @@ namespace CrashHandler
outb(0x21, 0xFD); outb(0x21, 0xFD);
outb(0xA1, 0xFF); outb(0xA1, 0xFF);
#endif // defined(a64) || defined(a32) #endif // defined(a86)
CPU::Interrupts(CPU::Enable); // Just to be sure. CPU::Interrupts(CPU::Enable); // Just to be sure.
} }
@ -130,7 +130,7 @@ namespace CrashHandler
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame)
#endif #endif
{ {
#if defined(a64) || defined(a32) #if defined(a86)
UNUSED(Frame); UNUSED(Frame);
uint8_t scanCode = inb(0x60); uint8_t scanCode = inb(0x60);
if (scanCode == KEY_D_TAB || if (scanCode == KEY_D_TAB ||
@ -184,7 +184,7 @@ namespace CrashHandler
SafeFunction void HookKeyboard() SafeFunction void HookKeyboard()
{ {
CrashKeyboardDriver kbd; // We don't want to allocate memory. CrashKeyboardDriver kbd; // We don't want to allocate memory.
#if defined(a64) || defined(a32) #if defined(a86)
asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;"); asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;");
#elif defined(aa64) #elif defined(aa64)
asmv("KeyboardHookLoop: nop; b KeyboardHookLoop;"); asmv("KeyboardHookLoop: nop; b KeyboardHookLoop;");

View File

@ -87,7 +87,7 @@ namespace CrashHandler
#elif defined(aa64) #elif defined(aa64)
#endif #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("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); 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) #elif defined(aa64)
#endif #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", 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.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", data.dr7.LocalDR2 ? "True " : "False", data.dr7.GlobalDR2 ? "True " : "False", data.dr7.LocalDR3 ? "True " : "False", data.dr7.GlobalDR3 ? "True " : "False",

View File

@ -99,7 +99,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
#elif defined(aa64) #elif defined(aa64)
#endif #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=%#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", 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", error("CR3: PWT:%s PCD:%s PDBR:%#llx",
cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR);
#endif // defined(a64) || defined(a32) #endif // defined(a86)
#if defined(a64) #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", 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); cr4.Reserved0, cr4.Reserved1);
#endif #endif
#if defined(a64) || defined(a32) #if defined(a86)
error("CR8: TPL:%d", cr8.TPL); error("CR8: TPL:%d", cr8.TPL);
#endif // defined(a64) || defined(a32) #endif // defined(a86)
#if defined(a64) #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", 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) #elif defined(aa64)
#endif #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", 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.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", efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False",

View File

@ -28,21 +28,17 @@ namespace Disk
{ {
void Manager::FetchDisks(unsigned long DriverUID) void Manager::FetchDisks(unsigned long DriverUID)
{ {
KernelCallback *callback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback))); KernelCallback callback{};
memset(callback, 0, sizeof(KernelCallback)); callback.Reason = FetchReason;
callback->Reason = FetchReason; DriverManager->IOCB(DriverUID, (void *)&callback);
DriverManager->IOCB(DriverUID, (void *)callback); this->AvailablePorts = callback.DiskCallback.Fetch.Ports;
this->AvailablePorts = callback->DiskCallback.Fetch.Ports; this->BytesPerSector = callback.DiskCallback.Fetch.BytesPerSector;
this->BytesPerSector = callback->DiskCallback.Fetch.BytesPerSector;
debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector); debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector);
if (this->AvailablePorts <= 0) if (this->AvailablePorts <= 0)
{
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback)));
return; 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++) for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++)
{ {
@ -53,16 +49,15 @@ namespace Disk
drive->MechanicalDisk = true; drive->MechanicalDisk = true;
memset(RWBuffer, 0, this->BytesPerSector); memset(RWBuffer, 0, this->BytesPerSector);
memset(callback, 0, sizeof(KernelCallback)); callback.Reason = ReceiveReason;
callback->Reason = ReceiveReason; callback.DiskCallback.RW = {
callback->DiskCallback.RW = {
.Sector = 0, .Sector = 0,
.SectorCount = 2, .SectorCount = 2,
.Port = ItrPort, .Port = ItrPort,
.Buffer = RWBuffer, .Buffer = RWBuffer,
.Write = false, .Write = false,
}; };
DriverManager->IOCB(DriverUID, (void *)callback); DriverManager->IOCB(DriverUID, (void *)&callback);
memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable)); memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable));
/* /*
@ -77,16 +72,15 @@ namespace Disk
for (uint32_t Block = 0; Block < Sectors; Block++) for (uint32_t Block = 0; Block < Sectors; Block++)
{ {
memset(RWBuffer, 0, this->BytesPerSector); memset(RWBuffer, 0, this->BytesPerSector);
memset(callback, 0, sizeof(KernelCallback)); callback.Reason = ReceiveReason;
callback->Reason = ReceiveReason; callback.DiskCallback.RW = {
callback->DiskCallback.RW = {
.Sector = 2 + Block, .Sector = 2 + Block,
.SectorCount = 1, .SectorCount = 1,
.Port = ItrPort, .Port = ItrPort,
.Buffer = RWBuffer, .Buffer = RWBuffer,
.Write = false, .Write = false,
}; };
DriverManager->IOCB(DriverUID, (void *)callback); DriverManager->IOCB(DriverUID, (void *)&callback);
for (uint32_t e = 0; e < Entries; e++) for (uint32_t e = 0; e < Entries; e++)
{ {
@ -161,7 +155,7 @@ namespace Disk
drives.push_back(drive); drives.push_back(drive);
} }
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback))); KernelAllocator.FreePages(RWBuffer, TO_PAGES(this->BytesPerSector + 1));
} }
Manager::Manager() Manager::Manager()

View File

@ -85,6 +85,7 @@ namespace Driver
{ {
if (!drv.InterruptHook[j]) if (!drv.InterruptHook[j])
break; break;
debug("Interrupt hook %#lx", drv.InterruptHook[j]);
delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr; delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr;
} }
if (drv.MemTrk) if (drv.MemTrk)
@ -106,11 +107,12 @@ namespace Driver
debug("Stopping and unloading driver %ld [%#lx]", drv.DriverUID, drv.Address); debug("Stopping and unloading driver %ld [%#lx]", drv.DriverUID, drv.Address);
this->IOCB(drv.DriverUID, (void *)&callback); 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; 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; delete drv.MemTrk, drv.MemTrk = nullptr;
Drivers.remove(i); Drivers.remove(i);
@ -141,6 +143,7 @@ namespace Driver
((KernelAPI *)KAPIAddress)->Info.Offset = (unsigned long)fex; ((KernelAPI *)KAPIAddress)->Info.Offset = (unsigned long)fex;
((KernelAPI *)KAPIAddress)->Info.DriverUID = DriverUIDs++; ((KernelAPI *)KAPIAddress)->Info.DriverUID = DriverUIDs++;
((KernelAPI *)KAPIAddress)->Info.KernelDebug = DebuggerIsAttached;
#ifdef DEBUG #ifdef DEBUG
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); 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 */ SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */
if (!Handle.InterruptCallback) if (!Handle.InterruptCallback)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
uint64_t IntNum = Frame->InterruptNumber - 32; uint64_t IntNum = Frame->InterruptNumber - 32;
#elif defined(aa64) #elif defined(aa64)
uint64_t IntNum = Frame->InterruptNumber; uint64_t IntNum = Frame->InterruptNumber;
@ -332,7 +335,7 @@ namespace Driver
DriverInterruptHook::DriverInterruptHook(int Interrupt, DriverFile Handle) : Interrupts::Handler(Interrupt) DriverInterruptHook::DriverInterruptHook(int Interrupt, DriverFile Handle) : Interrupts::Handler(Interrupt)
{ {
this->Handle = Handle; this->Handle = Handle;
#if defined(a64) || defined(a32) #if defined(a86)
trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID);
#elif defined(aa64) #elif defined(aa64)
trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID);

View File

@ -46,7 +46,7 @@ void DriverDisplayPrint(char *String)
void *RequestPage(unsigned long Size) 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)); drvdbg("Allocated %ld pages (%#lx-%#lx)", Size, (unsigned long)ret, (unsigned long)ret + FROM_PAGES(Size));
return ret; return ret;
} }
@ -54,7 +54,7 @@ void *RequestPage(unsigned long Size)
void FreePage(void *Page, 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)); 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) void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
@ -164,6 +164,7 @@ KernelAPI KernelAPITemplate = {
.Info = { .Info = {
.Offset = 0, .Offset = 0,
.DriverUID = 0, .DriverUID = 0,
.KernelDebug = false,
}, },
.Memory = { .Memory = {
.PageSize = PAGE_SIZE, .PageSize = PAGE_SIZE,

View File

@ -59,7 +59,7 @@ namespace Driver
DriverCode Driver::BindInputInput(Memory::MemMgr *mem, void *fex) DriverCode Driver::BindInputInput(Memory::MemMgr *mem, void *fex)
{ {
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); 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); fixme("Input driver: %s", fexExtended->Driver.Name);
KCallback->RawPtr = nullptr; KCallback->RawPtr = nullptr;
@ -100,7 +100,7 @@ namespace Driver
UNUSED(DrvExtHdr); UNUSED(DrvExtHdr);
UNUSED(IsElf); UNUSED(IsElf);
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); 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); memcpy(fex, (void *)DriverAddress, Size);
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); 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]); result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
kfree(result); kfree(result);
#endif #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) if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
{ {

View File

@ -455,7 +455,7 @@ namespace Driver
{ {
UNUSED(IsElf); UNUSED(IsElf);
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); 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); memcpy(fex, (void *)DriverAddress, Size);
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); 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]); result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
kfree(result); kfree(result);
#endif #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) if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
{ {

View File

@ -576,7 +576,7 @@ namespace Driver
{ {
debug("[%ld] VendorID: %#x; DeviceID: %#x", devices.size(), PCIDevice->VendorID, PCIDevice->DeviceID); debug("[%ld] VendorID: %#x; DeviceID: %#x", devices.size(), PCIDevice->VendorID, PCIDevice->DeviceID);
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory); 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); memcpy(fex, (void *)DriverAddress, Size);
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); 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]); result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
kfree(result); kfree(result);
#endif #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) if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
{ {

View File

@ -67,16 +67,14 @@ namespace Interrupts
CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData); CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
CoreData->ID = Core; CoreData->ID = Core;
CoreData->IsActive = true; CoreData->IsActive = true;
CoreData->SystemCallStack = (uint8_t *)((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)) + STACK_SIZE; CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
if (CoreData->Checksum != CPU_DATA_CHECKSUM) if (CoreData->Checksum != CPU_DATA_CHECKSUM)
{ {
KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM); KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
CPU::Stop(); CPU::Stop();
} }
debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE); 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(); InitializeSystemCalls();
#elif defined(a32) #elif defined(a32)
warn("i386 is not supported yet"); warn("i386 is not supported yet");
@ -152,7 +150,7 @@ namespace Interrupts
bool InterruptHandled = false; bool InterruptHandled = false;
foreach (auto ev in RegisteredEvents) foreach (auto ev in RegisteredEvents)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
if ((ev.ID + CPU::x86::IRQ0) == static_cast<int>(Frame->InterruptNumber)) if ((ev.ID + CPU::x86::IRQ0) == static_cast<int>(Frame->InterruptNumber))
#elif defined(aa64) #elif defined(aa64)
if (ev.ID == static_cast<int>(Frame->InterruptNumber)) if (ev.ID == static_cast<int>(Frame->InterruptNumber))

View File

@ -20,8 +20,8 @@
Xalloc_def; Xalloc_def;
#define XALLOC_CONCAT(x, y) x##y #define XALLOC_CONCAT(x, y) x##y
#define XStoP(x) (x / Xalloc_PAGE_SIZE + 1) #define XStoP(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
#define XPtoS(x) (x * Xalloc_PAGE_SIZE) #define XPtoS(d) ((d)*PAGE_SIZE)
#define Xalloc_BlockChecksum 0xA110C #define Xalloc_BlockChecksum 0xA110C
extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages); extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages);
@ -70,14 +70,14 @@ namespace Xalloc
Block(Xsize_t Size) Block(Xsize_t Size)
{ {
this->Address = Xalloc_REQUEST_PAGES(XStoP(Size)); this->Address = Xalloc_REQUEST_PAGES(XStoP(Size + 1));
this->Size = Size; this->Size = Size;
Xmemset(this->Address, 0, Size); Xmemset(this->Address, 0, Size);
} }
~Block() ~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 (this->SMAPUsed)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asm volatile("stac" :: asm volatile("stac" ::
: "cc"); : "cc");
#endif #endif
@ -131,7 +131,7 @@ namespace Xalloc
{ {
if (this->SMAPUsed) if (this->SMAPUsed)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asm volatile("clac" :: asm volatile("clac" ::
: "cc"); : "cc");
#endif #endif
@ -209,7 +209,8 @@ namespace Xalloc
{ {
if (!CurrentBlock->Check()) 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) while (Xalloc_StopOnFail)
; ;
} }

View File

@ -48,7 +48,6 @@ using namespace Memory;
Physical KernelAllocator; Physical KernelAllocator;
PageTable4 *KernelPageTable = nullptr; PageTable4 *KernelPageTable = nullptr;
PageTable4 *UserspaceKernelOnlyPageTable = nullptr;
bool Page1GBSupport = false; bool Page1GBSupport = false;
bool PSESupport = false; bool PSESupport = false;
@ -102,9 +101,7 @@ NIF void MapFromZero(PageTable4 *PT, BootInfo *Info)
else else
va.Map((void *)0, (void *)0, MemSize, PTFlag::RW); va.Map((void *)0, (void *)0, MemSize, PTFlag::RW);
void *NullAddress = KernelAllocator.RequestPage(); va.Unmap((void *)0);
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);
} }
NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info) 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) for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
} }
@ -179,7 +176,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE) for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
} }
@ -187,7 +184,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE) for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
} }
@ -195,7 +192,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE) for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G); va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.LockPage((void *)BaseKernelMapAddress); KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE; BaseKernelMapAddress += PAGE_SIZE;
} }
@ -203,7 +200,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE) for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE)
{ {
va.Map((void *)k, (void *)k, PTFlag::G); va.Map((void *)k, (void *)k, PTFlag::G);
KernelAllocator.LockPage((void *)k); KernelAllocator.ReservePage((void *)k);
} }
#ifdef DEBUG #ifdef DEBUG
@ -243,8 +240,8 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
#ifdef DEBUG #ifdef DEBUG
for (uint64_t i = 0; i < Info->Memory.Entries; i++) for (uint64_t i = 0; i < Info->Memory.Entries; i++)
{ {
uintptr_t Base = reinterpret_cast<uintptr_t>(Info->Memory.Entry[i].BaseAddress); uintptr_t Base = r_cst(uintptr_t, Info->Memory.Entry[i].BaseAddress);
uintptr_t Length = Info->Memory.Entry[i].Length; size_t Length = Info->Memory.Entry[i].Length;
uintptr_t End = Base + Length; uintptr_t End = Base + Length;
const char *Type = "Unknown"; const char *Type = "Unknown";
@ -293,12 +290,21 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
TO_MB(KernelAllocator.GetTotalMemory()), TO_MB(KernelAllocator.GetTotalMemory()),
TO_MB(KernelAllocator.GetReservedMemory())); TO_MB(KernelAllocator.GetReservedMemory()));
trace("Initializing Virtual Memory Manager"); /* -- Debugging --
KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); size_t bmap_size = KernelAllocator.GetPageBitmap().Size;
memset(KernelPageTable, 0, PAGE_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)); inf_loop debug("Alloc.: %#lx", KernelAllocator.RequestPage());
memset(UserspaceKernelOnlyPageTable, 0, PAGE_SIZE); */
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) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{ {
@ -333,16 +339,11 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
MapFramebuffer(KernelPageTable, Info); MapFramebuffer(KernelPageTable, Info);
MapKernel(KernelPageTable, Info); MapKernel(KernelPageTable, Info);
memcpy(UserspaceKernelOnlyPageTable, KernelPageTable, sizeof(PageTable4)); trace("Applying new page table from address %#lx", KernelPageTable);
trace("Applying new page table from address %p", KernelPageTable);
#ifdef DEBUG #ifdef DEBUG
debug("Kernel:");
tracepagetable(KernelPageTable); tracepagetable(KernelPageTable);
debug("Userspace:");
tracepagetable(UserspaceKernelOnlyPageTable);
#endif #endif
#if defined(a64) || defined(a32) #if defined(a86)
asmv("mov %0, %%cr3" ::"r"(KernelPageTable)); asmv("mov %0, %%cr3" ::"r"(KernelPageTable));
#elif defined(aa64) #elif defined(aa64)
asmv("msr ttbr0_el1, %0" ::"r"(KernelPageTable)); asmv("msr ttbr0_el1, %0" ::"r"(KernelPageTable));
@ -372,7 +373,7 @@ void *malloc(size_t Size)
{ {
case MemoryAllocatorType::Pages: case MemoryAllocatorType::Pages:
{ {
ret = KernelAllocator.RequestPages(TO_PAGES(Size)); ret = KernelAllocator.RequestPages(TO_PAGES(Size + 1));
memset(ret, 0, Size); memset(ret, 0, Size);
break; break;
} }
@ -425,7 +426,7 @@ void *calloc(size_t n, size_t Size)
{ {
case MemoryAllocatorType::Pages: case MemoryAllocatorType::Pages:
{ {
ret = KernelAllocator.RequestPages(TO_PAGES(n * Size)); ret = KernelAllocator.RequestPages(TO_PAGES(n * Size + 1));
memset(ret, 0, n * Size); memset(ret, 0, n * Size);
break; break;
} }
@ -478,7 +479,7 @@ void *realloc(void *Address, size_t Size)
{ {
case unlikely(MemoryAllocatorType::Pages): 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); memset(ret, 0, Size);
break; break;
} }

View File

@ -295,7 +295,7 @@ namespace Memory
if (unlikely(Address == nullptr)) if (unlikely(Address == nullptr))
warn("Trying to reserve null address."); 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)) if (unlikely(PageBitmap[Index] == true))
return; return;
@ -313,7 +313,18 @@ namespace Memory
warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
for (size_t t = 0; t < PageCount; t++) 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) void Physical::UnreservePage(void *Address)
@ -321,7 +332,7 @@ namespace Memory
if (unlikely(Address == nullptr)) if (unlikely(Address == nullptr))
warn("Trying to unreserve null address."); 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)) if (unlikely(PageBitmap[Index] == false))
return; return;
@ -341,7 +352,20 @@ namespace Memory
warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
for (size_t t = 0; t < PageCount; t++) 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) void Physical::Init(BootInfo *Info)
@ -349,6 +373,7 @@ namespace Memory
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
uint64_t MemorySize = Info->Memory.Size; uint64_t MemorySize = Info->Memory.Size;
debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize));
TotalMemory = MemorySize; TotalMemory = MemorySize;
FreeMemory = MemorySize; FreeMemory = MemorySize;
@ -381,8 +406,9 @@ namespace Memory
CPU::Stop(); CPU::Stop();
} }
/* TODO: Read swap config and make the configure the bitmap size correctly */
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1; 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, LargestFreeMemorySegment,
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize), (void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
BitmapSize); BitmapSize);
@ -392,16 +418,27 @@ namespace Memory
for (size_t i = 0; i < BitmapSize; i++) for (size_t i = 0; i < BitmapSize; i++)
*(uint8_t *)(PageBitmap.Buffer + i) = 0; *(uint8_t *)(PageBitmap.Buffer + i) = 0;
trace("Reserving pages..."); debug("Reserving pages...");
for (uint64_t i = 0; i < Info->Memory.Entries; i++) for (uint64_t i = 0; i < Info->Memory.Entries; i++)
{ {
if (Info->Memory.Entry[i].Type != Usable) if (Info->Memory.Entry[i].Type != Usable)
this->ReservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length)); this->ReservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length));
} }
trace("Locking bitmap pages..."); /* Making sure that the lower memory area is properly reserved. */
this->ReservePages(0, 0x100); this->ReservePages(0, 0x200);
this->LockPages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); 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() {} Physical::Physical() {}

View File

@ -28,7 +28,7 @@ namespace Memory
if (this->UserMode) 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); memset(AllocatedStack, 0, USER_STACK_SIZE);
debug("AllocatedStack: %p", AllocatedStack); debug("AllocatedStack: %p", AllocatedStack);
@ -52,7 +52,7 @@ namespace Memory
} }
else else
{ {
this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
memset(this->StackBottom, 0, STACK_SIZE); memset(this->StackBottom, 0, STACK_SIZE);
debug("StackBottom: %p", this->StackBottom); debug("StackBottom: %p", this->StackBottom);
@ -70,7 +70,7 @@ namespace Memory
StackGuard::~StackGuard() StackGuard::~StackGuard()
{ {
fixme("Temporarily disabled stack guard deallocation"); 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); // debug("Freed stack at %p", this->StackBottom);
} }
@ -85,7 +85,7 @@ namespace Memory
} }
else else
{ {
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE)); void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1));
debug("AllocatedStack: %p", AllocatedStack); debug("AllocatedStack: %p", AllocatedStack);
memset(AllocatedStack, 0, USER_STACK_SIZE); memset(AllocatedStack, 0, USER_STACK_SIZE);
for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)

View File

@ -131,8 +131,8 @@ namespace Memory
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr; PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
if (!PML4->Present) if (!PML4->Present)
{ {
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr))); PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr) + 1));
memset(PDPTEPtr, 0, PAGE_SIZE); memset(PDPTEPtr, 0, sizeof(PageDirectoryPointerTableEntryPtr));
PML4->Present = true; PML4->Present = true;
PML4->SetAddress((uintptr_t)PDPTEPtr >> 12); PML4->SetAddress((uintptr_t)PDPTEPtr >> 12);
} }
@ -153,8 +153,8 @@ namespace Memory
PageDirectoryEntryPtr *PDEPtr = nullptr; PageDirectoryEntryPtr *PDEPtr = nullptr;
if (!PDPTE->Present) if (!PDPTE->Present)
{ {
PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr))); PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr) + 1));
memset(PDEPtr, 0, PAGE_SIZE); memset(PDEPtr, 0, sizeof(PageDirectoryEntryPtr));
PDPTE->Present = true; PDPTE->Present = true;
PDPTE->SetAddress((uintptr_t)PDEPtr >> 12); PDPTE->SetAddress((uintptr_t)PDEPtr >> 12);
} }
@ -175,8 +175,8 @@ namespace Memory
PageTableEntryPtr *PTEPtr = nullptr; PageTableEntryPtr *PTEPtr = nullptr;
if (!PDE->Present) if (!PDE->Present)
{ {
PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr))); PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr) + 1));
memset(PTEPtr, 0, PAGE_SIZE); memset(PTEPtr, 0, sizeof(PageTableEntryPtr));
PDE->Present = true; PDE->Present = true;
PDE->SetAddress((uintptr_t)PTEPtr >> 12); PDE->SetAddress((uintptr_t)PTEPtr >> 12);
} }
@ -217,7 +217,7 @@ namespace Memory
(byte & 0x01 ? '1' : '0') (byte & 0x01 ? '1' : '0')
if (!this->Check(VirtualAddress, (PTFlag)Flags, Type)) // quick workaround just to see where it fails 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 #endif
} }

View File

@ -77,7 +77,7 @@ namespace Power
Power::Power() Power::Power()
{ {
this->acpi = new ACPI::ACPI(bInfo); this->acpi = new ACPI::ACPI;
this->madt = new ACPI::MADT(((ACPI::ACPI *)acpi)->MADT); this->madt = new ACPI::MADT(((ACPI::ACPI *)acpi)->MADT);
trace("Power manager initialized"); trace("Power manager initialized");
} }

View File

@ -41,7 +41,7 @@ namespace Random
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
RDRANDFlag = 0; RDRANDFlag = 0;
#if defined(a64) || defined(a32) #if defined(a86)
if (RDRANDFlag) if (RDRANDFlag)
{ {
uint16_t RDRANDValue = 0; uint16_t RDRANDValue = 0;
@ -74,7 +74,7 @@ namespace Random
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
RDRANDFlag = 0; RDRANDFlag = 0;
#if defined(a64) || defined(a32) #if defined(a86)
if (RDRANDFlag) if (RDRANDFlag)
{ {
uint32_t RDRANDValue = 0; uint32_t RDRANDValue = 0;
@ -107,7 +107,7 @@ namespace Random
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
RDRANDFlag = 0; RDRANDFlag = 0;
#if defined(a64) || defined(a32) #if defined(a86)
if (RDRANDFlag) if (RDRANDFlag)
{ {
uint64_t RDRANDValue = 0; uint64_t RDRANDValue = 0;

View File

@ -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); debug("Current stack check guard value: %#lx", __stack_chk_guard);
KPrint("\eFF0000Stack smashing detected!"); KPrint("\eFF0000Stack smashing detected!");
#if defined(a64) || defined(a32) #if defined(a86)
void *Stack = nullptr; void *Stack = nullptr;
#if defined(a64) #if defined(a64)
asmv("movq %%rsp, %0" asmv("movq %%rsp, %0"
@ -87,7 +87,7 @@ EXTERNC __weak __noreturn __no_stack_protector void __chk_fail(void)
error("Buffer overflow detected!"); error("Buffer overflow detected!");
KPrint("\eFF0000Buffer overflow detected!"); KPrint("\eFF0000Buffer overflow detected!");
#if defined(a64) || defined(a32) #if defined(a86)
while (1) while (1)
asmv("cli; hlt"); asmv("cli; hlt");
#elif defined(aa64) #elif defined(aa64)

View File

@ -21,22 +21,20 @@
#include "../kernel.h" #include "../kernel.h"
/* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf */
namespace SMBIOS namespace SMBIOS
{ {
bool CheckSMBIOS() 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; return true;
} }
debug("SMBIOS is not available. (%#lx)", bInfo->SMBIOSPtr); debug("SMBIOS is not available. (%#lx)", bInfo.SMBIOSPtr);
return false; return false;
} }
SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; } SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; }
static inline int SMBIOSTableLength(SMBIOSHeader *Hdr) static inline int SMBIOSTableLength(SMBIOSHeader *Hdr)
{ {
@ -52,7 +50,7 @@ namespace SMBIOS
if (!CheckSMBIOS()) if (!CheckSMBIOS())
return nullptr; return nullptr;
SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo.SMBIOSPtr;
debug("Getting SMBIOS header for type %d", Type); debug("Getting SMBIOS header for type %d", Type);
struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress; struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress;

View File

@ -24,7 +24,7 @@ namespace Time
Clock ReadClock() Clock ReadClock()
{ {
Clock tm; Clock tm;
#if defined(a64) || defined(a32) #if defined(a86)
uint32_t t = 0; uint32_t t = 0;
outb(0x70, 0x00); outb(0x70, 0x00);
t = inb(0x71); t = inb(0x71);

View File

@ -33,7 +33,7 @@ namespace Time
{ {
void time::Sleep(uint64_t Milliseconds) void time::Sleep(uint64_t Milliseconds)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk; uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
#ifdef DEBUG #ifdef DEBUG
uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue); uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue);
@ -52,7 +52,7 @@ namespace Time
uint64_t time::GetCounter() uint64_t time::GetCounter()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
return mminq(&((HPET *)hpet)->MainCounterValue); return mminq(&((HPET *)hpet)->MainCounterValue);
#elif defined(aa64) #elif defined(aa64)
#endif #endif
@ -60,7 +60,7 @@ namespace Time
uint64_t time::CalculateTarget(uint64_t Milliseconds) uint64_t time::CalculateTarget(uint64_t Milliseconds)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
return mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk; return mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
#elif defined(aa64) #elif defined(aa64)
#endif #endif
@ -75,7 +75,7 @@ namespace Time
ACPI::ACPI *acpi = (ACPI::ACPI *)this->acpi; ACPI::ACPI *acpi = (ACPI::ACPI *)this->acpi;
if (acpi->HPET) if (acpi->HPET)
{ {
Memory::Virtual().Map((void *)acpi->HPET->Address.Address, Memory::Virtual().Remap((void *)acpi->HPET->Address.Address,
(void *)acpi->HPET->Address.Address, (void *)acpi->HPET->Address.Address,
Memory::PTFlag::RW | Memory::PTFlag::PCD); Memory::PTFlag::RW | Memory::PTFlag::PCD);
this->hpet = (void *)acpi->HPET->Address.Address; this->hpet = (void *)acpi->HPET->Address.Address;

View File

@ -386,7 +386,8 @@ bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
{ {
/* This can be ignored (unaligned memory access) */ /* This can be ignored (unaligned memory access) */
if (strstr(file, "AdvancedConfigurationAndPowerInterface.cpp") && if (strstr(file, "AdvancedConfigurationAndPowerInterface.cpp") &&
(line == 34 && column == 47)) ((line == 34 && column == 47) ||
(line == 36 && column == 47)))
return false; return false;
/* This can be ignored (unaligned memory access) */ /* 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)) (line == 63 && column == 30))
return false; 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') */ /* This can be ignored (store address x with insufficient space for object of type 'y') */
if (strstr(file, "Task.cpp") && line > 500) if (strstr(file, "Task.cpp") && line > 500)
return false; return false;

View File

@ -23,7 +23,7 @@
volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
std::vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents; std::vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents;
#if defined(a64) || defined(a32) #if defined(a86)
NIF __always_inline inline uint8_t NoProfiler_inportb(uint16_t Port) NIF __always_inline inline uint8_t NoProfiler_inportb(uint16_t Port)
{ {
uint8_t Result; uint8_t Result;
@ -56,7 +56,7 @@ namespace UniversalAsynchronousReceiverTransmitter
SafeFunction NIF UART::UART(SerialPorts Port) SafeFunction NIF UART::UART(SerialPorts Port)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
if (Port == COMNULL) if (Port == COMNULL)
return; return;
@ -125,7 +125,7 @@ namespace UniversalAsynchronousReceiverTransmitter
SafeFunction NIF void UART::Write(uint8_t Char) 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) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & SERIAL_BUFFER_EMPTY) == 0)
; ;
NoProfiler_outportb(Port, Char); NoProfiler_outportb(Port, Char);
@ -137,7 +137,7 @@ namespace UniversalAsynchronousReceiverTransmitter
SafeFunction NIF uint8_t UART::Read() 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) while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & 1) == 0)
; ;
return NoProfiler_inportb(Port); return NoProfiler_inportb(Port);
@ -146,7 +146,7 @@ namespace UniversalAsynchronousReceiverTransmitter
{ {
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL) if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
e->OnReceived(NoProfiler_inportb(Port)); e->OnReceived(NoProfiler_inportb(Port));
#endif #endif
} }

View File

@ -50,7 +50,7 @@ namespace Video
size_t Size = this->framebuffer.Pitch * Height; 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); memset(this->Buffers[Index].Buffer, 0, Size);
this->Buffers[Index].Width = Width; this->Buffers[Index].Width = Width;
@ -102,7 +102,7 @@ namespace Video
return; 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].Buffer = nullptr;
this->Buffers[Index].Checksum = 0; this->Buffers[Index].Checksum = 0;
debug("Buffer %d deleted", Index); debug("Buffer %d deleted", Index);

View File

@ -33,7 +33,7 @@ namespace Video
{ {
this->Info.PSF2Font = new PSF2_FONT; 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); memcpy((void *)font2, Start, FontDataLength);
Memory::Virtual().Map((void *)font2, (void *)font2, FontDataLength, Memory::PTFlag::RW); 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) 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."); error("Font2 magic mismatch.");
KernelAllocator.FreePages((void *)font2, FontDataLength / PAGE_SIZE + 1); KernelAllocator.FreePages((void *)font2, TO_PAGES(FontDataLength + 1));
return; return;
} }

View File

@ -86,6 +86,7 @@ struct KernelAPI
{ {
unsigned long Offset; unsigned long Offset;
unsigned long DriverUID; unsigned long DriverUID;
char KernelDebug;
} Info; } Info;
struct KAPIMemory struct KAPIMemory

View File

@ -159,7 +159,7 @@ namespace Execute
size_t ExFileSize = ExFile->node->Length; size_t ExFileSize = ExFile->node->Length;
/* Allocate elf in memory */ /* 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 */ /* Copy the file to the allocated memory */
memcpy(ElfFile, (void *)ExFile->node->Address, ExFileSize); memcpy(ElfFile, (void *)ExFile->node->Address, ExFileSize);
debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize); debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize);

View File

@ -172,7 +172,7 @@ namespace Execute
if (ELFGetDynamicTag(ElfFile, DT_TEXTREL)) if (ELFGetDynamicTag(ElfFile, DT_TEXTREL))
{ {
fixme("Text relocation is not(?) tested yet!"); 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); memset(MemoryImage, 0, Length);
return {MemoryImage, 0x0}; return {MemoryImage, 0x0};
} }
@ -196,14 +196,14 @@ namespace Execute
if (ItrPhdr.p_type == PT_LOAD && ItrPhdr.p_vaddr == 0) if (ItrPhdr.p_type == PT_LOAD && ItrPhdr.p_vaddr == 0)
{ {
debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length)); 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); memset(MemoryImage, 0, Length);
return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress}; return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress};
} }
} }
debug("Allocating %ld pages for image", TO_PAGES(Length)); 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); memset(MemoryImage, 0, Length);
if (FirstProgramHeaderVirtualAddress != 0) if (FirstProgramHeaderVirtualAddress != 0)

View File

@ -48,7 +48,7 @@ namespace Execute
continue; continue;
if (Section->sh_flags & SHF_ALLOC) 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); memset(Buffer, 0, Section->sh_size);
Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US); Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);

View File

@ -89,7 +89,7 @@ namespace Execute
sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */ sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */
sl.RefCount = 0; sl.RefCount = 0;
void *LibFile = mem->RequestPages(TO_PAGES(Length), true); void *LibFile = mem->RequestPages(TO_PAGES(Length + 1), true);
debug("LibFile: %#lx", LibFile); debug("LibFile: %#lx", LibFile);
memcpy(LibFile, (void *)ElfImage, Length); memcpy(LibFile, (void *)ElfImage, Length);
Memory::Virtual().Map(LibFile, LibFile, Length, Memory::RW | Memory::US | Memory::G); Memory::Virtual().Map(LibFile, LibFile, Length, Memory::RW | Memory::US | Memory::G);

View File

@ -58,7 +58,7 @@ namespace Execute
cwk_path_get_basename(Path, &BaseName, nullptr); cwk_path_get_basename(Path, &BaseName, nullptr);
PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User); 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); 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); Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile->node->Length, Memory::PTFlag::RW | Memory::PTFlag::US);

View File

@ -71,7 +71,8 @@ enum FexDriverType
FexDriverType_Storage, FexDriverType_Storage,
FexDriverType_FileSystem, FexDriverType_FileSystem,
FexDriverType_Input, FexDriverType_Input,
FexDriverType_Audio FexDriverType_Audio,
FexDriverType_ACPI,
/* ... */ /* ... */
}; };

View File

@ -618,7 +618,7 @@ namespace GraphicalUserInterface
this->BackBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->BackBuffer->BitsPerPixel = Display->GetBitsPerPixel();
this->BackBuffer->Pitch = Display->GetPitch(); this->BackBuffer->Pitch = Display->GetPitch();
this->BackBuffer->Size = Display->GetBuffer(200)->Size; 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); memset(this->BackBuffer->Data, 0, this->BackBuffer->Size);
this->DesktopBuffer = new ScreenBitmap; this->DesktopBuffer = new ScreenBitmap;
@ -627,7 +627,7 @@ namespace GraphicalUserInterface
this->DesktopBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->DesktopBuffer->BitsPerPixel = Display->GetBitsPerPixel();
this->DesktopBuffer->Pitch = Display->GetPitch(); this->DesktopBuffer->Pitch = Display->GetPitch();
this->DesktopBuffer->Size = Display->GetBuffer(200)->Size; 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); memset(this->DesktopBuffer->Data, 0, this->DesktopBuffer->Size);
this->OverlayBuffer = new ScreenBitmap; this->OverlayBuffer = new ScreenBitmap;
@ -636,7 +636,7 @@ namespace GraphicalUserInterface
this->OverlayBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->OverlayBuffer->BitsPerPixel = Display->GetBitsPerPixel();
this->OverlayBuffer->Pitch = Display->GetPitch(); this->OverlayBuffer->Pitch = Display->GetPitch();
this->OverlayBuffer->Size = Display->GetBuffer(200)->Size; 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); memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size);
this->CursorBuffer = new ScreenBitmap; this->CursorBuffer = new ScreenBitmap;
@ -645,7 +645,7 @@ namespace GraphicalUserInterface
this->CursorBuffer->BitsPerPixel = Display->GetBitsPerPixel(); this->CursorBuffer->BitsPerPixel = Display->GetBitsPerPixel();
this->CursorBuffer->Pitch = Display->GetPitch(); this->CursorBuffer->Pitch = Display->GetPitch();
this->CursorBuffer->Size = this->CursorBuffer->Width * this->CursorBuffer->Height * (this->CursorBuffer->BitsPerPixel / 8); 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); memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size);
this->IsRunning = true; this->IsRunning = true;

View File

@ -73,7 +73,7 @@ namespace GraphicalUserInterface
LastWidth = ((Window *)this->ParentWindow)->GetPosition().Width; LastWidth = ((Window *)this->ParentWindow)->GetPosition().Width;
LastHeight = ((Window *)this->ParentWindow)->GetPosition().Height; 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; this->Buffer->Data = nullptr;
delete this->Buffer, this->Buffer = nullptr; delete this->Buffer, this->Buffer = nullptr;
@ -83,7 +83,7 @@ namespace GraphicalUserInterface
this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->BitsPerPixel = Display->GetBitsPerPixel();
this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Pitch = Display->GetPitch();
this->Buffer->Size = this->Buffer->Pitch * LastHeight; 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); memset(this->Buffer->Data, 0, this->Buffer->Size);
this->NeedRedraw = true; this->NeedRedraw = true;

View File

@ -34,7 +34,7 @@ namespace GraphicalUserInterface
{ {
Handle WidgetCollection::CreatePanel(Rect rect, uint32_t Color) 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[0] = 'P';
panel->Handle.Type[1] = 'N'; panel->Handle.Type[1] = 'N';
@ -54,7 +54,7 @@ namespace GraphicalUserInterface
Handle WidgetCollection::CreateLabel(Rect rect, const char *Text) 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[0] = 'L';
label->Handle.Type[1] = 'B'; label->Handle.Type[1] = 'B';
@ -74,7 +74,7 @@ namespace GraphicalUserInterface
Handle WidgetCollection::CreateButton(Rect rect, const char *Text, uintptr_t OnClick) 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[0] = 'B';
button->Handle.Type[1] = 'T'; button->Handle.Type[1] = 'T';
@ -126,7 +126,7 @@ namespace GraphicalUserInterface
this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->BitsPerPixel = Display->GetBitsPerPixel();
this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Pitch = Display->GetPitch();
this->Buffer->Size = this->Buffer->Pitch * ((Window *)this->ParentWindow)->GetPosition().Height; 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); 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); 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);

View File

@ -66,7 +66,7 @@ namespace GraphicalUserInterface
this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->BitsPerPixel = Display->GetBitsPerPixel();
this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Pitch = Display->GetPitch();
this->Buffer->Size = this->Buffer->Pitch * rect.Height; 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); memset(this->Buffer->Data, 0, this->Buffer->Size);
this->ParentGUI = ParentGUI; this->ParentGUI = ParentGUI;
this->Position = rect; this->Position = rect;

View File

@ -31,7 +31,7 @@ namespace GraphicalUserInterface
void Window::OnResize(Event *e) void Window::OnResize(Event *e)
{ {
// TODO: Optimize this // 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; this->Buffer->Data = nullptr;
delete this->Buffer, this->Buffer = nullptr; delete this->Buffer, this->Buffer = nullptr;
@ -41,7 +41,7 @@ namespace GraphicalUserInterface
this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); this->Buffer->BitsPerPixel = Display->GetBitsPerPixel();
this->Buffer->Pitch = Display->GetPitch(); this->Buffer->Pitch = Display->GetPitch();
this->Buffer->Size = this->Buffer->Pitch * e->Resize.Height; 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); memset(this->Buffer->Data, 0, this->Buffer->Size);
this->OnPaint(e); this->OnPaint(e);
} }

View File

@ -103,7 +103,7 @@ void TaskMgr()
{ {
for (short j = 0; j < 200; j++) 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; *Pixel = 0x222222;
} }
} }

View File

@ -70,6 +70,8 @@ LockClass mExtTrkLock;
* - [ ] Fix memcpy, memset and memcmp functions (they are not working properly with SIMD). * - [ ] Fix memcpy, memset and memcmp functions (they are not working properly with SIMD).
* - [ ] Support Aarch64. * - [ ] Support Aarch64.
* - [ ] Fully support i386. * - [ ] Fully support i386.
* - [ ] SMP trampoline shouldn't be hardcoded at 0x2000.
* - [ ] Rework the stack guard.
* *
* ISSUES: * ISSUES:
* - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) * - [ ] 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: * - CPUID lists:
* https://www.amd.com/system/files/TechDocs/40332.pdf * 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 #ifdef a64
@ -176,7 +185,7 @@ using VirtualFileSystem::FileStatus;
using VirtualFileSystem::Node; using VirtualFileSystem::Node;
using VirtualFileSystem::NodeFlags; using VirtualFileSystem::NodeFlags;
BootInfo *bInfo = nullptr; __aligned(16) BootInfo bInfo{};
Video::Display *Display = nullptr; Video::Display *Display = nullptr;
SymbolResolver::Symbols *KernelSymbolTable = nullptr; SymbolResolver::Symbols *KernelSymbolTable = nullptr;
Power::Power *PowerManager = nullptr; Power::Power *PowerManager = nullptr;
@ -233,11 +242,11 @@ EXTERNC void KPrint(const char *Format, ...)
EXTERNC NIF void Main(BootInfo *Info) EXTERNC NIF void Main(BootInfo *Info)
{ {
BootClock = Time::ReadClock(); BootClock = Time::ReadClock();
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); // bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo) + 1));
memcpy(bInfo, Info, sizeof(BootInfo)); memcpy(&bInfo, Info, sizeof(BootInfo));
debug("BootInfo structure is at %p", bInfo); 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); 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", KPrint("Time: \e8888FF%02d:%02d:%02d %02d/%02d/%02d UTC",
@ -249,7 +258,7 @@ EXTERNC NIF void Main(BootInfo *Info)
Interrupts::Initialize(0); Interrupts::Initialize(0);
KPrint("Reading Kernel Parameters"); KPrint("Reading Kernel Parameters");
ParseConfig((char *)bInfo->Kernel.CommandLine, &Config); ParseConfig((char *)bInfo.Kernel.CommandLine, &Config);
if (Config.BootAnimation) if (Config.BootAnimation)
{ {
@ -268,8 +277,8 @@ EXTERNC NIF void Main(BootInfo *Info)
KPrint("Initializing CPU Features"); KPrint("Initializing CPU Features");
CPU::InitializeFeatures(0); CPU::InitializeFeatures(0);
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) if (DebuggerIsAttached)
KPrint("\eFFA500TCG Virtual Machine detected."); KPrint("\eFFA500Kernel debugger detected.");
KPrint("Loading Kernel Symbols"); KPrint("Loading Kernel Symbols");
KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase); 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++) for (size_t i = 0; i < MAX_MODULES; i++)
{ {
if (!bInfo->Modules[i].Address) if (!bInfo.Modules[i].Address)
continue; 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; static char initrd = 0;
if (!initrd++) 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; static char bootanim = 0;
if (!bootanim++) 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!"); 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 // https://wiki.osdev.org/Calling_Global_Constructors
for (CallPtr *func = __init_array_start; func != __init_array_end; func++) for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
(*func)(); (*func)();
InitializeMemoryManagement(Info); InitializeMemoryManagement(Info);
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
DebuggerIsAttached = true;
#ifdef DEBUG #ifdef DEBUG
/* I had to do this because KernelAllocator /* I had to do this because KernelAllocator
* is a global constructor but we need * is a global constructor but we need

View File

@ -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 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. 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 Copyright (C) 2023 EnderIce2
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify

View File

@ -749,7 +749,7 @@ EXTERNC void __chk_fail(void) __noreturn;
__noreturn __always_inline static inline void __convert_chk_fail(void) __noreturn __always_inline static inline void __convert_chk_fail(void)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("int3"); asmv("int3");
#else #else
#warning "Not implemented!" #warning "Not implemented!"

View File

@ -68,7 +68,7 @@ ifeq ($(OSARCH), amd64)
CFLAGS += -fno-pic -fno-pie \ CFLAGS += -fno-pic -fno-pie \
-mno-red-zone -march=core2 -pipe \ -mno-red-zone -march=core2 -pipe \
-mcmodel=kernel -fno-builtin -Da64 -mcmodel=kernel -fno-builtin -Da64 -Da86
CFLAG_STACK_PROTECTOR := -fstack-protector-all CFLAG_STACK_PROTECTOR := -fstack-protector-all
LDFLAGS += -TArchitecture/amd64/linker.ld \ LDFLAGS += -TArchitecture/amd64/linker.ld \
-fno-pic -fno-pie \ -fno-pic -fno-pie \
@ -81,7 +81,7 @@ else ifeq ($(OSARCH), i386)
CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \ CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \
-mno-red-zone -march=pentium -pipe -msoft-float \ -mno-red-zone -march=pentium -pipe -msoft-float \
-fno-builtin -Da32 -fno-builtin -Da32 -Da86
CFLAG_STACK_PROTECTOR := -fstack-protector-all CFLAG_STACK_PROTECTOR := -fstack-protector-all
LDFLAGS += -TArchitecture/i386/linker.ld \ LDFLAGS += -TArchitecture/i386/linker.ld \
-fno-pic -fno-pie \ -fno-pic -fno-pie \

View File

@ -68,12 +68,12 @@ namespace NetworkInterfaceManager
void NetworkInterface::FetchNetworkCards(unsigned long DriverUID) 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)); memset(cb, 0, sizeof(KernelCallback));
cb->Reason = FetchReason; cb->Reason = FetchReason;
DriverManager->IOCB(DriverUID, (void *)cb); 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); strcpy(Iface->Name, cb->NetworkCallback.Fetch.Name);
Iface->ID = this->CardIDs++; Iface->ID = this->CardIDs++;
Iface->MAC.FromHex(cb->NetworkCallback.Fetch.MAC); 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 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); memcpy(DataToBeSent, Data, Length);
KernelCallback *cb = (KernelCallback *)Interface->DriverCallBackAddress; KernelCallback *cb = (KernelCallback *)Interface->DriverCallBackAddress;
@ -209,7 +209,7 @@ namespace NetworkInterfaceManager
cb->NetworkCallback.Send.Length = Length; cb->NetworkCallback.Send.Length = Length;
DriverManager->IOCB(Interface->DriverID, (void *)cb); DriverManager->IOCB(Interface->DriverID, (void *)cb);
mem->FreePages(DataToBeSent, TO_PAGES(Length)); mem->FreePages(DataToBeSent, TO_PAGES(Length + 1));
foreach (auto var in RegisteredEvents) foreach (auto var in RegisteredEvents)
var->OnInterfaceSent(Interface, Data, Length); var->OnInterfaceSent(Interface, Data, Length);
} }

View File

@ -43,7 +43,7 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_enter(void *Function, void *Cal
return; return;
while (Wait) while (Wait)
#if defined(a64) || defined(a32) #if defined(a86)
asmv("pause"); asmv("pause");
#elif defined(aa64) #elif defined(aa64)
asmv("yield"); asmv("yield");
@ -80,7 +80,7 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_exit(void *Function, void *Call
return; return;
while (Wait) while (Wait)
#if defined(a64) || defined(a32) #if defined(a86)
asmv("pause"); asmv("pause");
#elif defined(aa64) #elif defined(aa64)
asmv("yield"); asmv("yield");

View File

@ -78,7 +78,7 @@ namespace Recovery
return; 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); memcpy(PCMRaw, (void *)pcm->node->Address, pcm->node->Length);
KernelCallback callback; KernelCallback callback;
@ -89,7 +89,7 @@ namespace Recovery
debug("Playing audio..."); debug("Playing audio...");
int status = DriverManager->IOCB(AudioDrv.DriverUID, (void *)&callback); int status = DriverManager->IOCB(AudioDrv.DriverUID, (void *)&callback);
debug("Audio played! %d", status); 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); vfs->Close(pcm);
TEXIT(0); TEXIT(0);
} }

View File

@ -88,7 +88,7 @@ static uintptr_t sys_request_pages(SyscallsFrame *Frame, size_t Count)
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED; return SYSCALL_ACCESS_DENIED;
UNUSED(Frame); 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) 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 */ /* Allow everyone to free pages */
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED; return SYSCALL_ACCESS_DENIED;
TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count); TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count + 1);
UNUSED(Frame); UNUSED(Frame);
return SYSCALL_OK; return SYSCALL_OK;
} }

View File

@ -27,7 +27,7 @@ namespace InterProcessCommunication
IPCHandle *IPC::Create(IPCType Type, char UniqueToken[16]) IPCHandle *IPC::Create(IPCType Type, char UniqueToken[16])
{ {
SmartLock(this->IPCLock); 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->ID = NextID++;
Hnd->Node = vfs->Create(UniqueToken, VirtualFileSystem::NodeFlags::FILE, IPCNode); Hnd->Node = vfs->Create(UniqueToken, VirtualFileSystem::NodeFlags::FILE, IPCNode);
@ -48,7 +48,7 @@ namespace InterProcessCommunication
if (Handles[i]->ID == ID) if (Handles[i]->ID == ID)
{ {
vfs->Delete(Handles[i]->Node); 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); Handles.remove(i);
debug("Destroyed IPC with ID %d", ID); debug("Destroyed IPC with ID %d", ID);
return IPCSuccess; return IPCSuccess;
@ -71,7 +71,7 @@ namespace InterProcessCommunication
if (Hnd->Buffer != nullptr || Hnd->Length != 0) if (Hnd->Buffer != nullptr || Hnd->Length != 0)
return IPCAlreadyAllocated; return IPCAlreadyAllocated;
Hnd->Buffer = (uint8_t *)mem->RequestPages(TO_PAGES(Size)); Hnd->Buffer = (uint8_t *)mem->RequestPages(TO_PAGES(Size + 1));
Hnd->Length = Size; Hnd->Length = Size;
return IPCSuccess; return IPCSuccess;
} }
@ -89,7 +89,7 @@ namespace InterProcessCommunication
if (Hnd->Buffer == nullptr || Hnd->Length == 0) if (Hnd->Buffer == nullptr || Hnd->Length == 0)
return IPCNotAllocated; return IPCNotAllocated;
mem->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length)); mem->FreePages(Hnd->Buffer, TO_PAGES(Hnd->Length + 1));
Hnd->Buffer = nullptr; Hnd->Buffer = nullptr;
Hnd->Length = 0; Hnd->Length = 0;
return IPCSuccess; return IPCSuccess;

View File

@ -58,7 +58,7 @@ namespace Tasking
// ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); // ((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() __naked __used __no_stack_protector NIF void IdleProcessLoop()
{ {
asmv("IdleLoop:\n" asmv("IdleLoop:\n"
@ -140,7 +140,7 @@ namespace Tasking
delete ListProcess[i]->ELFSymbolTable, ListProcess[i]->ELFSymbolTable = nullptr; delete ListProcess[i]->ELFSymbolTable, ListProcess[i]->ELFSymbolTable = nullptr;
SecurityManager.DestroyToken(ListProcess[i]->Security.UniqueToken); SecurityManager.DestroyToken(ListProcess[i]->Security.UniqueToken);
if (ListProcess[i]->Security.TrustLevel == TaskTrustLevel::User) 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 // Remove the process from parent's children list
if (ListProcess[i]->Parent) if (ListProcess[i]->Parent)
@ -293,7 +293,7 @@ namespace Tasking
// TaskingScheduler_OneShot(1); // TaskingScheduler_OneShot(1);
// IRQ16 // IRQ16
TaskingLock.Unlock(); 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 */ asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
#elif defined(aa64) #elif defined(aa64)
asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */ 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); SecurityManager.DestroyToken(Process->Security.UniqueToken);
if (Process->Security.TrustLevel == TaskTrustLevel::User) 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) if (Process->Parent)
for (size_t j = 0; j < Process->Parent->Children.size(); j++) for (size_t j = 0; j < Process->Parent->Children.size(); j++)
@ -408,7 +408,7 @@ namespace Tasking
Thread->ExitCode = 0xdead; Thread->ExitCode = 0xdead;
Thread->Status = TaskStatus::Ready; Thread->Status = TaskStatus::Ready;
Thread->Memory = new Memory::MemMgr(Parent->PageTable, Parent->memDirectory); 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)))); memset(Thread->FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState))));
Thread->Security.TrustLevel = Parent->Security.TrustLevel; Thread->Security.TrustLevel = Parent->Security.TrustLevel;
@ -721,9 +721,8 @@ namespace Tasking
#if defined(a64) #if defined(a64)
if (!DoNotCreatePageTable) if (!DoNotCreatePageTable)
{ {
Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(sizeof(Memory::PageTable4) + 1));
memcpy(Process->PageTable, (void *)UserspaceKernelOnlyPageTable, PAGE_SIZE); memcpy(Process->PageTable, (void *)KernelPageTable, PAGE_SIZE);
Memory::Virtual(Process->PageTable).Map((void *)Process->PageTable, (void *)Process->PageTable, Memory::PTFlag::RW); // Make sure the page table is mapped.
} }
#elif defined(a32) #elif defined(a32)
#elif defined(aa64) #elif defined(aa64)

155
Tests/CPUID.cpp Normal file
View File

@ -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 <https://www.gnu.org/licenses/>.
*/
#ifdef DEBUG
#include <types.h>
#include <memory.hpp>
#include <debug.h>
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

View File

@ -15,6 +15,8 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>. along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifdef DEBUG
#include <types.h> #include <types.h>
#include <memory.hpp> #include <memory.hpp>
#include <debug.h> #include <debug.h>
@ -23,54 +25,71 @@ __constructor void TestMacros()
{ {
{ {
int a = TO_PAGES(4096); int a = TO_PAGES(4096);
int b = FROM_PAGES(2); int b = FROM_PAGES(1);
debug("a: 4096 -> %d", a); debug("a: 4096 -> %d", a);
debug("b: a -> %d", b); 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) if (a != 2)
{ {
error("TO_PAGES is not equal to 2"); error("t2: TO_PAGES is not equal to 2");
while (1) inf_loop;
;
} }
if (b != 8192) if (b != 8192)
{ {
error("FROM_PAGES is not equal to 8192"); error("t2: FROM_PAGES is not equal to 8192");
while (1) inf_loop;
;
} }
} }
debug("-------------------------"); debug("-------------------------");
{ {
uint64_t actual = PAGE_SIZE; uint64_t bytes = PAGE_SIZE;
uint64_t expected = 1; uint64_t pgs = 1;
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
{ {
uint64_t a = TO_PAGES(actual); uint64_t cnv_to_pgs = TO_PAGES(bytes);
uint64_t b = FROM_PAGES(expected); uint64_t cnv_from_pgs = FROM_PAGES(pgs);
/* TODO: This is a workaround for now. */ if (cnv_to_pgs != pgs)
if (a != expected + 1)
{ {
error("TO_PAGES is not equal to %d (actual: %d)", expected, a); error("TO_PAGES is not equal to %d (pages: %d)", pgs, cnv_to_pgs);
while (1) inf_loop;
;
} }
if (b != actual) if (cnv_from_pgs != bytes)
{ {
error("FROM_PAGES is not equal to %d (actual: %d)", actual, b); error("FROM_PAGES is not equal to %d (bytes: %d)", bytes, cnv_from_pgs);
while (1) inf_loop;
;
} }
actual += PAGE_SIZE; bytes += PAGE_SIZE;
expected++; pgs++;
} }
} }
} }
#endif // DEBUG

View File

@ -38,32 +38,29 @@ __constructor void TestMemoryOperations()
char str2[] = "World"; char str2[] = "World";
memcpy_unsafe(arr2, arr1, sizeof(arr1)); 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]); arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]);
if (memcmp(arr1, arr2, sizeof(arr1)) != 0) if (memcmp(arr1, arr2, sizeof(arr1)) != 0)
{ {
error("memcpy failed!\n"); error("memcpy failed!");
while (1) inf_loop;
;
} }
memset_unsafe(arr2, 0, sizeof(arr2)); 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]); arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]);
if (memcmp(arr1, arr2, sizeof(arr1)) == 0) if (memcmp(arr1, arr2, sizeof(arr1)) == 0)
{ {
error("memset failed!\n"); error("memset failed!");
while (1) inf_loop;
;
} }
memmove_unsafe(str1 + 3, str1, strlen(str1) + 1); memmove_unsafe(str1 + 3, str1, strlen(str1) + 1);
debug("memmove: str1=%s\n", str1); debug("memmove: str1=%s", str1);
if (strcmp(str1, "HelHello") != 0) if (strcmp(str1, "HelHello") != 0)
{ {
error("memmove failed!\n"); error("memmove failed!");
while (1) inf_loop;
;
} }
char carr[1024]; char carr[1024];
@ -82,7 +79,7 @@ __constructor void TestMemoryOperations()
{ {
if (carr[i] != 'a') if (carr[i] != 'a')
{ {
error("memcpy failed!\n"); error("memcpy failed!");
while (1) while (1)
; ;
} }
@ -97,7 +94,7 @@ __constructor void TestMemoryOperations()
{ {
if (carr[i] != 'b') if (carr[i] != 'b')
{ {
error("memcpy failed!\n"); error("memcpy failed!");
while (1) while (1)
; ;
} }
@ -113,7 +110,7 @@ __constructor void TestMemoryOperations()
{ {
if (carr[i] != 'c') if (carr[i] != 'c')
{ {
error("memcpy failed!\n"); error("memcpy failed!");
while (1) while (1)
; ;
} }
@ -128,7 +125,7 @@ __constructor void TestMemoryOperations()
{ {
if (carr[i] != 'd') if (carr[i] != 'd')
{ {
error("memset failed!\n"); error("memset failed!");
while (1) while (1)
; ;
} }

View File

@ -40,7 +40,7 @@ __constructor void TestRandom()
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
RDRANDFlag = 0; RDRANDFlag = 0;
#if defined(a64) || defined(a32) #if defined(a86)
if (RDRANDFlag) if (RDRANDFlag)
{ {
uint64_t RDSEEDValue = 0; uint64_t RDSEEDValue = 0;

View File

@ -31,8 +31,7 @@ void TestString()
else else
{ {
error("String comparison doesn't work! \"%s\"", hw.c_str()); error("String comparison doesn't work! \"%s\"", hw.c_str());
while (1) inf_loop;
;
} }
std::string hi("Hi"); std::string hi("Hi");
@ -45,8 +44,7 @@ void TestString()
else else
{ {
error("String indexing doesn't work! \"%s\" \"%s\"", chi, hi.c_str()); error("String indexing doesn't work! \"%s\" \"%s\"", chi, hi.c_str());
while (1) inf_loop;
;
} }
hi << " there!"; hi << " there!";
@ -55,8 +53,7 @@ void TestString()
else else
{ {
error("String concatenation doesn't work! \"%s\"", hi.c_str()); error("String concatenation doesn't work! \"%s\"", hi.c_str());
while (1) inf_loop;
;
} }
hi << " " << hw; hi << " " << hw;
@ -65,8 +62,7 @@ void TestString()
else else
{ {
error("String concatenation doesn't work! \"%s\"", hi.c_str()); error("String concatenation doesn't work! \"%s\"", hi.c_str());
while (1) inf_loop;
;
} }
std::string eq0("Hello, world!"); std::string eq0("Hello, world!");
@ -78,8 +74,7 @@ void TestString()
else else
{ {
error("String equality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq1.c_str()); error("String equality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq1.c_str());
while (1) inf_loop;
;
} }
if (eq0 != eq2) if (eq0 != eq2)
@ -87,8 +82,7 @@ void TestString()
else else
{ {
error("String inequality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq2.c_str()); error("String inequality doesn't work! \"%s\" \"%s\"", eq0.c_str(), eq2.c_str());
while (1) inf_loop;
;
} }
char chw[14]; char chw[14];
@ -105,8 +99,7 @@ void TestString()
else else
{ {
error("String iteration doesn't work! \"%s\" \"%s\" %d", chw, hw.c_str(), i); error("String iteration doesn't work! \"%s\" \"%s\" %d", chw, hw.c_str(), i);
while (1) inf_loop;
;
} }
std::string a("Hello"); std::string a("Hello");
@ -119,8 +112,7 @@ void TestString()
else else
{ {
error("String addition doesn't work! \"%s\"", c.c_str()); error("String addition doesn't work! \"%s\"", c.c_str());
while (1) inf_loop;
;
} }
} }

View File

@ -54,7 +54,6 @@ struct BootInfo
__UINT32_TYPE__ Height; __UINT32_TYPE__ Height;
__UINT64_TYPE__ Pitch; __UINT64_TYPE__ Pitch;
__UINT16_TYPE__ BitsPerPixel; __UINT16_TYPE__ BitsPerPixel;
__UINT8_TYPE__ MemoryModel;
__UINT8_TYPE__ RedMaskSize; __UINT8_TYPE__ RedMaskSize;
__UINT8_TYPE__ RedMaskShift; __UINT8_TYPE__ RedMaskShift;
__UINT8_TYPE__ GreenMaskSize; __UINT8_TYPE__ GreenMaskSize;

View File

@ -143,7 +143,7 @@ namespace CPU
{ {
do do
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("pause"); asmv("pause");
#elif defined(aa64) #elif defined(aa64)
asmv("yield"); asmv("yield");
@ -154,7 +154,7 @@ namespace CPU
/** /**
* @brief Stop the CPU (infinite loop) * @brief Stop the CPU (infinite loop)
*/ */
#if defined(a64) || defined(a32) #if defined(a86)
SafeFunction __noreturn __naked __used inline void Stop() SafeFunction __noreturn __naked __used inline void Stop()
{ {
asmv("CPUStopLoop:\n" asmv("CPUStopLoop:\n"
@ -178,7 +178,7 @@ namespace CPU
{ {
do do
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("hlt"); asmv("hlt");
#elif defined(aa64) #elif defined(aa64)
asmv("wfe"); asmv("wfe");

View File

@ -26,7 +26,7 @@ namespace CPU
{ {
SafeFunction static inline void Barrier() SafeFunction static inline void Barrier()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("" :: asmv("" ::
: "memory"); : "memory");
#elif defined(aa64) #elif defined(aa64)
@ -37,7 +37,7 @@ namespace CPU
SafeFunction static inline void Fence() SafeFunction static inline void Fence()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("mfence" :: asmv("mfence" ::
: "memory"); : "memory");
#elif defined(aa64) #elif defined(aa64)
@ -48,7 +48,7 @@ namespace CPU
SafeFunction static inline void StoreFence() SafeFunction static inline void StoreFence()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("sfence" :: asmv("sfence" ::
: "memory"); : "memory");
#elif defined(aa64) #elif defined(aa64)
@ -59,7 +59,7 @@ namespace CPU
SafeFunction static inline void LoadFence() SafeFunction static inline void LoadFence()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("lfence" :: asmv("lfence" ::
: "memory"); : "memory");
#elif defined(aa64) #elif defined(aa64)

View File

@ -38,12 +38,12 @@ namespace CPU
/** @brief Basic CPU information */ /** @brief Basic CPU information */
struct CPUID0x00000000 struct CPUID0x00000000
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x0));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -91,9 +91,9 @@ namespace CPU
/** @brief Additional CPU information */ /** @brief Additional CPU information */
struct CPUID0x00000001 struct CPUID0x00000001
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x1));
@ -207,12 +207,12 @@ namespace CPU
/** @brief Monitor and MWait Features */ /** @brief Monitor and MWait Features */
struct CPUID0x00000005 struct CPUID0x00000005
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x5));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -264,12 +264,12 @@ namespace CPU
/** @brief Power Management Related Features */ /** @brief Power Management Related Features */
struct CPUID0x00000006 struct CPUID0x00000006
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x6));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -320,12 +320,12 @@ namespace CPU
/** @brief Structured Extended Feature Identifiers */ /** @brief Structured Extended Feature Identifiers */
struct CPUID0x00000007 struct CPUID0x00000007
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x7));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -408,12 +408,12 @@ namespace CPU
/** @brief Thread Level - Extended Topology Enumeration */ /** @brief Thread Level - Extended Topology Enumeration */
struct CPUID0x0000000B_ECX_0 struct CPUID0x0000000B_ECX_0
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xB), "c"(0x0));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -465,12 +465,12 @@ namespace CPU
/** @brief Core Level - Extended Topology Enumeration */ /** @brief Core Level - Extended Topology Enumeration */
struct CPUID0x0000000B_ECX_1 struct CPUID0x0000000B_ECX_1
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xB), "c"(0x1));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -522,12 +522,12 @@ namespace CPU
/** @brief Processor Extended State Enumeration */ /** @brief Processor Extended State Enumeration */
struct CPUID0x0000000D_ECX_0 struct CPUID0x0000000D_ECX_0
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xD), "c"(0x0));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -575,12 +575,12 @@ namespace CPU
/** @brief Processor Extended State Enumeration */ /** @brief Processor Extended State Enumeration */
struct CPUID0x0000000D_ECX_1 struct CPUID0x0000000D_ECX_1
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xD), "c"(0x1));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -645,12 +645,12 @@ namespace CPU
/** @brief Processor Extended State Enumeration */ /** @brief Processor Extended State Enumeration */
struct CPUID0x0000000D_ECX_2 struct CPUID0x0000000D_ECX_2
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xD), "c"(0x2));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -698,12 +698,66 @@ namespace CPU
/** @brief Processor Extended State Emulation */ /** @brief Processor Extended State Emulation */
struct CPUID0x0000000D_ECX_11 struct CPUID0x0000000D_ECX_11
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=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 #endif // a64 || a32
} }
@ -750,14 +804,14 @@ namespace CPU
}; };
/** @brief Processor Extended State Enumeration */ /** @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" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xD), "c"(0x3E));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -805,12 +859,12 @@ namespace CPU
/** @brief Maximum Extended Function Number and Vendor String */ /** @brief Maximum Extended Function Number and Vendor String */
struct CPUID0x80000000 struct CPUID0x80000000
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000000));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -858,12 +912,12 @@ namespace CPU
/** @brief Extended Processor and Processor Feature Identifiers */ /** @brief Extended Processor and Processor Feature Identifiers */
struct CPUID0x80000001 struct CPUID0x80000001
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000001));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -979,12 +1033,12 @@ namespace CPU
/** @brief Extended Processor Name String */ /** @brief Extended Processor Name String */
struct CPUID0x80000002 struct CPUID0x80000002
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000002));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1028,12 +1082,12 @@ namespace CPU
/** @brief Extended Processor Name String */ /** @brief Extended Processor Name String */
struct CPUID0x80000003 struct CPUID0x80000003
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000003));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1077,12 +1131,12 @@ namespace CPU
/** @brief Extended Processor Name String */ /** @brief Extended Processor Name String */
struct CPUID0x80000004 struct CPUID0x80000004
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000004));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1126,12 +1180,12 @@ namespace CPU
/** @brief L1 Cache and TLB Information */ /** @brief L1 Cache and TLB Information */
struct CPUID0x80000005 struct CPUID0x80000005
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000005));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1191,12 +1245,12 @@ namespace CPU
/** @brief L2 Cache and TLB and L3 Cache Information */ /** @brief L2 Cache and TLB and L3 Cache Information */
struct CPUID0x80000006 struct CPUID0x80000006
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000006));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1257,12 +1311,12 @@ namespace CPU
/** @brief Processor Power Management and RAS Capabilities */ /** @brief Processor Power Management and RAS Capabilities */
struct CPUID0x80000007 struct CPUID0x80000007
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000007));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1326,12 +1380,12 @@ namespace CPU
/** @brief Processor Capacity Parameters and Extended Feature Identification */ /** @brief Processor Capacity Parameters and Extended Feature Identification */
struct CPUID0x80000008 struct CPUID0x80000008
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000008));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1413,12 +1467,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000000A struct CPUID0x8000000A
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000000A));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1466,12 +1520,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000019 struct CPUID0x80000019
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000019));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1519,12 +1573,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001A struct CPUID0x8000001A
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001A));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1572,12 +1626,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001B struct CPUID0x8000001B
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001B));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1625,12 +1679,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001C struct CPUID0x8000001C
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001C));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1678,12 +1732,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001D struct CPUID0x8000001D
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001D));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1731,12 +1785,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001E struct CPUID0x8000001E
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001E));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1784,12 +1838,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x8000001F struct CPUID0x8000001F
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000001F));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1837,12 +1891,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000020 struct CPUID0x80000020
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000020));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1890,12 +1944,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000021 struct CPUID0x80000021
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000021));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1943,12 +1997,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000022 struct CPUID0x80000022
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000022));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1996,12 +2050,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000023 struct CPUID0x80000023
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000023));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -2049,12 +2103,12 @@ namespace CPU
/** @brief TODO */ /** @brief TODO */
struct CPUID0x80000026 struct CPUID0x80000026
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000026));
#endif // a64 || a32 #endif // a64 || a32
} }

View File

@ -38,12 +38,12 @@ namespace CPU
/** @brief Basic CPU information */ /** @brief Basic CPU information */
struct CPUID0x00000000 struct CPUID0x00000000
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x0));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -84,9 +84,9 @@ namespace CPU
/** @brief Additional CPU information */ /** @brief Additional CPU information */
struct CPUID0x00000001 struct CPUID0x00000001
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x1));
@ -206,12 +206,12 @@ namespace CPU
/** @brief CPU cache and TLB */ /** @brief CPU cache and TLB */
struct CPUID0x00000002 struct CPUID0x00000002
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x2));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -267,12 +267,12 @@ namespace CPU
/** @brief CPU serial number */ /** @brief CPU serial number */
struct CPUID0x00000003 struct CPUID0x00000003
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x3));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -316,12 +316,12 @@ namespace CPU
/** @brief Cache information */ /** @brief Cache information */
struct CPUID0x00000004_1 struct CPUID0x00000004_1
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x4), "c"(0x1)); /* FIXME */
#endif // a64 || a32 #endif // a64 || a32
} }
@ -373,12 +373,12 @@ namespace CPU
/** @brief MONITOR information */ /** @brief MONITOR information */
struct CPUID0x00000005 struct CPUID0x00000005
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x5));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -431,12 +431,12 @@ namespace CPU
/** @brief Thermal and power management information */ /** @brief Thermal and power management information */
struct CPUID0x00000006 struct CPUID0x00000006
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x6));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -483,12 +483,12 @@ namespace CPU
/** @brief Extended feature flags enumeration */ /** @brief Extended feature flags enumeration */
struct CPUID0x00000007_0 struct CPUID0x00000007_0
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x7), "c"(0x0)); /* FIXME */
#endif // a64 || a32 #endif // a64 || a32
} }
@ -709,12 +709,12 @@ namespace CPU
/** @brief Extended feature flags enumeration */ /** @brief Extended feature flags enumeration */
struct CPUID0x00000007_1 struct CPUID0x00000007_1
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x7), "c"(0x1)); /* FIXME */
#endif // a64 || a32 #endif // a64 || a32
} }
@ -815,12 +815,12 @@ namespace CPU
/** @brief Performance monitors */ /** @brief Performance monitors */
struct CPUID0x0000000A struct CPUID0x0000000A
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0xA));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -876,12 +876,12 @@ namespace CPU
/** @brief Get CPU frequency information */ /** @brief Get CPU frequency information */
struct CPUID0x00000015 struct CPUID0x00000015
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x15));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -937,12 +937,12 @@ namespace CPU
/** @brief Get CPU frequency information */ /** @brief Get CPU frequency information */
struct CPUID0x00000016 struct CPUID0x00000016
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x16));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -998,12 +998,12 @@ namespace CPU
/** @brief Extended CPU information */ /** @brief Extended CPU information */
struct CPUID0x80000000 struct CPUID0x80000000
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000000));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1048,12 +1048,12 @@ namespace CPU
/** @brief Extended CPU information */ /** @brief Extended CPU information */
struct CPUID0x80000001 struct CPUID0x80000001
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000001));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1105,12 +1105,12 @@ namespace CPU
/** @brief CPU brand string */ /** @brief CPU brand string */
struct CPUID0x80000002 struct CPUID0x80000002
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000002));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1155,12 +1155,12 @@ namespace CPU
/** @brief CPU brand string */ /** @brief CPU brand string */
struct CPUID0x80000003 struct CPUID0x80000003
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000003));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1205,12 +1205,12 @@ namespace CPU
/** @brief CPU brand string */ /** @brief CPU brand string */
struct CPUID0x80000004 struct CPUID0x80000004
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000004));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1255,12 +1255,12 @@ namespace CPU
/** @brief CPU cache line information */ /** @brief CPU cache line information */
struct CPUID0x80000006 struct CPUID0x80000006
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000006));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1314,12 +1314,12 @@ namespace CPU
/** @brief Virtual and physical memory size */ /** @brief Virtual and physical memory size */
struct CPUID0x80000008 struct CPUID0x80000008
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x80000008));
#endif // a64 || a32 #endif // a64 || a32
} }
@ -1366,12 +1366,12 @@ namespace CPU
/** @brief Secure virtual machine parameters */ /** @brief Secure virtual machine parameters */
struct CPUID0x8000000A struct CPUID0x8000000A
{ {
void Get() __always_inline inline void Get()
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("cpuid" asmv("cpuid"
: "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw)
: "a"(0x1)); : "a"(0x8000000A));
#endif // a64 || a32 #endif // a64 || a32
} }

View File

@ -109,7 +109,7 @@ namespace Video
{ {
private: private:
BootInfo::FramebufferInfo framebuffer; BootInfo::FramebufferInfo framebuffer;
Font *CurrentFont; Font *CurrentFont = nullptr;
ScreenBuffer Buffers[256]; ScreenBuffer Buffers[256];
bool ColorIteration = false; bool ColorIteration = false;
int ColorPickerIteration = 0; int ColorPickerIteration = 0;

View File

@ -52,7 +52,7 @@ namespace Driver
void *Address = nullptr; void *Address = nullptr;
void *InterruptCallback = nullptr; void *InterruptCallback = nullptr;
Memory::MemMgr *MemTrk = nullptr; Memory::MemMgr *MemTrk = nullptr;
DriverInterruptHook *InterruptHook[16] = {nullptr}; DriverInterruptHook *InterruptHook[16]{};
}; };
class DriverInterruptHook : public Interrupts::Handler class DriverInterruptHook : public Interrupts::Handler

View File

@ -21,7 +21,7 @@
#include <types.h> #include <types.h>
#include <debug.h> #include <debug.h>
#if defined(a64) || defined(a32) #if defined(a86)
#define MMX_FN_ATTR __always_inline __target("mmx") #define MMX_FN_ATTR __always_inline __target("mmx")
#define SSE_FN_ATTR __always_inline __target("sse") #define SSE_FN_ATTR __always_inline __target("sse")
#define SSE2_FN_ATTR __always_inline __target("sse2") #define SSE2_FN_ATTR __always_inline __target("sse2")
@ -86,7 +86,7 @@ namespace SMAP
{ {
void _clac(void) void _clac(void)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("clac" :: asmv("clac" ::
: "cc"); : "cc");
#endif // a64 || a32 #endif // a64 || a32
@ -94,7 +94,7 @@ namespace SMAP
void _stac(void) void _stac(void)
{ {
#if defined(a64) || defined(a32) #if defined(a86)
asmv("stac" :: asmv("stac" ::
: "cc"); : "cc");
#endif // a64 || a32 #endif // a64 || a32
@ -103,7 +103,7 @@ namespace SMAP
namespace MMX namespace MMX
{ {
#if defined(a64) || defined(a32) #if defined(a86)
typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8))); typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8)));
typedef long long __v1di __attribute__((__vector_size__(8))); typedef long long __v1di __attribute__((__vector_size__(8)));
@ -120,7 +120,7 @@ namespace MMX
namespace SSE namespace SSE
{ {
#if defined(a64) || defined(a32) #if defined(a86)
typedef int __v4si __attribute__((__vector_size__(16))); typedef int __v4si __attribute__((__vector_size__(16)));
typedef unsigned int __v4su __attribute__((__vector_size__(16))); typedef unsigned int __v4su __attribute__((__vector_size__(16)));
typedef float __v4sf __attribute__((__vector_size__(16))); typedef float __v4sf __attribute__((__vector_size__(16)));
@ -144,7 +144,7 @@ namespace SSE
namespace SSE2 namespace SSE2
{ {
#if defined(a64) || defined(a32) #if defined(a86)
typedef double __v2df __attribute__((__vector_size__(16))); typedef double __v2df __attribute__((__vector_size__(16)));
typedef long long __v2di __attribute__((__vector_size__(16))); typedef long long __v2di __attribute__((__vector_size__(16)));
@ -205,19 +205,19 @@ namespace SSE2
namespace SSE3 namespace SSE3
{ {
#if defined(a64) || defined(a32) #if defined(a86)
#endif // a64 || a32 #endif // a64 || a32
} }
namespace SSSE3 namespace SSSE3
{ {
#if defined(a64) || defined(a32) #if defined(a86)
#endif // a64 || a32 #endif // a64 || a32
} }
namespace SSE4_1 namespace SSE4_1
{ {
#if defined(a64) || defined(a32) #if defined(a86)
typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16))); typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16)));
ST_IN SSE4_1_FN_ATTR __m128i _mm_cvtepu8_epi32(__m128i a); ST_IN SSE4_1_FN_ATTR __m128i _mm_cvtepu8_epi32(__m128i a);
@ -229,19 +229,19 @@ namespace SSE4_1
namespace SSE4_2 namespace SSE4_2
{ {
#if defined(a64) || defined(a32) #if defined(a86)
#endif // a64 || a32 #endif // a64 || a32
} }
namespace AVX namespace AVX
{ {
#if defined(a64) || defined(a32) #if defined(a86)
#endif // a64 || a32 #endif // a64 || a32
} }
namespace AVX2 namespace AVX2
{ {
#if defined(a64) || defined(a32) #if defined(a86)
#endif // a64 || a32 #endif // a64 || a32
} }

View File

@ -20,7 +20,7 @@
#include <types.h> #include <types.h>
#if defined(a64) || defined(a32) #if defined(a86)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@ -232,6 +232,6 @@ extern "C"
#define outw(Port, Data) outportw(Port, Data) #define outw(Port, Data) outportw(Port, Data)
#define outl(Port, Data) outportl(Port, Data) #define outl(Port, Data) outportl(Port, Data)
#endif // defined(a64) || defined(a32) #endif // defined(a86)
#endif // !__FENNIX_KERNEL_IO_H__ #endif // !__FENNIX_KERNEL_IO_H__

View File

@ -62,7 +62,7 @@ extern uintptr_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end;
#define USER_STACK_SIZE 0x2000 // 8kb #define USER_STACK_SIZE 0x2000 // 8kb
// To pages // To pages
#define TO_PAGES(d) ((d) / PAGE_SIZE + 1) #define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
// From pages // From pages
#define FROM_PAGES(d) ((d)*PAGE_SIZE) #define FROM_PAGES(d) ((d)*PAGE_SIZE)
@ -436,6 +436,18 @@ namespace Memory
struct PageTable4 struct PageTable4
{ {
PageMapLevel4 Entries[511]; 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); } __aligned(0x1000);
struct __packed PageMapLevel5 struct __packed PageMapLevel5
@ -460,11 +472,6 @@ namespace Memory
uint64_t PageBitmapIndex = 0; uint64_t PageBitmapIndex = 0;
Bitmap PageBitmap; 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: public:
Bitmap GetPageBitmap() { return PageBitmap; } Bitmap GetPageBitmap() { return PageBitmap; }
@ -549,6 +556,11 @@ namespace Memory
*/ */
void LockPages(void *Address, size_t PageCount); 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 * @brief Request page
* *
@ -869,7 +881,6 @@ void operator delete[](void *Pointer, long unsigned int Size);
extern Memory::Physical KernelAllocator; extern Memory::Physical KernelAllocator;
extern Memory::PageTable4 *KernelPageTable; extern Memory::PageTable4 *KernelPageTable;
extern Memory::PageTable4 *UserspaceKernelOnlyPageTable;
#endif // __cplusplus #endif // __cplusplus

View File

@ -45,7 +45,7 @@ struct CPUData
uintptr_t TempStack; /* gs+0x8 */ uintptr_t TempStack; /* gs+0x8 */
/** @brief Used by CPU */ /** @brief Used by CPU */
uintptr_t Stack; uintptr_t Stack; /* gs+0x10 */
/** @brief CPU ID. */ /** @brief CPU ID. */
int ID; int ID;

View File

@ -44,6 +44,9 @@
#define true 1 #define true 1
#define false 0 #define false 0
#define inf_loop while (1)
#define ilp inf_loop; /* Used for debugging */
#ifdef __cplusplus #ifdef __cplusplus
#define foreach for #define foreach for
#define in : #define in :

View File

@ -36,7 +36,7 @@
#include <pci.hpp> #include <pci.hpp>
#endif #endif
extern struct BootInfo *bInfo; extern struct BootInfo bInfo;
extern bool DebuggerIsAttached; extern bool DebuggerIsAttached;
#ifdef __cplusplus #ifdef __cplusplus