mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
implemented interrupts handler & stub crash screen
This commit is contained in:
parent
04757bd11c
commit
b8c5c15a47
@ -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");
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
15
Core/CPU.cpp
15
Core/CPU.cpp
@ -224,12 +224,14 @@ 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)
|
||||
@ -251,14 +253,19 @@ namespace CPU
|
||||
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)
|
||||
{
|
||||
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
650
Core/CrashHandler.cpp
Normal 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
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
13
Core/crashhandler.hpp
Normal 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__
|
10
Kernel.cpp
10
Kernel.cpp
@ -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();
|
||||
}
|
||||
|
123
include/cpu.hpp
123
include/cpu.hpp
@ -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__)
|
||||
|
@ -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;
|
||||
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 = 0x000000;
|
||||
buffer->Color = 0xFFFFFF;
|
||||
buffer->CursorX = 0;
|
||||
buffer->CursorY = 0;
|
||||
this->Buffers[Index] = buffer;
|
||||
memset(buffer->Buffer, 0, Size);
|
||||
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();
|
||||
};
|
||||
|
@ -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__
|
||||
|
Loading…
x
Reference in New Issue
Block a user