implemented interrupts handler & stub crash screen

This commit is contained in:
Alex 2022-10-16 20:53:57 +03:00
parent 04757bd11c
commit b8c5c15a47
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
15 changed files with 978 additions and 80 deletions

View File

@ -4,9 +4,7 @@
#include <debug.h>
#include <io.h>
// #include "../timer.h"
// #include "apic.hpp"
// #include "smp.hpp"
#include "cpu/apic.hpp"
#define ACPI_TIMER 0x0001
#define ACPI_BUSMASTER 0x0010
@ -31,7 +29,7 @@ namespace ACPI
#define ACPI_GAS_IO 1
#define ACPI_GAS_PCI 2
void DSDT::SCIHandler(CPU::x64::TrapFrame *regs)
void DSDT::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
{
debug("SCI Handle Triggered");
uint16_t event = this->GetSCIevent();
@ -58,7 +56,7 @@ namespace ACPI
return;
}
}
UNUSED(regs);
UNUSED(Frame);
}
void DSDT::Shutdown()
@ -163,24 +161,12 @@ namespace ACPI
GetSCIevent();
}
void DSDT::InitSCI()
{
// this should be done for all CPUs
if (ACPIShutdownSupported)
{
debug("Registering SCI Handler to vector IRQ%d", acpi->FADT->SCI_Interrupt);
this->RegisterSCIEvents();
// RegisterInterrupt(this->SCIHandler, acpi->FADT->SCI_Interrupt + CPU::x64::IRQ0, true, true);
}
}
DSDT::DSDT(ACPI *acpi)
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt + CPU::x64::IRQ0)
{
uint64_t Address = ((IsCanonical(acpi->FADT->X_Dsdt) && acpi->XSDTSupported) ? acpi->FADT->X_Dsdt : acpi->FADT->Dsdt);
uint8_t *S5Address = (uint8_t *)(Address) + 36;
ACPI::ACPI::ACPIHeader *Header = (ACPI::ACPI::ACPIHeader *)Address;
uint64_t Length = Header->Length;
Address *= 2;
while (Length-- > 0)
{
if (!memcmp(S5Address, "_S5_", 4))
@ -213,6 +199,8 @@ namespace ACPI
SCI_EN = 1;
trace("ACPI Shutdown is supported");
ACPIShutdownSupported = true;
this->RegisterSCIEvents();
((APIC::APIC *)Interrupts::apic)->RedirectIRQ(0, acpi->FADT->SCI_Interrupt, 1);
return;
}
warn("Failed to parse _S5 in ACPI");

View File

@ -246,7 +246,7 @@ namespace ACPI
~MADT();
};
class DSDT
class DSDT : public Interrupts::Handler
{
private:
uint32_t SMI_CMD = 0;
@ -262,10 +262,17 @@ namespace ACPI
ACPI *acpi;
#if defined(__amd64__)
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
#elif defined(__i386__)
void OnInterruptReceived(void *Frame);
#elif defined(__aarch64__)
void OnInterruptReceived(void *Frame);
#endif
public:
bool ACPIShutdownSupported = false;
void SCIHandler(CPU::x64::TrapFrame *regs);
void RegisterSCIEvents();
void SetSCIevent(uint16_t value);
uint16_t GetSCIevent();
@ -273,7 +280,6 @@ namespace ACPI
void Reboot();
void Shutdown();
void InitSCI();
DSDT(ACPI *acpi);
~DSDT();
};

View File

@ -5,21 +5,8 @@
#include "gdt.hpp"
// TODO: IMPLEMENT "MainInterruptHandler"
extern "C" void MainInterruptHandler(void *Data)
{
debug("Interrupt: %p", Data);
asmv("cli");
asmv("hlt");
}
// TODO: IMPLEMENT "ExceptionHandler"
extern "C" void ExceptionHandler(void *Data)
{
debug("Exception: %p", Data);
asmv("cli");
asmv("hlt");
}
extern "C" void MainInterruptHandler(void *Data);
extern "C" void ExceptionHandler(void *Data);
namespace InterruptDescriptorTable
{

View File

@ -70,6 +70,7 @@ extern "C" void StartCPU()
// Initialize GDT and IDT
Interrupts::Initialize(CPU_ID);
((APIC::APIC *)Interrupts::apic)->RedirectIRQs(CPU_ID);
CPU::Interrupts(CPU::Enable);
KPrint("CPU %d is online", CPU_ID);

View File

@ -52,7 +52,6 @@ namespace APIC
void RedirectIRQs(int CPU = 0);
void IPI(uint8_t CPU, uint32_t InterruptNumber);
void OneShot(uint32_t Vector, uint64_t Miliseconds);
bool APICSupported();
uint32_t IOGetMaxRedirect(uint32_t APICID);
void RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
void RedirectIRQ(int CPU, uint8_t IRQ, int Status);

View File

@ -224,41 +224,48 @@ namespace CPU
cr4.OSXMMEXCPT = 1;
}
if (!BSP)
KPrint("Enabling CPU cache.");
// Enable cpu cache but... how to use it?
cr0.NW = 0;
cr0.CD = 0;
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0)
CPU::x64::writecr0(cr0);
debug("Enabling UMIP, SMEP & SMAP support...");
CPU::x64::cpuid(0x1, &rax, &rbx, &rcx, &rdx);
if (rdx & CPU::x64::CPUID_FEAT_RDX_UMIP)
{
debug("Enabling UMIP, SMEP & SMAP support...");
CPU::x64::cpuid(0x1, &rax, &rbx, &rcx, &rdx);
if (rdx & CPU::x64::CPUID_FEAT_RDX_UMIP)
{
if (!BSP)
KPrint("UMIP is supported.");
fixme("Not going to enable UMIP.");
// cr4.UMIP = 1;
}
if (rdx & CPU::x64::CPUID_FEAT_RDX_SMEP)
{
if (!BSP)
KPrint("SMEP is supported.");
cr4.SMEP = 1;
}
if (rdx & CPU::x64::CPUID_FEAT_RDX_SMAP)
{
if (!BSP)
KPrint("SMAP is supported.");
cr4.SMAP = 1;
}
CPU::x64::writecr4(cr4);
if (!BSP)
KPrint("UMIP is supported.");
fixme("Not going to enable UMIP.");
// cr4.UMIP = 1;
}
if (rdx & CPU::x64::CPUID_FEAT_RDX_SMEP)
{
if (!BSP)
KPrint("SMEP is supported.");
cr4.SMEP = 1;
}
if (rdx & CPU::x64::CPUID_FEAT_RDX_SMAP)
{
if (!BSP)
KPrint("SMAP is supported.");
cr4.SMAP = 1;
}
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
CPU::x64::writecr4(cr4);
else
{
if (!BSP)
KPrint("VirtualBox detected. Not using UMIP, SMEP & SMAP");
{
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0)
KPrint("VirtualBox detected. Not using UMIP, SMEP & SMAP");
else if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
KPrint("QEMU (TCG) detected. Not using UMIP, SMEP & SMAP");
}
}
CPU::x64::writecr0(cr0);
debug("Enabling PAT support...");
CPU::x64::wrmsr(CPU::x64::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16));
if (!BSP++)

