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];
binfo.Framebuffer[i].Type = RGB; switch (framebuffer->memory_model)
binfo.Framebuffer[i].BaseAddress = (void *)((uint64_t)framebuffer->address - 0xFFFF800000000000); {
case LIMINE_FRAMEBUFFER_RGB:
binfo.Framebuffer[i].Type = RGB;
break;
default:
{
error("Unsupported framebuffer memory model %d", framebuffer->memory_model);
TerminalResponse->write(TerminalResponse->terminals[0], "Unsupported framebuffer memory model", 37);
inf_loop asmv("hlt");
}
}
binfo.Framebuffer[i].BaseAddress = (void *)((uintptr_t)framebuffer->address - 0xFFFF800000000000);
binfo.Framebuffer[i].Width = (uint32_t)framebuffer->width; binfo.Framebuffer[i].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"
@ -148,25 +150,25 @@ 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"); \
} }
/* ISR */ /* ISR */
@ -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);
// FIXME: I don't think this is reporting correctly. This has to be fixed asap.
debug("Enabling UMIP, SMEP & SMAP support...");
uint32_t eax, ebx, ecx, edx;
x64::cpuid(0x1, &eax, &ebx, &ecx, &edx);
if (edx & (1 << 2)) // https://en.wikipedia.org/wiki/Control_register
{
if (!BSP)
KPrint("UMIP is supported.");
debug("UMIP is supported.");
// cr4.UMIP = 1;
}
if (edx & (1 << 7)) // https://en.wikipedia.org/wiki/Control_register#SMEP
// https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf
{
if (!BSP)
KPrint("SMEP is supported.");
debug("SMEP is supported.");
// cr4.SMEP = 1;
}
if (edx & (1 << 20)) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
{
if (!BSP)
KPrint("SMAP is supported.");
debug("SMAP is supported.");
// cr4.SMAP = 1;
}
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 && if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
{ {
debug("Writing CR4..."); // FIXME: I don't think this is reporting correctly. This has to be fixed asap.
x64::writecr4(cr4); debug("Enabling UMIP, SMEP & SMAP support...");
debug("Wrote CR4."); if (UMIPSupport)
{
if (!BSP)
KPrint("UMIP is supported.");
debug("UMIP is supported.");
// cr4.UMIP = 1;
}
if (SMEPSupport)
{
if (!BSP)
KPrint("SMEP is supported.");
debug("SMEP is supported.");
// cr4.SMEP = 1;
}
if (SMAPSupport)
{
if (!BSP)
KPrint("SMAP is supported.");
debug("SMAP is supported.");
// cr4.SMAP = 1;
}
} }
else 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

@ -1,18 +1,18 @@
/* /*
This file is part of Fennix Kernel. This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful, Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
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/>.
*/ */
#include "kernel.h" #include "kernel.h"
@ -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