mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 15:29:18 +00:00
QoL and bug fixes
This commit is contained in:
193
Core/CPU.cpp
193
Core/CPU.cpp
@ -30,19 +30,21 @@ namespace CPU
|
||||
|
||||
char *Vendor()
|
||||
{
|
||||
static char Vendor[13];
|
||||
static char Vendor[13] = {0};
|
||||
if (Vendor[0] != 0)
|
||||
return Vendor;
|
||||
#if defined(a64)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x64::cpuid(0x0, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Vendor + 0, &ebx, 4);
|
||||
memcpy_unsafe(Vendor + 4, &edx, 4);
|
||||
memcpy_unsafe(Vendor + 8, &ecx, 4);
|
||||
memcpy(Vendor + 0, &ebx, 4);
|
||||
memcpy(Vendor + 4, &edx, 4);
|
||||
memcpy(Vendor + 8, &ecx, 4);
|
||||
#elif defined(a32)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x32::cpuid(0x0, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Vendor + 0, &ebx, 4);
|
||||
memcpy_unsafe(Vendor + 4, &edx, 4);
|
||||
memcpy_unsafe(Vendor + 8, &ecx, 4);
|
||||
memcpy(Vendor + 0, &ebx, 4);
|
||||
memcpy(Vendor + 4, &edx, 4);
|
||||
memcpy(Vendor + 8, &ecx, 4);
|
||||
#elif defined(aa64)
|
||||
asmv("mrs %0, MIDR_EL1"
|
||||
: "=r"(Vendor[0]));
|
||||
@ -52,41 +54,43 @@ namespace CPU
|
||||
|
||||
char *Name()
|
||||
{
|
||||
static char Name[49];
|
||||
static char Name[49] = {0};
|
||||
if (Name[0] != 0)
|
||||
return Name;
|
||||
#if defined(a64)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x64::cpuid(0x80000002, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 0, &eax, 4);
|
||||
memcpy_unsafe(Name + 4, &ebx, 4);
|
||||
memcpy_unsafe(Name + 8, &ecx, 4);
|
||||
memcpy_unsafe(Name + 12, &edx, 4);
|
||||
memcpy(Name + 0, &eax, 4);
|
||||
memcpy(Name + 4, &ebx, 4);
|
||||
memcpy(Name + 8, &ecx, 4);
|
||||
memcpy(Name + 12, &edx, 4);
|
||||
x64::cpuid(0x80000003, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 16, &eax, 4);
|
||||
memcpy_unsafe(Name + 20, &ebx, 4);
|
||||
memcpy_unsafe(Name + 24, &ecx, 4);
|
||||
memcpy_unsafe(Name + 28, &edx, 4);
|
||||
memcpy(Name + 16, &eax, 4);
|
||||
memcpy(Name + 20, &ebx, 4);
|
||||
memcpy(Name + 24, &ecx, 4);
|
||||
memcpy(Name + 28, &edx, 4);
|
||||
x64::cpuid(0x80000004, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 32, &eax, 4);
|
||||
memcpy_unsafe(Name + 36, &ebx, 4);
|
||||
memcpy_unsafe(Name + 40, &ecx, 4);
|
||||
memcpy_unsafe(Name + 44, &edx, 4);
|
||||
memcpy(Name + 32, &eax, 4);
|
||||
memcpy(Name + 36, &ebx, 4);
|
||||
memcpy(Name + 40, &ecx, 4);
|
||||
memcpy(Name + 44, &edx, 4);
|
||||
#elif defined(a32)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x32::cpuid(0x80000002, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 0, &eax, 4);
|
||||
memcpy_unsafe(Name + 4, &ebx, 4);
|
||||
memcpy_unsafe(Name + 8, &ecx, 4);
|
||||
memcpy_unsafe(Name + 12, &edx, 4);
|
||||
memcpy(Name + 0, &eax, 4);
|
||||
memcpy(Name + 4, &ebx, 4);
|
||||
memcpy(Name + 8, &ecx, 4);
|
||||
memcpy(Name + 12, &edx, 4);
|
||||
x32::cpuid(0x80000003, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 16, &eax, 4);
|
||||
memcpy_unsafe(Name + 20, &ebx, 4);
|
||||
memcpy_unsafe(Name + 24, &ecx, 4);
|
||||
memcpy_unsafe(Name + 28, &edx, 4);
|
||||
memcpy(Name + 16, &eax, 4);
|
||||
memcpy(Name + 20, &ebx, 4);
|
||||
memcpy(Name + 24, &ecx, 4);
|
||||
memcpy(Name + 28, &edx, 4);
|
||||
x32::cpuid(0x80000004, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Name + 32, &eax, 4);
|
||||
memcpy_unsafe(Name + 36, &ebx, 4);
|
||||
memcpy_unsafe(Name + 40, &ecx, 4);
|
||||
memcpy_unsafe(Name + 44, &edx, 4);
|
||||
memcpy(Name + 32, &eax, 4);
|
||||
memcpy(Name + 36, &ebx, 4);
|
||||
memcpy(Name + 40, &ecx, 4);
|
||||
memcpy(Name + 44, &edx, 4);
|
||||
#elif defined(aa64)
|
||||
asmv("mrs %0, MIDR_EL1"
|
||||
: "=r"(Name[0]));
|
||||
@ -96,19 +100,21 @@ namespace CPU
|
||||
|
||||
char *Hypervisor()
|
||||
{
|
||||
static char Hypervisor[13];
|
||||
static char Hypervisor[13] = {0};
|
||||
if (Hypervisor[0] != 0)
|
||||
return Hypervisor;
|
||||
#if defined(a64)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Hypervisor + 0, &ebx, 4);
|
||||
memcpy_unsafe(Hypervisor + 4, &ecx, 4);
|
||||
memcpy_unsafe(Hypervisor + 8, &edx, 4);
|
||||
memcpy(Hypervisor + 0, &ebx, 4);
|
||||
memcpy(Hypervisor + 4, &ecx, 4);
|
||||
memcpy(Hypervisor + 8, &edx, 4);
|
||||
#elif defined(a32)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x64::cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||
memcpy_unsafe(Hypervisor + 0, &ebx, 4);
|
||||
memcpy_unsafe(Hypervisor + 4, &ecx, 4);
|
||||
memcpy_unsafe(Hypervisor + 8, &edx, 4);
|
||||
memcpy(Hypervisor + 0, &ebx, 4);
|
||||
memcpy(Hypervisor + 4, &ecx, 4);
|
||||
memcpy(Hypervisor + 8, &edx, 4);
|
||||
#elif defined(aa64)
|
||||
asmv("mrs %0, MIDR_EL1"
|
||||
: "=r"(Hypervisor[0]));
|
||||
@ -141,7 +147,7 @@ namespace CPU
|
||||
}
|
||||
case Enable:
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asmv("sti");
|
||||
#elif defined(aa64)
|
||||
asmv("msr daifclr, #2");
|
||||
@ -150,7 +156,7 @@ namespace CPU
|
||||
}
|
||||
case Disable:
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asmv("cli");
|
||||
#elif defined(aa64)
|
||||
asmv("msr daifset, #2");
|
||||
@ -195,30 +201,41 @@ namespace CPU
|
||||
|
||||
void InitializeFeatures(long Core)
|
||||
{
|
||||
#if defined(a64)
|
||||
bool PGESupport = false;
|
||||
bool SSESupport = false;
|
||||
#if defined(a64)
|
||||
bool UMIPSupport = false;
|
||||
bool SMEPSupport = false;
|
||||
bool SMAPSupport = false;
|
||||
|
||||
static int BSP = 0;
|
||||
x64::CR0 cr0 = x64::readcr0();
|
||||
x64::CR4 cr4 = x64::readcr4();
|
||||
|
||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||
{
|
||||
CPU::x86::AMD::CPUID0x00000001 cpuid;
|
||||
cpuid.Get();
|
||||
if (cpuid.EDX.PGE)
|
||||
PGESupport = true;
|
||||
if (cpuid.EDX.SSE)
|
||||
SSESupport = true;
|
||||
CPU::x86::AMD::CPUID0x00000001 cpuid1;
|
||||
CPU::x86::AMD::CPUID0x00000007 cpuid7;
|
||||
cpuid1.Get();
|
||||
cpuid7.Get();
|
||||
|
||||
PGESupport = cpuid1.EDX.PGE;
|
||||
SSESupport = cpuid1.EDX.SSE;
|
||||
SMEPSupport = cpuid7.EBX.SMEP;
|
||||
SMAPSupport = cpuid7.EBX.SMAP;
|
||||
UMIPSupport = cpuid7.ECX.UMIP;
|
||||
}
|
||||
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
|
||||
{
|
||||
CPU::x86::Intel::CPUID0x00000001 cpuid;
|
||||
cpuid.Get();
|
||||
if (cpuid.EDX.PGE)
|
||||
PGESupport = true;
|
||||
if (cpuid.EDX.SSE)
|
||||
SSESupport = true;
|
||||
CPU::x86::Intel::CPUID0x00000001 cpuid1;
|
||||
CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0;
|
||||
cpuid1.Get();
|
||||
cpuid7_0.Get();
|
||||
PGESupport = cpuid1.EDX.PGE;
|
||||
SSESupport = cpuid1.EDX.SSE;
|
||||
SMEPSupport = cpuid7_0.EBX.SMEP;
|
||||
SMAPSupport = cpuid7_0.EBX.SMAP;
|
||||
UMIPSupport = cpuid7_0.ECX.UMIP;
|
||||
}
|
||||
|
||||
if (Config.SIMD == false)
|
||||
@ -251,7 +268,7 @@ namespace CPU
|
||||
cr4.OSXMMEXCPT = 1;
|
||||
|
||||
CPUData *CoreData = GetCPU(Core);
|
||||
CoreData->Data.FPU = (CPU::x64::FXState *)KernelAllocator.RequestPages(TO_PAGES(sizeof(CPU::x64::FXState)));
|
||||
CoreData->Data.FPU = (CPU::x64::FXState *)KernelAllocator.RequestPages(TO_PAGES(sizeof(CPU::x64::FXState) + 1));
|
||||
memset(CoreData->Data.FPU, 0, FROM_PAGES(TO_PAGES(sizeof(CPU::x64::FXState))));
|
||||
CoreData->Data.FPU->mxcsr = 0b0001111110000000;
|
||||
CoreData->Data.FPU->mxcsrmask = 0b1111111110111111;
|
||||
@ -261,47 +278,40 @@ namespace CPU
|
||||
SSEEnableAfter = true;
|
||||
}
|
||||
|
||||
if (!BSP)
|
||||
KPrint("Enabling CPU cache.");
|
||||
|
||||
cr0.NW = 0;
|
||||
cr0.CD = 0;
|
||||
cr0.WP = 1;
|
||||
|
||||
x64::writecr0(cr0);
|
||||
|
||||
// FIXME: I don't think this is reporting correctly. This has to be fixed asap.
|
||||
debug("Enabling UMIP, SMEP & SMAP support...");
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
x64::cpuid(0x1, &eax, &ebx, &ecx, &edx);
|
||||
if (edx & (1 << 2)) // https://en.wikipedia.org/wiki/Control_register
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("UMIP is supported.");
|
||||
debug("UMIP is supported.");
|
||||
// cr4.UMIP = 1;
|
||||
}
|
||||
if (edx & (1 << 7)) // https://en.wikipedia.org/wiki/Control_register#SMEP
|
||||
// https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMEP is supported.");
|
||||
debug("SMEP is supported.");
|
||||
// cr4.SMEP = 1;
|
||||
}
|
||||
if (edx & (1 << 20)) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMAP is supported.");
|
||||
debug("SMAP is supported.");
|
||||
// cr4.SMAP = 1;
|
||||
}
|
||||
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
|
||||
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
|
||||
{
|
||||
debug("Writing CR4...");
|
||||
x64::writecr4(cr4);
|
||||
debug("Wrote CR4.");
|
||||
// FIXME: I don't think this is reporting correctly. This has to be fixed asap.
|
||||
debug("Enabling UMIP, SMEP & SMAP support...");
|
||||
if (UMIPSupport)
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("UMIP is supported.");
|
||||
debug("UMIP is supported.");
|
||||
// cr4.UMIP = 1;
|
||||
}
|
||||
|
||||
if (SMEPSupport)
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMEP is supported.");
|
||||
debug("SMEP is supported.");
|
||||
// cr4.SMEP = 1;
|
||||
}
|
||||
|
||||
if (SMAPSupport)
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMAP is supported.");
|
||||
debug("SMAP is supported.");
|
||||
// cr4.SMAP = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -313,6 +323,11 @@ namespace CPU
|
||||
KPrint("QEMU (TCG) detected. Not using UMIP, SMEP & SMAP");
|
||||
}
|
||||
}
|
||||
|
||||
debug("Writing CR4...");
|
||||
x64::writecr4(cr4);
|
||||
debug("Wrote CR4.");
|
||||
|
||||
debug("Enabling PAT support...");
|
||||
x64::wrmsr(x64::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16));
|
||||
if (!BSP++)
|
||||
@ -352,7 +367,7 @@ namespace CPU
|
||||
|
||||
// return SIMD_SSE;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
static uint64_t SIMDType = SIMD_NONE;
|
||||
|
||||
if (likely(SIMDType != SIMD_NONE))
|
||||
@ -434,7 +449,7 @@ namespace CPU
|
||||
if (unlikely(!SSEEnabled))
|
||||
return false;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||
{
|
||||
CPU::x86::AMD::CPUID0x00000001 cpuid;
|
||||
|
@ -375,7 +375,7 @@ namespace CrashHandler
|
||||
int tmpidx = SBIdx;
|
||||
SBIdx = atoi(arg);
|
||||
Display->SetBuffer(SBIdx);
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
for (int i = 0; i < 5000000; i++)
|
||||
inb(0x80);
|
||||
#endif // a64 || a32
|
||||
@ -415,7 +415,7 @@ namespace CrashHandler
|
||||
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i]));
|
||||
else
|
||||
EHPrint("\eFF4CA9Outside Kernel");
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
for (int i = 0; i < 20000; i++)
|
||||
inb(0x80);
|
||||
#endif // a64 || a32
|
||||
@ -624,7 +624,7 @@ namespace CrashHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
GlobalDescriptorTable::TaskStateSegment tss = GlobalDescriptorTable::tss[TSSIndex];
|
||||
EHPrint("\eFAFAFAStack Pointer 0: \eAABB22%#lx\n", tss.StackPointer[0]);
|
||||
EHPrint("\eFAFAFAStack Pointer 1: \eAABB22%#lx\n", tss.StackPointer[1]);
|
||||
@ -779,7 +779,7 @@ namespace CrashHandler
|
||||
|
||||
SafeFunction void StopAllCores()
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
/* FIXME: Can't send IPIs to other cores
|
||||
* because it causes another exception on
|
||||
* the other cores.
|
||||
|
@ -96,7 +96,7 @@ namespace CrashHandler
|
||||
{
|
||||
CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
while (inb(0x64) & 0x1)
|
||||
inb(0x60);
|
||||
|
||||
@ -109,7 +109,7 @@ namespace CrashHandler
|
||||
|
||||
outb(0x21, 0xFD);
|
||||
outb(0xA1, 0xFF);
|
||||
#endif // defined(a64) || defined(a32)
|
||||
#endif // defined(a86)
|
||||
|
||||
CPU::Interrupts(CPU::Enable); // Just to be sure.
|
||||
}
|
||||
@ -130,7 +130,7 @@ namespace CrashHandler
|
||||
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame)
|
||||
#endif
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
UNUSED(Frame);
|
||||
uint8_t scanCode = inb(0x60);
|
||||
if (scanCode == KEY_D_TAB ||
|
||||
@ -184,7 +184,7 @@ namespace CrashHandler
|
||||
SafeFunction void HookKeyboard()
|
||||
{
|
||||
CrashKeyboardDriver kbd; // We don't want to allocate memory.
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;");
|
||||
#elif defined(aa64)
|
||||
asmv("KeyboardHookLoop: nop; b KeyboardHookLoop;");
|
||||
|
@ -87,7 +87,7 @@ namespace CrashHandler
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", data.cr0.raw, data.cr2.raw, data.cr3.raw, data.cr4.raw, data.cr8.raw);
|
||||
EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", data.dr0, data.dr1, data.dr2, data.dr3, data.dr6, data.dr7.raw);
|
||||
|
||||
@ -136,7 +136,7 @@ namespace CrashHandler
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
EHPrint("\eA0F0F0DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s\n LDR2:%s GDR2:%s LDR3:%s GDR3:%s\n CDR0:%s SDR0:%s CDR1:%s SDR1:%s\n CDR2:%s SDR2:%s CDR3:%s SDR3:%s\n R:%#x\n",
|
||||
data.dr7.LocalDR0 ? "True " : "False", data.dr7.GlobalDR0 ? "True " : "False", data.dr7.LocalDR1 ? "True " : "False", data.dr7.GlobalDR1 ? "True " : "False",
|
||||
data.dr7.LocalDR2 ? "True " : "False", data.dr7.GlobalDR2 ? "True " : "False", data.dr7.LocalDR3 ? "True " : "False", data.dr7.GlobalDR3 ? "True " : "False",
|
||||
|
@ -99,7 +99,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw);
|
||||
|
||||
error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x",
|
||||
@ -113,7 +113,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
|
||||
error("CR3: PWT:%s PCD:%s PDBR:%#llx",
|
||||
cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR);
|
||||
#endif // defined(a64) || defined(a32)
|
||||
#endif // defined(a86)
|
||||
|
||||
#if defined(a64)
|
||||
error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x",
|
||||
@ -133,9 +133,9 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
cr4.Reserved0, cr4.Reserved1);
|
||||
#endif
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
error("CR8: TPL:%d", cr8.TPL);
|
||||
#endif // defined(a64) || defined(a32)
|
||||
#endif // defined(a86)
|
||||
|
||||
#if defined(a64)
|
||||
error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x",
|
||||
@ -156,7 +156,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x",
|
||||
efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False",
|
||||
efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False",
|
||||
|
@ -28,21 +28,17 @@ namespace Disk
|
||||
{
|
||||
void Manager::FetchDisks(unsigned long DriverUID)
|
||||
{
|
||||
KernelCallback *callback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback)));
|
||||
memset(callback, 0, sizeof(KernelCallback));
|
||||
callback->Reason = FetchReason;
|
||||
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||
this->AvailablePorts = callback->DiskCallback.Fetch.Ports;
|
||||
this->BytesPerSector = callback->DiskCallback.Fetch.BytesPerSector;
|
||||
KernelCallback callback{};
|
||||
callback.Reason = FetchReason;
|
||||
DriverManager->IOCB(DriverUID, (void *)&callback);
|
||||
this->AvailablePorts = callback.DiskCallback.Fetch.Ports;
|
||||
this->BytesPerSector = callback.DiskCallback.Fetch.BytesPerSector;
|
||||
debug("AvailablePorts:%ld BytesPerSector:%ld", this->AvailablePorts, this->BytesPerSector);
|
||||
|
||||
if (this->AvailablePorts <= 0)
|
||||
{
|
||||
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback)));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector));
|
||||
uint8_t *RWBuffer = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(this->BytesPerSector + 1));
|
||||
|
||||
for (unsigned char ItrPort = 0; ItrPort < this->AvailablePorts; ItrPort++)
|
||||
{
|
||||
@ -53,16 +49,15 @@ namespace Disk
|
||||
drive->MechanicalDisk = true;
|
||||
|
||||
memset(RWBuffer, 0, this->BytesPerSector);
|
||||
memset(callback, 0, sizeof(KernelCallback));
|
||||
callback->Reason = ReceiveReason;
|
||||
callback->DiskCallback.RW = {
|
||||
callback.Reason = ReceiveReason;
|
||||
callback.DiskCallback.RW = {
|
||||
.Sector = 0,
|
||||
.SectorCount = 2,
|
||||
.Port = ItrPort,
|
||||
.Buffer = RWBuffer,
|
||||
.Write = false,
|
||||
};
|
||||
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||
DriverManager->IOCB(DriverUID, (void *)&callback);
|
||||
memcpy(&drive->Table, RWBuffer, sizeof(PartitionTable));
|
||||
|
||||
/*
|
||||
@ -77,16 +72,15 @@ namespace Disk
|
||||
for (uint32_t Block = 0; Block < Sectors; Block++)
|
||||
{
|
||||
memset(RWBuffer, 0, this->BytesPerSector);
|
||||
memset(callback, 0, sizeof(KernelCallback));
|
||||
callback->Reason = ReceiveReason;
|
||||
callback->DiskCallback.RW = {
|
||||
callback.Reason = ReceiveReason;
|
||||
callback.DiskCallback.RW = {
|
||||
.Sector = 2 + Block,
|
||||
.SectorCount = 1,
|
||||
.Port = ItrPort,
|
||||
.Buffer = RWBuffer,
|
||||
.Write = false,
|
||||
};
|
||||
DriverManager->IOCB(DriverUID, (void *)callback);
|
||||
DriverManager->IOCB(DriverUID, (void *)&callback);
|
||||
|
||||
for (uint32_t e = 0; e < Entries; e++)
|
||||
{
|
||||
@ -160,8 +154,8 @@ namespace Disk
|
||||
|
||||
drives.push_back(drive);
|
||||
}
|
||||
|
||||
KernelAllocator.FreePages((void *)callback, TO_PAGES(sizeof(KernelCallback)));
|
||||
|
||||
KernelAllocator.FreePages(RWBuffer, TO_PAGES(this->BytesPerSector + 1));
|
||||
}
|
||||
|
||||
Manager::Manager()
|
||||
|
@ -85,6 +85,7 @@ namespace Driver
|
||||
{
|
||||
if (!drv.InterruptHook[j])
|
||||
break;
|
||||
debug("Interrupt hook %#lx", drv.InterruptHook[j]);
|
||||
delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr;
|
||||
}
|
||||
if (drv.MemTrk)
|
||||
@ -106,11 +107,12 @@ namespace Driver
|
||||
debug("Stopping and unloading driver %ld [%#lx]", drv.DriverUID, drv.Address);
|
||||
this->IOCB(drv.DriverUID, (void *)&callback);
|
||||
|
||||
for (size_t i = 0; i < sizeof(drv.InterruptHook) / sizeof(drv.InterruptHook[0]); i++)
|
||||
for (size_t j = 0; j < sizeof(drv.InterruptHook) / sizeof(drv.InterruptHook[0]); j++)
|
||||
{
|
||||
if (!drv.InterruptHook[i])
|
||||
if (!drv.InterruptHook[j])
|
||||
break;
|
||||
delete drv.InterruptHook[i], drv.InterruptHook[i] = nullptr;
|
||||
debug("Interrupt hook %#lx", drv.InterruptHook[j]);
|
||||
delete drv.InterruptHook[j], drv.InterruptHook[j] = nullptr;
|
||||
}
|
||||
delete drv.MemTrk, drv.MemTrk = nullptr;
|
||||
Drivers.remove(i);
|
||||
@ -141,6 +143,7 @@ namespace Driver
|
||||
|
||||
((KernelAPI *)KAPIAddress)->Info.Offset = (unsigned long)fex;
|
||||
((KernelAPI *)KAPIAddress)->Info.DriverUID = DriverUIDs++;
|
||||
((KernelAPI *)KAPIAddress)->Info.KernelDebug = DebuggerIsAttached;
|
||||
|
||||
#ifdef DEBUG
|
||||
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
@ -273,7 +276,7 @@ namespace Driver
|
||||
SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */
|
||||
if (!Handle.InterruptCallback)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
uint64_t IntNum = Frame->InterruptNumber - 32;
|
||||
#elif defined(aa64)
|
||||
uint64_t IntNum = Frame->InterruptNumber;
|
||||
@ -332,7 +335,7 @@ namespace Driver
|
||||
DriverInterruptHook::DriverInterruptHook(int Interrupt, DriverFile Handle) : Interrupts::Handler(Interrupt)
|
||||
{
|
||||
this->Handle = Handle;
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID);
|
||||
#elif defined(aa64)
|
||||
trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID);
|
||||
|
@ -46,7 +46,7 @@ void DriverDisplayPrint(char *String)
|
||||
|
||||
void *RequestPage(unsigned long Size)
|
||||
{
|
||||
void *ret = KernelAllocator.RequestPages(Size);
|
||||
void *ret = KernelAllocator.RequestPages(Size + 1);
|
||||
drvdbg("Allocated %ld pages (%#lx-%#lx)", Size, (unsigned long)ret, (unsigned long)ret + FROM_PAGES(Size));
|
||||
return ret;
|
||||
}
|
||||
@ -54,7 +54,7 @@ void *RequestPage(unsigned long Size)
|
||||
void FreePage(void *Page, unsigned long Size)
|
||||
{
|
||||
drvdbg("Freeing %ld pages (%#lx-%#lx)", Size, (unsigned long)Page, (unsigned long)Page + FROM_PAGES(Size));
|
||||
KernelAllocator.FreePages(Page, Size);
|
||||
KernelAllocator.FreePages(Page, Size + 1);
|
||||
}
|
||||
|
||||
void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
|
||||
@ -164,6 +164,7 @@ KernelAPI KernelAPITemplate = {
|
||||
.Info = {
|
||||
.Offset = 0,
|
||||
.DriverUID = 0,
|
||||
.KernelDebug = false,
|
||||
},
|
||||
.Memory = {
|
||||
.PageSize = PAGE_SIZE,
|
||||
|
@ -59,7 +59,7 @@ namespace Driver
|
||||
DriverCode Driver::BindInputInput(Memory::MemMgr *mem, void *fex)
|
||||
{
|
||||
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback)));
|
||||
KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback) + 1));
|
||||
|
||||
fixme("Input driver: %s", fexExtended->Driver.Name);
|
||||
KCallback->RawPtr = nullptr;
|
||||
@ -100,7 +100,7 @@ namespace Driver
|
||||
UNUSED(DrvExtHdr);
|
||||
UNUSED(IsElf);
|
||||
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory);
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size));
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1));
|
||||
memcpy(fex, (void *)DriverAddress, Size);
|
||||
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size);
|
||||
@ -111,7 +111,7 @@ namespace Driver
|
||||
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
|
||||
kfree(result);
|
||||
#endif
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI)));
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1));
|
||||
|
||||
if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
|
||||
{
|
||||
|
@ -455,7 +455,7 @@ namespace Driver
|
||||
{
|
||||
UNUSED(IsElf);
|
||||
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory);
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size));
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1));
|
||||
memcpy(fex, (void *)DriverAddress, Size);
|
||||
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size);
|
||||
@ -466,7 +466,7 @@ namespace Driver
|
||||
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
|
||||
kfree(result);
|
||||
#endif
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI)));
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1));
|
||||
|
||||
if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
|
||||
{
|
||||
|
@ -576,7 +576,7 @@ namespace Driver
|
||||
{
|
||||
debug("[%ld] VendorID: %#x; DeviceID: %#x", devices.size(), PCIDevice->VendorID, PCIDevice->DeviceID);
|
||||
Memory::MemMgr *mem = new Memory::MemMgr(nullptr, TaskManager->GetCurrentProcess()->memDirectory);
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size));
|
||||
Fex *fex = (Fex *)mem->RequestPages(TO_PAGES(Size + 1));
|
||||
memcpy(fex, (void *)DriverAddress, Size);
|
||||
FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
debug("Driver allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size);
|
||||
@ -587,7 +587,7 @@ namespace Driver
|
||||
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
|
||||
kfree(result);
|
||||
#endif
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI)));
|
||||
KernelAPI *KAPI = (KernelAPI *)mem->RequestPages(TO_PAGES(sizeof(KernelAPI) + 1));
|
||||
|
||||
if (CallDriverEntryPoint(fex, KAPI) != DriverCode::OK)
|
||||
{
|
||||
|
@ -67,16 +67,14 @@ namespace Interrupts
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
|
||||
CoreData->ID = Core;
|
||||
CoreData->IsActive = true;
|
||||
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE);
|
||||
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
|
||||
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE);
|
||||
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
|
||||
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
|
||||
{
|
||||
KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
|
||||
CPU::Stop();
|
||||
}
|
||||
debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);
|
||||
/* TODO: Implement a proper way to set the stack pointer. */
|
||||
// asmv("movq %0, %%rsp" ::"r"(CoreData->Stack));
|
||||
InitializeSystemCalls();
|
||||
#elif defined(a32)
|
||||
warn("i386 is not supported yet");
|
||||
@ -152,7 +150,7 @@ namespace Interrupts
|
||||
bool InterruptHandled = false;
|
||||
foreach (auto ev in RegisteredEvents)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if ((ev.ID + CPU::x86::IRQ0) == static_cast<int>(Frame->InterruptNumber))
|
||||
#elif defined(aa64)
|
||||
if (ev.ID == static_cast<int>(Frame->InterruptNumber))
|
||||
|
@ -20,8 +20,8 @@
|
||||
Xalloc_def;
|
||||
|
||||
#define XALLOC_CONCAT(x, y) x##y
|
||||
#define XStoP(x) (x / Xalloc_PAGE_SIZE + 1)
|
||||
#define XPtoS(x) (x * Xalloc_PAGE_SIZE)
|
||||
#define XStoP(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
|
||||
#define XPtoS(d) ((d)*PAGE_SIZE)
|
||||
#define Xalloc_BlockChecksum 0xA110C
|
||||
|
||||
extern "C" void *Xalloc_REQUEST_PAGES(Xsize_t Pages);
|
||||
@ -70,14 +70,14 @@ namespace Xalloc
|
||||
|
||||
Block(Xsize_t Size)
|
||||
{
|
||||
this->Address = Xalloc_REQUEST_PAGES(XStoP(Size));
|
||||
this->Address = Xalloc_REQUEST_PAGES(XStoP(Size + 1));
|
||||
this->Size = Size;
|
||||
Xmemset(this->Address, 0, Size);
|
||||
}
|
||||
|
||||
~Block()
|
||||
{
|
||||
Xalloc_FREE_PAGES(this->Address, XStoP(this->Size));
|
||||
Xalloc_FREE_PAGES(this->Address, XStoP(this->Size + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,7 +120,7 @@ namespace Xalloc
|
||||
{
|
||||
if (this->SMAPUsed)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asm volatile("stac" ::
|
||||
: "cc");
|
||||
#endif
|
||||
@ -131,7 +131,7 @@ namespace Xalloc
|
||||
{
|
||||
if (this->SMAPUsed)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asm volatile("clac" ::
|
||||
: "cc");
|
||||
#endif
|
||||
@ -209,7 +209,8 @@ namespace Xalloc
|
||||
{
|
||||
if (!CurrentBlock->Check())
|
||||
{
|
||||
Xalloc_err("Block %#lx checksum failed!", (Xuint64_t)CurrentBlock);
|
||||
Xalloc_err("Block %#lx has an invalid checksum! (%#x != %#x)",
|
||||
(Xuint64_t)CurrentBlock, CurrentBlock->Checksum, Xalloc_BlockChecksum);
|
||||
while (Xalloc_StopOnFail)
|
||||
;
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ using namespace Memory;
|
||||
|
||||
Physical KernelAllocator;
|
||||
PageTable4 *KernelPageTable = nullptr;
|
||||
PageTable4 *UserspaceKernelOnlyPageTable = nullptr;
|
||||
bool Page1GBSupport = false;
|
||||
bool PSESupport = false;
|
||||
|
||||
@ -102,9 +101,7 @@ NIF void MapFromZero(PageTable4 *PT, BootInfo *Info)
|
||||
else
|
||||
va.Map((void *)0, (void *)0, MemSize, PTFlag::RW);
|
||||
|
||||
void *NullAddress = KernelAllocator.RequestPage();
|
||||
memset(NullAddress, 0, PAGE_SIZE); // TODO: If the CPU instruction pointer hits this page, there should be function to handle it. (memcpy assembly code?)
|
||||
va.Remap((void *)0, (void *)NullAddress, PTFlag::RW | PTFlag::US);
|
||||
va.Unmap((void *)0);
|
||||
}
|
||||
|
||||
NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info)
|
||||
@ -171,7 +168,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
||||
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@ -179,7 +176,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
||||
for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@ -187,7 +184,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
||||
for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@ -195,7 +192,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
||||
for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
@ -203,7 +200,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
||||
for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)k, PTFlag::G);
|
||||
KernelAllocator.LockPage((void *)k);
|
||||
KernelAllocator.ReservePage((void *)k);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -243,8 +240,8 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
|
||||
#ifdef DEBUG
|
||||
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||
{
|
||||
uintptr_t Base = reinterpret_cast<uintptr_t>(Info->Memory.Entry[i].BaseAddress);
|
||||
uintptr_t Length = Info->Memory.Entry[i].Length;
|
||||
uintptr_t Base = r_cst(uintptr_t, Info->Memory.Entry[i].BaseAddress);
|
||||
size_t Length = Info->Memory.Entry[i].Length;
|
||||
uintptr_t End = Base + Length;
|
||||
const char *Type = "Unknown";
|
||||
|
||||
@ -293,12 +290,21 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
|
||||
TO_MB(KernelAllocator.GetTotalMemory()),
|
||||
TO_MB(KernelAllocator.GetReservedMemory()));
|
||||
|
||||
trace("Initializing Virtual Memory Manager");
|
||||
KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE));
|
||||
memset(KernelPageTable, 0, PAGE_SIZE);
|
||||
/* -- Debugging --
|
||||
size_t bmap_size = KernelAllocator.GetPageBitmap().Size;
|
||||
for (size_t i = 0; i < bmap_size; i++)
|
||||
{
|
||||
bool idx = KernelAllocator.GetPageBitmap().Get(i);
|
||||
if (idx == true)
|
||||
debug("Page %04d: %#lx", i, i * PAGE_SIZE);
|
||||
}
|
||||
|
||||
UserspaceKernelOnlyPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE));
|
||||
memset(UserspaceKernelOnlyPageTable, 0, PAGE_SIZE);
|
||||
inf_loop debug("Alloc.: %#lx", KernelAllocator.RequestPage());
|
||||
*/
|
||||
|
||||
trace("Initializing Virtual Memory Manager");
|
||||
KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1));
|
||||
memset(KernelPageTable, 0, PAGE_SIZE);
|
||||
|
||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||
{
|
||||
@ -333,16 +339,11 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
|
||||
MapFramebuffer(KernelPageTable, Info);
|
||||
MapKernel(KernelPageTable, Info);
|
||||
|
||||
memcpy(UserspaceKernelOnlyPageTable, KernelPageTable, sizeof(PageTable4));
|
||||
|
||||
trace("Applying new page table from address %p", KernelPageTable);
|
||||
trace("Applying new page table from address %#lx", KernelPageTable);
|
||||
#ifdef DEBUG
|
||||
debug("Kernel:");
|
||||
tracepagetable(KernelPageTable);
|
||||
debug("Userspace:");
|
||||
tracepagetable(UserspaceKernelOnlyPageTable);
|
||||
#endif
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
asmv("mov %0, %%cr3" ::"r"(KernelPageTable));
|
||||
#elif defined(aa64)
|
||||
asmv("msr ttbr0_el1, %0" ::"r"(KernelPageTable));
|
||||
@ -372,7 +373,7 @@ void *malloc(size_t Size)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
{
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(Size + 1));
|
||||
memset(ret, 0, Size);
|
||||
break;
|
||||
}
|
||||
@ -425,7 +426,7 @@ void *calloc(size_t n, size_t Size)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
{
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(n * Size));
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(n * Size + 1));
|
||||
memset(ret, 0, n * Size);
|
||||
break;
|
||||
}
|
||||
@ -478,7 +479,7 @@ void *realloc(void *Address, size_t Size)
|
||||
{
|
||||
case unlikely(MemoryAllocatorType::Pages):
|
||||
{
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak
|
||||
ret = KernelAllocator.RequestPages(TO_PAGES(Size + 1)); // WARNING: Potential memory leak
|
||||
memset(ret, 0, Size);
|
||||
break;
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ namespace Memory
|
||||
if (unlikely(Address == nullptr))
|
||||
warn("Trying to reserve null address.");
|
||||
|
||||
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
|
||||
uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE;
|
||||
|
||||
if (unlikely(PageBitmap[Index] == true))
|
||||
return;
|
||||
@ -313,7 +313,18 @@ namespace Memory
|
||||
warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
|
||||
|
||||
for (size_t t = 0; t < PageCount; t++)
|
||||
this->ReservePage((void *)((uintptr_t)Address + (t * PAGE_SIZE)));
|
||||
{
|
||||
uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE;
|
||||
|
||||
if (unlikely(PageBitmap[Index] == true))
|
||||
return;
|
||||
|
||||
if (PageBitmap.Set(Index, true))
|
||||
{
|
||||
FreeMemory -= PAGE_SIZE;
|
||||
ReservedMemory += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Physical::UnreservePage(void *Address)
|
||||
@ -321,7 +332,7 @@ namespace Memory
|
||||
if (unlikely(Address == nullptr))
|
||||
warn("Trying to unreserve null address.");
|
||||
|
||||
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
|
||||
uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE;
|
||||
|
||||
if (unlikely(PageBitmap[Index] == false))
|
||||
return;
|
||||
@ -341,7 +352,20 @@ namespace Memory
|
||||
warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : "");
|
||||
|
||||
for (size_t t = 0; t < PageCount; t++)
|
||||
this->UnreservePage((void *)((uintptr_t)Address + (t * PAGE_SIZE)));
|
||||
{
|
||||
uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE;
|
||||
|
||||
if (unlikely(PageBitmap[Index] == false))
|
||||
return;
|
||||
|
||||
if (PageBitmap.Set(Index, false))
|
||||
{
|
||||
FreeMemory += PAGE_SIZE;
|
||||
ReservedMemory -= PAGE_SIZE;
|
||||
if (PageBitmapIndex > Index)
|
||||
PageBitmapIndex = Index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Physical::Init(BootInfo *Info)
|
||||
@ -349,6 +373,7 @@ namespace Memory
|
||||
SmartLock(this->MemoryLock);
|
||||
|
||||
uint64_t MemorySize = Info->Memory.Size;
|
||||
debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize));
|
||||
TotalMemory = MemorySize;
|
||||
FreeMemory = MemorySize;
|
||||
|
||||
@ -381,8 +406,9 @@ namespace Memory
|
||||
CPU::Stop();
|
||||
}
|
||||
|
||||
/* TODO: Read swap config and make the configure the bitmap size correctly */
|
||||
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1;
|
||||
trace("Initializing Bitmap at %llp-%llp (%lld Bytes)",
|
||||
debug("Initializing Bitmap at %llp-%llp (%lld Bytes)",
|
||||
LargestFreeMemorySegment,
|
||||
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
|
||||
BitmapSize);
|
||||
@ -392,16 +418,27 @@ namespace Memory
|
||||
for (size_t i = 0; i < BitmapSize; i++)
|
||||
*(uint8_t *)(PageBitmap.Buffer + i) = 0;
|
||||
|
||||
trace("Reserving pages...");
|
||||
debug("Reserving pages...");
|
||||
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||
{
|
||||
if (Info->Memory.Entry[i].Type != Usable)
|
||||
this->ReservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length));
|
||||
}
|
||||
|
||||
trace("Locking bitmap pages...");
|
||||
this->ReservePages(0, 0x100);
|
||||
this->LockPages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size));
|
||||
/* Making sure that the lower memory area is properly reserved. */
|
||||
this->ReservePages(0, 0x200);
|
||||
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||
{
|
||||
if (Info->Memory.Entry[i].Type == Usable)
|
||||
this->UnreservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length));
|
||||
}
|
||||
|
||||
debug("Reserving pages for SMP...");
|
||||
this->ReservePage((void *)0x0); /* Trampoline stack, gdt, idt, etc... */
|
||||
this->ReservePage((void *)0x2000); /* TRAMPOLINE_START */
|
||||
|
||||
debug("Reserving bitmap pages...");
|
||||
this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size));
|
||||
}
|
||||
|
||||
Physical::Physical() {}
|
||||
|
@ -28,7 +28,7 @@ namespace Memory
|
||||
|
||||
if (this->UserMode)
|
||||
{
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1));
|
||||
memset(AllocatedStack, 0, USER_STACK_SIZE);
|
||||
debug("AllocatedStack: %p", AllocatedStack);
|
||||
|
||||
@ -52,7 +52,7 @@ namespace Memory
|
||||
}
|
||||
else
|
||||
{
|
||||
this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));
|
||||
this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1));
|
||||
memset(this->StackBottom, 0, STACK_SIZE);
|
||||
debug("StackBottom: %p", this->StackBottom);
|
||||
|
||||
@ -70,7 +70,7 @@ namespace Memory
|
||||
StackGuard::~StackGuard()
|
||||
{
|
||||
fixme("Temporarily disabled stack guard deallocation");
|
||||
// KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size));
|
||||
// KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size + 1));
|
||||
// debug("Freed stack at %p", this->StackBottom);
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ namespace Memory
|
||||
}
|
||||
else
|
||||
{
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1));
|
||||
debug("AllocatedStack: %p", AllocatedStack);
|
||||
memset(AllocatedStack, 0, USER_STACK_SIZE);
|
||||
for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
|
||||
|
@ -131,8 +131,8 @@ namespace Memory
|
||||
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
|
||||
if (!PML4->Present)
|
||||
{
|
||||
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr)));
|
||||
memset(PDPTEPtr, 0, PAGE_SIZE);
|
||||
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr) + 1));
|
||||
memset(PDPTEPtr, 0, sizeof(PageDirectoryPointerTableEntryPtr));
|
||||
PML4->Present = true;
|
||||
PML4->SetAddress((uintptr_t)PDPTEPtr >> 12);
|
||||
}
|
||||
@ -153,8 +153,8 @@ namespace Memory
|
||||
PageDirectoryEntryPtr *PDEPtr = nullptr;
|
||||
if (!PDPTE->Present)
|
||||
{
|
||||
PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr)));
|
||||
memset(PDEPtr, 0, PAGE_SIZE);
|
||||
PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr) + 1));
|
||||
memset(PDEPtr, 0, sizeof(PageDirectoryEntryPtr));
|
||||
PDPTE->Present = true;
|
||||
PDPTE->SetAddress((uintptr_t)PDEPtr >> 12);
|
||||
}
|
||||
@ -175,8 +175,8 @@ namespace Memory
|
||||
PageTableEntryPtr *PTEPtr = nullptr;
|
||||
if (!PDE->Present)
|
||||
{
|
||||
PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr)));
|
||||
memset(PTEPtr, 0, PAGE_SIZE);
|
||||
PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr) + 1));
|
||||
memset(PTEPtr, 0, sizeof(PageTableEntryPtr));
|
||||
PDE->Present = true;
|
||||
PDE->SetAddress((uintptr_t)PTEPtr >> 12);
|
||||
}
|
||||
@ -217,7 +217,7 @@ namespace Memory
|
||||
(byte & 0x01 ? '1' : '0')
|
||||
|
||||
if (!this->Check(VirtualAddress, (PTFlag)Flags, Type)) // quick workaround just to see where it fails
|
||||
warn("Failed to map %#lx - %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags));
|
||||
warn("Failed to map v:%#lx p:%#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace Power
|
||||
|
||||
Power::Power()
|
||||
{
|
||||
this->acpi = new ACPI::ACPI(bInfo);
|
||||
this->acpi = new ACPI::ACPI;
|
||||
this->madt = new ACPI::MADT(((ACPI::ACPI *)acpi)->MADT);
|
||||
trace("Power manager initialized");
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace Random
|
||||
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
|
||||
RDRANDFlag = 0;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if (RDRANDFlag)
|
||||
{
|
||||
uint16_t RDRANDValue = 0;
|
||||
@ -74,7 +74,7 @@ namespace Random
|
||||
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
|
||||
RDRANDFlag = 0;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if (RDRANDFlag)
|
||||
{
|
||||
uint32_t RDRANDValue = 0;
|
||||
@ -107,7 +107,7 @@ namespace Random
|
||||
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
|
||||
RDRANDFlag = 0;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if (RDRANDFlag)
|
||||
{
|
||||
uint64_t RDRANDValue = 0;
|
||||
|
@ -60,7 +60,7 @@ EXTERNC __weak __noreturn __no_stack_protector void __stack_chk_fail(void)
|
||||
debug("Current stack check guard value: %#lx", __stack_chk_guard);
|
||||
KPrint("\eFF0000Stack smashing detected!");
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
void *Stack = nullptr;
|
||||
#if defined(a64)
|
||||
asmv("movq %%rsp, %0"
|
||||
@ -87,7 +87,7 @@ EXTERNC __weak __noreturn __no_stack_protector void __chk_fail(void)
|
||||
error("Buffer overflow detected!");
|
||||
KPrint("\eFF0000Buffer overflow detected!");
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
while (1)
|
||||
asmv("cli; hlt");
|
||||
#elif defined(aa64)
|
||||
|
@ -21,22 +21,20 @@
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
/* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf */
|
||||
|
||||
namespace SMBIOS
|
||||
{
|
||||
bool CheckSMBIOS()
|
||||
{
|
||||
if (bInfo->SMBIOSPtr != nullptr && bInfo->SMBIOSPtr < (void *)0xffffffffffff0000)
|
||||
if (bInfo.SMBIOSPtr != nullptr && bInfo.SMBIOSPtr < (void *)0xFFFFFFFFFFFF0000)
|
||||
{
|
||||
debug("SMBIOS is available (%#lx).", bInfo->SMBIOSPtr);
|
||||
debug("SMBIOS is available (%#lx).", bInfo.SMBIOSPtr);
|
||||
return true;
|
||||
}
|
||||
debug("SMBIOS is not available. (%#lx)", bInfo->SMBIOSPtr);
|
||||
debug("SMBIOS is not available. (%#lx)", bInfo.SMBIOSPtr);
|
||||
return false;
|
||||
}
|
||||
|
||||
SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; }
|
||||
SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; }
|
||||
|
||||
static inline int SMBIOSTableLength(SMBIOSHeader *Hdr)
|
||||
{
|
||||
@ -52,7 +50,7 @@ namespace SMBIOS
|
||||
if (!CheckSMBIOS())
|
||||
return nullptr;
|
||||
|
||||
SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo->SMBIOSPtr;
|
||||
SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo.SMBIOSPtr;
|
||||
debug("Getting SMBIOS header for type %d", Type);
|
||||
|
||||
struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress;
|
||||
|
@ -24,7 +24,7 @@ namespace Time
|
||||
Clock ReadClock()
|
||||
{
|
||||
Clock tm;
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
uint32_t t = 0;
|
||||
outb(0x70, 0x00);
|
||||
t = inb(0x71);
|
||||
|
@ -33,7 +33,7 @@ namespace Time
|
||||
{
|
||||
void time::Sleep(uint64_t Milliseconds)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
|
||||
#ifdef DEBUG
|
||||
uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue);
|
||||
@ -52,7 +52,7 @@ namespace Time
|
||||
|
||||
uint64_t time::GetCounter()
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
return mminq(&((HPET *)hpet)->MainCounterValue);
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
@ -60,7 +60,7 @@ namespace Time
|
||||
|
||||
uint64_t time::CalculateTarget(uint64_t Milliseconds)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
return mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
@ -75,7 +75,7 @@ namespace Time
|
||||
ACPI::ACPI *acpi = (ACPI::ACPI *)this->acpi;
|
||||
if (acpi->HPET)
|
||||
{
|
||||
Memory::Virtual().Map((void *)acpi->HPET->Address.Address,
|
||||
Memory::Virtual().Remap((void *)acpi->HPET->Address.Address,
|
||||
(void *)acpi->HPET->Address.Address,
|
||||
Memory::PTFlag::RW | Memory::PTFlag::PCD);
|
||||
this->hpet = (void *)acpi->HPET->Address.Address;
|
||||
|
@ -386,7 +386,8 @@ bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
|
||||
{
|
||||
/* This can be ignored (unaligned memory access) */
|
||||
if (strstr(file, "AdvancedConfigurationAndPowerInterface.cpp") &&
|
||||
(line == 34 && column == 47))
|
||||
((line == 34 && column == 47) ||
|
||||
(line == 36 && column == 47)))
|
||||
return false;
|
||||
|
||||
/* This can be ignored (unaligned memory access) */
|
||||
@ -401,6 +402,9 @@ bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
|
||||
(line == 63 && column == 30))
|
||||
return false;
|
||||
|
||||
if (strstr(file, "liballoc_1_1.c"))
|
||||
return false;
|
||||
|
||||
/* This can be ignored (store address x with insufficient space for object of type 'y') */
|
||||
if (strstr(file, "Task.cpp") && line > 500)
|
||||
return false;
|
||||
|
@ -23,7 +23,7 @@
|
||||
volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
|
||||
std::vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents;
|
||||
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
NIF __always_inline inline uint8_t NoProfiler_inportb(uint16_t Port)
|
||||
{
|
||||
uint8_t Result;
|
||||
@ -56,7 +56,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
|
||||
SafeFunction NIF UART::UART(SerialPorts Port)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
if (Port == COMNULL)
|
||||
return;
|
||||
|
||||
@ -125,7 +125,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
|
||||
SafeFunction NIF void UART::Write(uint8_t Char)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & SERIAL_BUFFER_EMPTY) == 0)
|
||||
;
|
||||
NoProfiler_outportb(Port, Char);
|
||||
@ -137,7 +137,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
|
||||
SafeFunction NIF uint8_t UART::Read()
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
while ((NoProfiler_inportb(s_cst(uint16_t, Port + 5)) & 1) == 0)
|
||||
;
|
||||
return NoProfiler_inportb(Port);
|
||||
@ -146,7 +146,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
{
|
||||
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
||||
{
|
||||
#if defined(a64) || defined(a32)
|
||||
#if defined(a86)
|
||||
e->OnReceived(NoProfiler_inportb(Port));
|
||||
#endif
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace Video
|
||||
|
||||
size_t Size = this->framebuffer.Pitch * Height;
|
||||
|
||||
this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||
this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size + 1));
|
||||
memset(this->Buffers[Index].Buffer, 0, Size);
|
||||
|
||||
this->Buffers[Index].Width = Width;
|
||||
@ -102,7 +102,7 @@ namespace Video
|
||||
return;
|
||||
}
|
||||
|
||||
KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size));
|
||||
KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size + 1));
|
||||
this->Buffers[Index].Buffer = nullptr;
|
||||
this->Buffers[Index].Checksum = 0;
|
||||
debug("Buffer %d deleted", Index);
|
||||
|
@ -33,7 +33,7 @@ namespace Video
|
||||
{
|
||||
this->Info.PSF2Font = new PSF2_FONT;
|
||||
|
||||
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1);
|
||||
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(TO_PAGES(FontDataLength + 1));
|
||||
memcpy((void *)font2, Start, FontDataLength);
|
||||
|
||||
Memory::Virtual().Map((void *)font2, (void *)font2, FontDataLength, Memory::PTFlag::RW);
|
||||
@ -41,7 +41,7 @@ namespace Video
|
||||
if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3)
|
||||
{
|
||||
error("Font2 magic mismatch.");
|
||||
KernelAllocator.FreePages((void *)font2, FontDataLength / PAGE_SIZE + 1);
|
||||
KernelAllocator.FreePages((void *)font2, TO_PAGES(FontDataLength + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user