650
Core/CrashHandler.cpp Normal file
View File

@ -0,0 +1,650 @@
#include "crashhandler.hpp"
#include <display.hpp>
#include <printf.h>
#include <debug.h>
#include <cpu.hpp>
#if defined(__amd64__)
#include "../Architecture/amd64/cpu/gdt.hpp"
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#include "../kernel.h"
#if defined(__amd64__) || defined(__i386__)
static const char *PagefaultDescriptions[] = {
"Supervisory process tried to read a non-present page entry",
"Supervisory process tried to read a page and caused a protection fault",
"Supervisory process tried to write to a non-present page entry",
"Supervisory process tried to write a page and caused a protection fault",
"User process tried to read a non-present page entry",
"User process tried to read a page and caused a protection fault",
"User process tried to write to a non-present page entry",
"User process tried to write a page and caused a protection fault"};
#endif
#if defined(__amd64__)
void DivideByZeroExceptionHandler(CPU::x64::TrapFrame *Frame);
void DebugExceptionHandler(CPU::x64::TrapFrame *Frame);
void NonMaskableInterruptExceptionHandler(CPU::x64::TrapFrame *Frame);
void BreakpointExceptionHandler(CPU::x64::TrapFrame *Frame);
void OverflowExceptionHandler(CPU::x64::TrapFrame *Frame);
void BoundRangeExceptionHandler(CPU::x64::TrapFrame *Frame);
void InvalidOpcodeExceptionHandler(CPU::x64::TrapFrame *Frame);
void DeviceNotAvailableExceptionHandler(CPU::x64::TrapFrame *Frame);
void DoubleFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void CoprocessorSegmentOverrunExceptionHandler(CPU::x64::TrapFrame *Frame);
void InvalidTSSExceptionHandler(CPU::x64::TrapFrame *Frame);
void SegmentNotPresentExceptionHandler(CPU::x64::TrapFrame *Frame);
void StackFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void GeneralProtectionExceptionHandler(CPU::x64::TrapFrame *Frame);
void PageFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void x87FloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame);
void AlignmentCheckExceptionHandler(CPU::x64::TrapFrame *Frame);
void MachineCheckExceptionHandler(CPU::x64::TrapFrame *Frame);
void SIMDFloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame);
void VirtualizationExceptionHandler(CPU::x64::TrapFrame *Frame);
void SecurityExceptionHandler(CPU::x64::TrapFrame *Frame);
void UnknownExceptionHandler(CPU::x64::TrapFrame *Frame);
void UserModeExceptionHandler(CPU::x64::TrapFrame *Frame);
#endif
#ifdef __debug_vscode__
extern "C" int printf_(const char *format, ...);
extern "C" int vprintf_(const char *format, va_list arg);
extern "C" int sprintf_(char *s, const char *format, ...);
#endif
namespace CrashHandler
{
void printfWrapper(char c, void *unused)
{
Display->Print(c, 255, true);
UNUSED(unused);
}
void EHPrint(const char *Format, ...)
{
va_list args;
va_start(args, Format);
vfctprintf(printfWrapper, NULL, Format, args);
va_end(args);
}
void Handle(void *Data)
{
CPU::Interrupts(CPU::Disable);
#if defined(__amd64__)
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
error("Exception: %#lx", Frame->int_num);
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
{
debug("Exception in kernel mode");
Display->CreateBuffer(0, 0, 255);
}
else
{
debug("Exception in user mode");
UserModeExceptionHandler(Frame);
return;
}
debug("Reading control registers...");
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
CPU::x64::CR2 cr2 = CPU::x64::readcr2();
CPU::x64::CR3 cr3 = CPU::x64::readcr3();
CPU::x64::CR4 cr4 = CPU::x64::readcr4();
CPU::x64::CR8 cr8 = CPU::x64::readcr8();
CPU::x64::EFER efer;
efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER);
uint64_t dr0, dr1, dr2, dr3, dr6;
CPU::x64::DR7 dr7;
// store debug registers
debug("Reading debug registers...");
asm volatile("movq %%dr0, %0"
: "=r"(dr0));
asm volatile("movq %%dr1, %0"
: "=r"(dr1));
asm volatile("movq %%dr2, %0"
: "=r"(dr2));
asm volatile("movq %%dr3, %0"
: "=r"(dr3));
asm volatile("movq %%dr6, %0"
: "=r"(dr6));
asm volatile("movq %%dr7, %0"
: "=r"(dr7));
switch (Frame->int_num)
{
case CPU::x64::DivideByZero:
{
DivideByZeroExceptionHandler(Frame);
break;
}
case CPU::x64::Debug:
{
DebugExceptionHandler(Frame);
break;
}
case CPU::x64::NonMaskableInterrupt:
{
NonMaskableInterruptExceptionHandler(Frame);
break;
}
case CPU::x64::Breakpoint:
{
BreakpointExceptionHandler(Frame);
break;
}
case CPU::x64::Overflow:
{
OverflowExceptionHandler(Frame);
break;
}
case CPU::x64::BoundRange:
{
BoundRangeExceptionHandler(Frame);
break;
}
case CPU::x64::InvalidOpcode:
{
InvalidOpcodeExceptionHandler(Frame);
break;
}
case CPU::x64::DeviceNotAvailable:
{
DeviceNotAvailableExceptionHandler(Frame);
break;
}
case CPU::x64::DoubleFault:
{
DoubleFaultExceptionHandler(Frame);
break;
}
case CPU::x64::CoprocessorSegmentOverrun:
{
CoprocessorSegmentOverrunExceptionHandler(Frame);
break;
}
case CPU::x64::InvalidTSS:
{
InvalidTSSExceptionHandler(Frame);
break;
}
case CPU::x64::SegmentNotPresent:
{
SegmentNotPresentExceptionHandler(Frame);
break;
}
case CPU::x64::StackSegmentFault:
{
StackFaultExceptionHandler(Frame);
break;
}
case CPU::x64::GeneralProtectionFault:
{
GeneralProtectionExceptionHandler(Frame);
break;
}
case CPU::x64::PageFault:
{
PageFaultExceptionHandler(Frame);
break;
}
case CPU::x64::x87FloatingPoint:
{
x87FloatingPointExceptionHandler(Frame);
break;
}
case CPU::x64::AlignmentCheck:
{
AlignmentCheckExceptionHandler(Frame);
break;
}
case CPU::x64::MachineCheck:
{
MachineCheckExceptionHandler(Frame);
break;
}
case CPU::x64::SIMDFloatingPoint:
{
SIMDFloatingPointExceptionHandler(Frame);
break;
}
case CPU::x64::Virtualization:
{
VirtualizationExceptionHandler(Frame);
break;
}
case CPU::x64::Security:
{
SecurityExceptionHandler(Frame);
break;
}
default:
{
UnknownExceptionHandler(Frame);
break;
}
}
EHPrint("\e7981FCTechnical Informations on CPU %ld:\n",
CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE));
EHPrint("FS=%#lx GS=%#lx SS=%#lx CS=%#lx DS=%#lx\n",
CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE),
Frame->ss, Frame->cs, Frame->ds);
EHPrint("R8=%#lx R9=%#lx R10=%#lx R11=%#lx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11);
EHPrint("R12=%#lx R13=%#lx R14=%#lx R15=%#lx\n", Frame->r12, Frame->r13, Frame->r14, Frame->r15);
EHPrint("RAX=%#lx RBX=%#lx RCX=%#lx RDX=%#lx\n", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx);
EHPrint("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx\n", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp);
EHPrint("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx\n", Frame->rip, Frame->rflags.raw, Frame->int_num, Frame->error_code, efer.raw);
EHPrint("CR0=%#lx CR2=%#lx CR3=%#lx CR4=%#lx CR8=%#lx\n", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw);
EHPrint("DR0=%#lx DR1=%#lx DR2=%#lx DR3=%#lx DR6=%#lx DR7=%#lx\n", dr0, dr1, dr2, dr3, dr6, dr7.raw);
EHPrint("\eFC797BCR0: PE:%s MP:%s EM:%s TS:%s\n ET:%s NE:%s WP:%s AM:%s\n NW:%s CD:%s PG:%s\n R0:%#x R1:%#x R2:%#x\n",
cr0.PE ? "True " : "False", cr0.MP ? "True " : "False", cr0.EM ? "True " : "False", cr0.TS ? "True " : "False",
cr0.ET ? "True " : "False", cr0.NE ? "True " : "False", cr0.WP ? "True " : "False", cr0.AM ? "True " : "False",
cr0.NW ? "True " : "False", cr0.CD ? "True " : "False", cr0.PG ? "True " : "False",
cr0._reserved0, cr0._reserved1, cr0._reserved2);
EHPrint("\eFCBD79CR2: PFLA: %#lx\n",
cr2.PFLA);
EHPrint("\e79FC84CR3: PWT:%s PCD:%s PDBR:%#lx\n",
cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR);
EHPrint("\eBD79FCCR4: VME:%s PVI:%s TSD:%s DE:%s\n PSE:%s PAE:%s MCE:%s PGE:%s\n PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s\n LA57:%s VMXE:%s SMXE:%s PCIDE:%s\n OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s\n R0:%#x R1:%#x R2:%#x\n",
cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False",
cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False",
cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False",
cr4.LA57 ? "True " : "False", cr4.VMXE ? "True " : "False", cr4.SMXE ? "True " : "False", cr4.PCIDE ? "True " : "False",
cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False",
cr4._reserved0, cr4._reserved1, cr4._reserved2);
EHPrint("\e79FCF5CR8: TPL:%d\n", cr8.TPL);
EHPrint("\eFCFC02RFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x R3:%#x\n",
Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False",
Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False",
Frame->rflags.OF ? "True " : "False", Frame->rflags.IOPL ? "True " : "False", Frame->rflags.NT ? "True " : "False", Frame->rflags.RF ? "True " : "False",
Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False",
Frame->rflags.ID ? "True " : "False", Frame->rflags.always_one,
Frame->rflags._reserved0, Frame->rflags._reserved1, Frame->rflags._reserved2, Frame->rflags._reserved3);
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",
dr7.LocalDR0 ? "True " : "False", dr7.GlobalDR0 ? "True " : "False", dr7.LocalDR1 ? "True " : "False", dr7.GlobalDR1 ? "True " : "False",
dr7.LocalDR2 ? "True " : "False", dr7.GlobalDR2 ? "True " : "False", dr7.LocalDR3 ? "True " : "False", dr7.GlobalDR3 ? "True " : "False",
dr7.ConditionsDR0 ? "True " : "False", dr7.SizeDR0 ? "True " : "False", dr7.ConditionsDR1 ? "True " : "False", dr7.SizeDR1 ? "True " : "False",
dr7.ConditionsDR2 ? "True " : "False", dr7.SizeDR2 ? "True " : "False", dr7.ConditionsDR3 ? "True " : "False", dr7.SizeDR3 ? "True " : "False",
dr7.Reserved);
EHPrint("\e009FF0EFER: SCE:%s LME:%s LMA:%s NXE:%s\n SVME:%s LMSLE:%s FFXSR:%s TCE:%s\n R0:%#x R1:%#x R2:%#x\n",
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.Reserved0, efer.Reserved1, efer.Reserved2);
// restore debug registers
debug("Restoring debug registers...");
asm volatile("movq %0, %%dr0"
:
: "r"(dr0));
asm volatile("movq %0, %%dr1"
:
: "r"(dr1));
asm volatile("movq %0, %%dr2"
:
: "r"(dr2));
asm volatile("movq %0, %%dr3"
:
: "r"(dr3));
asm volatile("movq %0, %%dr6"
:
: "r"(dr6));
asm volatile("movq %0, %%dr7"
:
: "r"(dr7));
struct StackFrame
{
struct StackFrame *rbp;
uint64_t rip;
};
struct StackFrame *frames = (struct StackFrame *)Frame->rbp; // (struct StackFrame *)__builtin_frame_address(0);
debug("Stack tracing...");
EHPrint("\e7981FC\nStack Trace:\n");
if (!frames || !frames->rip || !frames->rbp)
{
EHPrint("\eFF0000\n< No stack trace available. >\n");
Display->SetBuffer(255);
while (1)
CPU::Stop();
}
else
{
frames = (struct StackFrame *)Frame->rbp;
if (Frame->rip >= 0xFFFFFFFF80000000 && Frame->rip <= (uint64_t)&_kernel_end)
debug("%p-%s <- Exception", (void *)Frame->rip, KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
else
debug("%p-OUTSIDE KERNEL <- Exception", (void *)Frame->rip);
for (uint64_t frame = 0; frame < 100; ++frame)
{
if (!frames->rip)
break;
if (frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uint64_t)&_kernel_end)
debug("%p-%s", (void *)frames->rip, KernelSymbolTable->GetSymbolFromAddress(frames->rip));
else
debug("%p-OUTSIDE KERNEL", (void *)frames->rip);
frames = frames->rbp;
}
}
if (!frames->rip || !frames->rbp)
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
EHPrint("\eAA25C%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
EHPrint("\e7981FC <- Exception");
EHPrint("\eFF0000\n< No stack trace available. >\n");
Display->SetBuffer(255);
while (1)
CPU::Stop();
}
else
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
if (Frame->rip >= 0xFFFFFFFF80000000 && Frame->rip <= (uint64_t)&_kernel_end)
EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
else
EHPrint("Outside Kernel");
EHPrint("\e7981FC <- Exception");
for (uint64_t frame = 0; frame < 20; ++frame)
{
if (!frames->rip)
break;
EHPrint("\n");
EHPrint("\e2565CC%p", (void *)frames->rip);
EHPrint("\e7925CC-");
if (frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uint64_t)&_kernel_end)
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress(frames->rip));
else
EHPrint("\eFF4CA9Outside Kernel");
frames = frames->rbp;
}
}
#elif defined(__i386__)
void *Frame = Data;
#elif defined(__aarch64__)
void *Frame = Data;
#endif
Display->SetBuffer(255);
while (1)
CPU::Stop();
}
}
#if defined(__amd64__)
// #define staticbuffer(name) char name[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
void DivideByZeroExceptionHandler(CPU::x64::TrapFrame *Frame)
{
fixme("Divide by zero exception");
}
void DebugExceptionHandler(CPU::x64::TrapFrame *Frame)
{
CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel triggered debug exception.");
}
void NonMaskableInterruptExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("NMI exception"); }
void BreakpointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Breakpoint exception"); }
void OverflowExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Overflow exception"); }
void BoundRangeExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Bound range exception"); }
void InvalidOpcodeExceptionHandler(CPU::x64::TrapFrame *Frame)
{
CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.");
}
void DeviceNotAvailableExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Device not available exception"); }
void DoubleFaultExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Double fault exception"); }
void CoprocessorSegmentOverrunExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
void InvalidTSSExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Invalid TSS exception"); }
void SegmentNotPresentExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Segment not present exception"); }
void StackFaultExceptionHandler(CPU::x64::TrapFrame *Frame)
{
// staticbuffer(descbuf);
// staticbuffer(desc_ext);
// staticbuffer(desc_table);
// staticbuffer(desc_idx);
// staticbuffer(desc_tmp);
// CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->error_code};
// switch (SelCode.Table)
// {
// case 0b00:
// memcpy(desc_tmp, "GDT", 3);
// break;
// case 0b01:
// memcpy(desc_tmp, "IDT", 3);
// break;
// case 0b10:
// memcpy(desc_tmp, "LDT", 3);
// break;
// case 0b11:
// memcpy(desc_tmp, "IDT", 3);
// break;
// default:
// memcpy(desc_tmp, "Unknown", 7);
// break;
// }
// debug("external:%d table:%d idx:%#x", SelCode.External, SelCode.Table, SelCode.Idx);
// sprintf_(descbuf, "Stack segment fault at address %#lx", Frame->rip);
// CrashHandler::EHPrint(descbuf);
// sprintf_(desc_ext, "External: %d", SelCode.External);
// CrashHandler::EHPrint(desc_ext);
// sprintf_(desc_table, "Table: %d (%s)", SelCode.Table, desc_tmp);
// CrashHandler::EHPrint(desc_table);
// sprintf_(desc_idx, "%s Index: %#x", desc_tmp, SelCode.Idx);
// CrashHandler::EHPrint(desc_idx);
// CrashHandler::EHPrint("\eDD2920System crashed!\n");
// CrashHandler::EHPrint("More info about the exception:\n");
}
void GeneralProtectionExceptionHandler(CPU::x64::TrapFrame *Frame)
{
// staticbuffer(descbuf);
// staticbuffer(desc_ext);
// staticbuffer(desc_table);
// staticbuffer(desc_idx);
// staticbuffer(desc_tmp);
// SelectorErrorCode SelCode = {.raw = ERROR_CODE};
// switch (SelCode.Table)
// {
// case CPU::x64::0b00:
// memcpy(desc_tmp, "GDT", 3);
// break;
// case CPU::x64::0b01:
// memcpy(desc_tmp, "IDT", 3);
// break;
// case CPU::x64::0b10:
// memcpy(desc_tmp, "LDT", 3);
// break;
// case CPU::x64::0b11:
// memcpy(desc_tmp, "IDT", 3);
// break;
// default:
// memcpy(desc_tmp, "Unknown", 7);
// break;
// }
// debug("external:%d table:%d idx:%#x", SelCode.External, SelCode.Table, SelCode.Idx);
// CurrentDisplay->SetPrintColor(0xDD2920);
// SET_PRINT_MID((char *)"System crashed!", FHeight(6));
// CurrentDisplay->ResetPrintColor();
// SET_PRINT_MID((char *)"More info about the exception:", FHeight(4));
// sprintf_(descbuf, "Kernel performed an illegal operation at address %#lx", RIP);
// SET_PRINT_MID((char *)descbuf, FHeight(5));
// sprintf_(desc_ext, "External: %d", SelCode.External);
// SET_PRINT_MID((char *)desc_ext, FHeight(3));
// sprintf_(desc_table, "Table: %d (%s)", SelCode.Table, desc_tmp);
// SET_PRINT_MID((char *)desc_table, FHeight(2));
// sprintf_(desc_idx, "%s Index: %#x", desc_tmp, SelCode.Idx);
// SET_PRINT_MID((char *)desc_idx, FHeight(1));
}
void PageFaultExceptionHandler(CPU::x64::TrapFrame *Frame)
{
// err("Kernel Exception");
// PageFaultErrorCode params = {.raw = (uint32_t)ERROR_CODE};
// // We can't use an allocator in exceptions (because that can cause another exception!) so, we'll just use a static buffer.
// staticbuffer(ret_err);
// staticbuffer(page_present);
// staticbuffer(page_write);
// staticbuffer(page_user);
// staticbuffer(page_reserved);
// staticbuffer(page_fetch);
// staticbuffer(page_protection);
// staticbuffer(page_shadow);
// staticbuffer(page_sgx);
// CurrentDisplay->SetPrintColor(0xDD2920);
// SET_PRINT_MID((char *)"System crashed!", FHeight(12));
// CurrentDisplay->ResetPrintColor();
// sprintf_(ret_err, "An exception occurred at %#lx by %#lx", cr2.PFLA, RIP);
// SET_PRINT_MID((char *)ret_err, FHeight(11));
// sprintf_(page_present, "Page: %s", params.P ? "Present" : "Not Present");
// SET_PRINT_MID((char *)page_present, FHeight(10));
// sprintf_(page_write, "Write Operation: %s", params.W ? "Read-Only" : "Read-Write");
// SET_PRINT_MID((char *)page_write, FHeight(9));
// sprintf_(page_user, "Processor Mode: %s", params.U ? "User-Mode" : "Kernel-Mode");
// SET_PRINT_MID((char *)page_user, FHeight(8));
// sprintf_(page_reserved, "CPU Reserved Bits: %s", params.R ? "Reserved" : "Unreserved");
// SET_PRINT_MID((char *)page_reserved, FHeight(7));
// sprintf_(page_fetch, "Caused By An Instruction Fetch: %s", params.I ? "Yes" : "No");
// SET_PRINT_MID((char *)page_fetch, FHeight(6));
// sprintf_(page_protection, "Caused By A Protection-Key Violation: %s", params.PK ? "Yes" : "No");
// SET_PRINT_MID((char *)page_protection, FHeight(5));
// sprintf_(page_shadow, "Caused By A Shadow Stack Access: %s", params.SS ? "Yes" : "No");
// SET_PRINT_MID((char *)page_shadow, FHeight(4));
// sprintf_(page_sgx, "Caused By An SGX Violation: %s", params.SGX ? "Yes" : "No");
// SET_PRINT_MID((char *)page_sgx, FHeight(3));
// if (ERROR_CODE & 0x00000008)
// {
// SET_PRINT_MID((char *)"One or more page directory entries contain reserved bits which are set to 1.", FHeight(2));
// }
// else
// {
// SET_PRINT_MID((char *)pagefault_message[ERROR_CODE & 0b111], FHeight(2));
// }
// err("\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", page_present, page_write, page_user, page_reserved, page_fetch, page_protection, page_shadow, page_sgx);
}
void x87FloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("x87 floating point exception"); }
void AlignmentCheckExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Alignment check exception"); }
void MachineCheckExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Machine check exception"); }
void SIMDFloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("SIMD floating point exception"); }
void VirtualizationExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Virtualization exception"); }
void SecurityExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Security exception"); }
void UnknownExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Unknown exception"); }
void UserModeExceptionHandler(CPU::x64::TrapFrame *Frame)
{
switch (Frame->int_num)
{
case CPU::x64::DivideByZero:
{
break;
}
case CPU::x64::Debug:
{
break;
}
case CPU::x64::NonMaskableInterrupt:
{
break;
}
case CPU::x64::Breakpoint:
{
break;
}
case CPU::x64::Overflow:
{
break;
}
case CPU::x64::BoundRange:
{
break;
}
case CPU::x64::InvalidOpcode:
{
break;
}
case CPU::x64::DeviceNotAvailable:
{
break;
}
case CPU::x64::DoubleFault:
{
break;
}
case CPU::x64::CoprocessorSegmentOverrun:
{
break;
}
case CPU::x64::InvalidTSS:
{
break;
}
case CPU::x64::SegmentNotPresent:
{
break;
}
case CPU::x64::StackSegmentFault:
{
break;
}
case CPU::x64::GeneralProtectionFault:
{
break;
}
case CPU::x64::PageFault:
{
break;
}
case CPU::x64::x87FloatingPoint:
{
break;
}
case CPU::x64::AlignmentCheck:
{
break;
}
case CPU::x64::MachineCheck:
{
break;
}
case CPU::x64::SIMDFloatingPoint:
{
break;
}
case CPU::x64::Virtualization:
{
break;
}
case CPU::x64::Security:
{
break;
}
default:
{
break;
}
}
}
#endif

View File

@ -13,13 +13,17 @@
#elif defined(__aarch64__)
#endif
#include "../crashhandler.hpp"
#include "../kernel.h"
extern "C" void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); }
namespace Interrupts
{
#if defined(__amd64__)
/* APIC::APIC */ void *apic = nullptr;
#elif defined(__i386__)
/* APIC::APIC */ void *apic = nullptr;
#elif defined(__aarch64__)
#endif
@ -38,14 +42,82 @@ namespace Interrupts
{
#if defined(__amd64__)
if (((ACPI::MADT *)PowerManager->GetMADT())->LAPICAddress != nullptr)
{
apic = new APIC::APIC;
((APIC::APIC *)apic)->RedirectIRQs(0);
}
else
{
error("LAPIC not found");
// PIC
// TODO: PIC
}
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
}
void InitializeTimer()
{
#if defined(__amd64__)
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
}
Vector<Handler *> RegisteredEvents;
extern "C" void MainInterruptHandler(void *Data)
{
#if defined(__amd64__)
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
if (RegisteredEvents[Frame->int_num])
RegisteredEvents[Frame->int_num]->OnInterruptReceived(Frame);
if (apic)
{
((APIC::APIC *)Interrupts::apic)->EOI();
return;
}
// TODO: PIC
#elif defined(__i386__)
void *Frame = Data;
#elif defined(__aarch64__)
void *Frame = Data;
#endif
while (1)
CPU::Stop();
}
Handler::Handler(int InterruptNumber)
{
debug("Handler::Handler(%d)", InterruptNumber);
this->InterruptNumber = InterruptNumber;
RegisteredEvents.push_back(this);
}
Handler::~Handler()
{
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
if (RegisteredEvents[i] == this)
{
debug("Handler::~Handler(%d)", InterruptNumber);
RegisteredEvents.remove(i);
return;
}
}
#if defined(__amd64__)
void Handler::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
{
warn("Unhandled interrupt received %#lx", Frame->int_num);
#elif defined(__i386__)
void Handler::OnInterruptReceived(void *Frame);
{
warn("Unhandled interrupt received");
#elif defined(__aarch64__)
void Handler::OnInterruptReceived(void *Frame);
{
warn("Unhandled interrupt received");
#endif
}
}

View File

@ -850,7 +850,7 @@ namespace PCI
{
DeviceConfig *NewDeviceConfig = (DeviceConfig *)((uint64_t)((ACPI::ACPI *)PowerManager->GetACPI())->MCFG + sizeof(ACPI::ACPI::MCFGHeader) + (sizeof(DeviceConfig) * t));
Memory::Virtual().Map((void *)NewDeviceConfig->BaseAddress, (void *)NewDeviceConfig->BaseAddress, Memory::PTFlag::RW);
trace("PCI Entry %d Address:%#llx BUS:%#llx-%#llx", t, NewDeviceConfig->BaseAddress,
trace("PCI Entry %d Address:%#lx BUS:%#lx-%#lx", t, NewDeviceConfig->BaseAddress,
NewDeviceConfig->StartBus, NewDeviceConfig->EndBus);
for (uint64_t Bus = NewDeviceConfig->StartBus; Bus < NewDeviceConfig->EndBus; Bus++)
EnumerateBus(NewDeviceConfig->BaseAddress, Bus);

View File

@ -1,5 +1,6 @@
#include <display.hpp>
#include <lock.hpp>
#include <uart.hpp>
#include <debug.h>
extern uint64_t _binary_Files_ter_powerline_v12n_psf_start;
@ -10,9 +11,11 @@ NEWLOCK(PrintLock);
namespace Video
{
char Display::Print(char Char, int Index)
char Display::Print(char Char, int Index, bool WriteToUART)
{
SMARTLOCK(PrintLock);
if (WriteToUART)
UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write((char)Char);
if (this->ColorIteration)
{

13
Core/crashhandler.hpp Normal file
View File

@ -0,0 +1,13 @@
#ifndef __FENNIX_KERNEL_CRASH_HANDELR_H__
#define __FENNIX_KERNEL_CRASH_HANDELR_H__
#include <types.h>
#include <cpu.hpp>
namespace CrashHandler
{
void EHPrint(const char *Format, ...);
void Handle(void *Data);
}
#endif // !__FENNIX_KERNEL_CRASH_HANDELR_H__

View File

@ -28,14 +28,14 @@ extern "C" int printf_(const char *format, ...);
extern "C" int vprintf_(const char *format, va_list arg);
#endif
EXTERNC void KPrint(const char *format, ...)
EXTERNC void KPrint(const char *Format, ...)
{
SMARTLOCK(KernelLock);
Time tm = ReadClock();
printf_("\eCCCCCC[\e00AEFF%02ld:%02ld:%02ld\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second);
va_list args;
va_start(args, format);
vprintf_(format, args);
va_start(args, Format);
vprintf_(Format, args);
va_end(args);
putchar('\n');
Display->SetBuffer(0);
@ -82,7 +82,11 @@ EXTERNC void Entry(BootInfo *Info)
Interrupts::Enable();
KPrint("Initializing SMP");
SMP::Initialize(PowerManager->GetMADT());
KPrint("Initializing timer");
Interrupts::InitializeTimer();
KPrint("\e058C19######## \eE85230END \e058C19########");
// CPU::Interrupts(CPU::Enable);
asmv("int $0x1");
while (1)
CPU::Halt();
}

View File

@ -1169,6 +1169,129 @@ namespace CPU
uint64_t raw;
} CR8;
typedef union EFER
{
struct
{
/** @brief Enable syscall & sysret instructions in 64-bit mode. */
uint64_t SCE : 1;
/** @brief Reserved */
uint64_t Reserved0 : 7;
/** @brief Enable long mode. */
uint64_t LME : 1;
/** @brief Reserved */
uint64_t Reserved1 : 1;
/** @brief Indicates long. */
uint64_t LMA : 1;
/** @brief Enable No-Execute Bit */
uint64_t NXE : 1;
/** @brief Enable Secure Virtual Machine */
uint64_t SVME : 1;
/** @brief Enable Long Mode Segment Limit */
uint64_t LMSLE : 1;
/** @brief Enable Fast FXSAVE/FXRSTOR */
uint64_t FFXSR : 1;
/** @brief Enable Translation Cache Extension */
uint64_t TCE : 1;
/** @brief Reserved */
uint64_t Reserved2 : 32;
};
uint64_t raw;
} __attribute__((packed)) EFER;
// ! TODO: UNTESTED!
typedef union DR7
{
struct
{
/** @brief Local DR0 Breakpoint (0) */
uint64_t LocalDR0 : 1;
/** @brief Global DR0 Breakpoint (1) */
uint64_t GlobalDR0 : 1;
/** @brief Local DR1 Breakpoint (2) */
uint64_t LocalDR1 : 1;
/** @brief Global DR1 Breakpoint (3) */
uint64_t GlobalDR1 : 1;
/** @brief Local DR2 Breakpoint (4) */
uint64_t LocalDR2 : 1;
/** @brief Global DR2 Breakpoint (5) */
uint64_t GlobalDR2 : 1;
/** @brief Local DR3 Breakpoint (6) */
uint64_t LocalDR3 : 1;
/** @brief Global DR3 Breakpoint (7) */
uint64_t GlobalDR3 : 1;
/** @brief Reserved [7 - (16-17)] */
uint64_t Reserved : 9;
/** @brief Conditions for DR0 (16-17) */
uint64_t ConditionsDR0 : 1;
/** @brief Size of DR0 Breakpoint (18-19) */
uint64_t SizeDR0 : 1;
/** @brief Conditions for DR1 (20-21) */
uint64_t ConditionsDR1 : 1;
/** @brief Size of DR1 Breakpoint (22-23) */
uint64_t SizeDR1 : 1;
/** @brief Conditions for DR2 (24-25) */
uint64_t ConditionsDR2 : 1;
/** @brief Size of DR2 Breakpoint (26-27) */
uint64_t SizeDR2 : 1;
/** @brief Conditions for DR3 (28-29) */
uint64_t ConditionsDR3 : 1;
/** @brief Size of DR3 Breakpoint (30-31) */
uint64_t SizeDR3 : 1;
};
uint64_t raw;
} DR7;
typedef union PageFaultErrorCode
{
struct
{
/** @brief When set, the page fault was caused by a page-protection violation. When not set, it was caused by a non-present page. */
uint64_t P : 1;
/** @brief When set, the page fault was caused by a write access. When not set, it was caused by a read access. */
uint64_t W : 1;
/** @brief When set, the page fault was caused while CPL = 3. This does not necessarily mean that the page fault was a privilege violation. */
uint64_t U : 1;
/** @brief When set, one or more page directory entries contain reserved bits which are set to 1. This only applies when the PSE or PAE flags in CR4 are set to 1. */
uint64_t R : 1;
/** @brief When set, the page fault was caused by an instruction fetch. This only applies when the No-Execute bit is supported and enabled. */
uint64_t I : 1;
/** @brief When set, the page fault was caused by a protection-key violation. The PKRU register (for user-mode accesses) or PKRS MSR (for supervisor-mode accesses) specifies the protection key rights. */
uint64_t PK : 1;
/** @brief When set, the page fault was caused by a shadow stack access. */
uint64_t SS : 1;
/** @brief Reserved */
uint64_t _reserved0 : 8;
/** @brief When set, the fault was due to an SGX violation. The fault is unrelated to ordinary paging. */
uint64_t SGX : 1;
/** @brief Reserved */
uint64_t _reserved1 : 16;
};
uint64_t raw;
} PageFaultErrorCode;
// ! TODO: UNTESTED!
typedef union SelectorErrorCode
{
struct
{
/** @brief When set, the exception originated externally to the processor. */
uint64_t External : 1;
/** @brief IDT/GDT/LDT Table
* @details 0b00 - The Selector Index references a descriptor in the GDT.
* @details 0b01 - The Selector Index references a descriptor in the IDT.
* @details 0b10 - The Selector Index references a descriptor in the LDT.
* @details 0b11 - The Selector Index references a descriptor in the IDT.
*/
uint64_t Table : 2;
/** @brief The index in the GDT, IDT or LDT. */
uint64_t Idx : 13;
/** @brief Reserved */
uint64_t Reserved : 16;
};
uint64_t raw;
} SelectorErrorCode;
static inline void lgdt(void *gdt)
{
#if defined(__amd64__)

View File

@ -5,6 +5,7 @@
#include <boot/binfo.h>
#include <memory.hpp>
#include <debug.h>
#include <cstring>
namespace Video
@ -82,6 +83,7 @@ namespace Video
uint64_t Size;
uint32_t Color;
uint32_t CursorX, CursorY;
long Checksum;
};
class Display
@ -89,7 +91,7 @@ namespace Video
private:
BootInfo::FramebufferInfo framebuffer;
Font *CurrentFont;
ScreenBuffer *Buffers[16];
ScreenBuffer *Buffers[256];
bool ColorIteration = false;
int ColorPickerIteration = 0;
@ -98,17 +100,30 @@ namespace Video
void SetCurrentFont(Font *Font) { CurrentFont = Font; }
void CreateBuffer(uint32_t Width, uint32_t Height, int Index)
{
if (Width == 0 && Height == 0)
{
Width = this->framebuffer.Width;
Height = this->framebuffer.Height;
debug("No width and height specified, using %ldx%ld", Width, Height);
}
uint64_t Size = this->framebuffer.Pitch * Height;
ScreenBuffer *buffer = new ScreenBuffer;
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
buffer->Width = Width;
buffer->Height = Height;
buffer->Size = Size;
buffer->Color = 0x000000;
buffer->CursorX = 0;
buffer->CursorY = 0;
this->Buffers[Index] = buffer;
memset(buffer->Buffer, 0, Size);
if (this->Buffers[Index]->Checksum != 0xDEAD5C9EE7)
{
ScreenBuffer *buffer = new ScreenBuffer;
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
buffer->Width = Width;
buffer->Height = Height;
buffer->Size = Size;
buffer->Color = 0xFFFFFF;
buffer->CursorX = 0;
buffer->CursorY = 0;
this->Buffers[Index] = buffer;
memset(this->Buffers[Index]->Buffer, 0, Size);
this->Buffers[Index]->Checksum = 0xDEAD5C9EE7;
}
else
warn("Buffer %d already exists, skipping creation", Index);
}
void SetBuffer(int Index) { memcpy(this->framebuffer.BaseAddress, this->Buffers[Index]->Buffer, this->Buffers[Index]->Size); }
void ClearBuffer(int Index) { memset(this->Buffers[Index]->Buffer, 0, this->Buffers[Index]->Size); }
@ -117,6 +132,7 @@ namespace Video
if (this->Buffers[Index] == nullptr)
return;
KernelAllocator.FreePages(this->Buffers[Index]->Buffer, TO_PAGES(this->Buffers[Index]->Size));
this->Buffers[Index]->Checksum = 0; // Making sure that the buffer is not used anymore
delete this->Buffers[Index];
}
@ -156,7 +172,7 @@ namespace Video
}
}
char Print(char Char, int Index);
char Print(char Char, int Index, bool WriteToUART = false);
Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont = true);
~Display();
};

View File

@ -2,12 +2,41 @@
#define __FENNIX_KERNEL_INTERRUPTS_H__
#include <types.h>
#include <cpu.hpp>
namespace Interrupts
{
#if defined(__amd64__)
extern void *apic;
#elif defined(__i386__)
extern void *apic;
#elif defined(__aarch64__)
#endif
void Initialize(int Core);
void Enable();
void InitializeTimer();
class Handler
{
private:
int InterruptNumber;
protected:
void SetInterruptNumber(int InterruptNumber) { this->InterruptNumber = InterruptNumber; }
int GetInterruptNumber() { return InterruptNumber; }
Handler(int InterruptNumber);
~Handler();
public:
#if defined(__amd64__)
virtual void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
#elif defined(__i386__)
virtual void OnInterruptReceived(void *Frame);
#elif defined(__aarch64__)
virtual void OnInterruptReceived(void *Frame);
#endif
};
}
#endif // !__FENNIX_KERNEL_INTERRUPTS_H__