mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-03 11:29:21 +00:00
Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more
This commit is contained in:
@ -25,30 +25,30 @@ static const char *PagefaultDescriptions[8] = {
|
||||
"User process tried to write to a non-present page entry\n",
|
||||
"User process tried to write a page and caused a protection fault\n"};
|
||||
|
||||
__no_stack_protector void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
fixme("Divide by zero exception\n");
|
||||
}
|
||||
__no_stack_protector void DebugExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void DebugExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
||||
CrashHandler::EHPrint("Kernel triggered debug exception.\n");
|
||||
}
|
||||
__no_stack_protector void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
|
||||
__no_stack_protector void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
|
||||
__no_stack_protector void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
|
||||
__no_stack_protector void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
|
||||
__no_stack_protector void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
|
||||
SafeFunction void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
|
||||
SafeFunction void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
|
||||
SafeFunction void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
|
||||
SafeFunction void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
||||
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n");
|
||||
}
|
||||
__no_stack_protector void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
|
||||
__no_stack_protector void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
|
||||
__no_stack_protector void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
|
||||
__no_stack_protector void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
|
||||
__no_stack_protector void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
|
||||
__no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
|
||||
SafeFunction void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
|
||||
SafeFunction void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
|
||||
SafeFunction void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
|
||||
SafeFunction void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
|
||||
SafeFunction void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode};
|
||||
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
||||
@ -64,7 +64,7 @@ __no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx);
|
||||
CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode);
|
||||
}
|
||||
__no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
// staticbuffer(descbuf);
|
||||
// staticbuffer(desc_ext);
|
||||
@ -97,7 +97,7 @@ __no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Fra
|
||||
CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
|
||||
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx);
|
||||
}
|
||||
__no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
|
||||
CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF");
|
||||
@ -120,10 +120,10 @@ __no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||
else
|
||||
CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
|
||||
}
|
||||
__no_stack_protector void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
|
||||
__no_stack_protector void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
|
||||
__no_stack_protector void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
|
||||
__no_stack_protector void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
|
||||
__no_stack_protector void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
|
||||
__no_stack_protector void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
|
||||
__no_stack_protector void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }
|
||||
SafeFunction void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
|
||||
SafeFunction void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
|
||||
SafeFunction void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
|
||||
SafeFunction void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
|
||||
SafeFunction void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
|
||||
SafeFunction void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
|
||||
SafeFunction void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }
|
||||
|
@ -22,15 +22,16 @@ NewLock(UserInputLock);
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
void *EHIntFrames[INT_FRAMES_MAX];
|
||||
static bool ExceptionOccurred = false;
|
||||
int SBIdx = 255;
|
||||
__no_stack_protector void printfWrapper(char c, void *unused)
|
||||
SafeFunction void printfWrapper(char c, void *unused)
|
||||
{
|
||||
Display->Print(c, SBIdx, true);
|
||||
UNUSED(unused);
|
||||
}
|
||||
|
||||
__no_stack_protector void EHPrint(const char *Format, ...)
|
||||
SafeFunction void EHPrint(const char *Format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, Format);
|
||||
@ -38,7 +39,7 @@ namespace CrashHandler
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
__no_stack_protector char *trimwhitespace(char *str)
|
||||
SafeFunction char *TrimWhiteSpace(char *str)
|
||||
{
|
||||
char *end;
|
||||
while (*str == ' ')
|
||||
@ -54,7 +55,7 @@ namespace CrashHandler
|
||||
|
||||
CRData crashdata = {};
|
||||
|
||||
__no_stack_protector void DisplayTopOverlay()
|
||||
SafeFunction void DisplayTopOverlay()
|
||||
{
|
||||
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
||||
Video::Font *f = Display->GetCurrentFont();
|
||||
@ -108,7 +109,7 @@ namespace CrashHandler
|
||||
Display->SetBufferCursor(SBIdx, 0, fi.Height + 10);
|
||||
}
|
||||
|
||||
__no_stack_protector void DisplayBottomOverlay()
|
||||
SafeFunction void DisplayBottomOverlay()
|
||||
{
|
||||
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
||||
Video::Font *f = Display->GetCurrentFont();
|
||||
@ -122,7 +123,7 @@ namespace CrashHandler
|
||||
EHPrint("\eAAAAAA> \eFAFAFA");
|
||||
}
|
||||
|
||||
__no_stack_protector void ArrowInput(uint8_t key)
|
||||
SafeFunction void ArrowInput(uint8_t key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
@ -193,7 +194,7 @@ namespace CrashHandler
|
||||
Display->SetBuffer(SBIdx);
|
||||
}
|
||||
|
||||
__no_stack_protector void UserInput(char *Input)
|
||||
SafeFunction void UserInput(char *Input)
|
||||
{
|
||||
SmartCriticalSection(UserInputLock);
|
||||
Display->ClearBuffer(SBIdx);
|
||||
@ -209,6 +210,7 @@ namespace CrashHandler
|
||||
EHPrint("showbuf <INDEX> - Display the contents of a screen buffer.\n");
|
||||
EHPrint(" - A sleep timer will be enabled. This will cause the OS to sleep for an unknown amount of time.\n");
|
||||
EHPrint(" - \eFF4400WARNING: This can crash the system if a wrong buffer is selected.\eFAFAFA\n");
|
||||
EHPrint("ifr <COUNT> - Show interrupt frames.\n");
|
||||
EHPrint("main - Show the main screen.\n");
|
||||
EHPrint("details - Show the details screen.\n");
|
||||
EHPrint("frames - Show the stack frame screen.\n");
|
||||
@ -223,25 +225,66 @@ namespace CrashHandler
|
||||
{
|
||||
PowerManager->Shutdown();
|
||||
EHPrint("\eFFFFFFNow it's safe to turn off your computer.");
|
||||
Display->SetBuffer(SBIdx);
|
||||
CPU::Stop();
|
||||
}
|
||||
else if (strcmp(Input, "reboot") == 0)
|
||||
{
|
||||
PowerManager->Reboot();
|
||||
EHPrint("\eFFFFFFNow it's safe to reboot your computer.");
|
||||
Display->SetBuffer(SBIdx);
|
||||
CPU::Stop();
|
||||
}
|
||||
else if (strncmp(Input, "showbuf", 7) == 0)
|
||||
{
|
||||
char *arg = trimwhitespace(Input + 7);
|
||||
char *arg = TrimWhiteSpace(Input + 7);
|
||||
int tmpidx = SBIdx;
|
||||
SBIdx = atoi(arg);
|
||||
Display->SetBuffer(SBIdx);
|
||||
for (int i = 0; i < 1000000; i++)
|
||||
for (int i = 0; i < 5000000; i++)
|
||||
inb(0x80);
|
||||
SBIdx = tmpidx;
|
||||
Display->SetBuffer(SBIdx);
|
||||
}
|
||||
else if (strncmp(Input, "ifr", 3) == 0)
|
||||
{
|
||||
char *arg = TrimWhiteSpace(Input + 3);
|
||||
uint64_t CountI = atoi(arg);
|
||||
uint64_t TotalCount = sizeof(EHIntFrames) / sizeof(EHIntFrames[0]);
|
||||
|
||||
debug("Printing %ld interrupt frames.", CountI);
|
||||
|
||||
if (CountI > TotalCount)
|
||||
{
|
||||
EHPrint("eFF4400Count too big! Maximum allowed is %ld\eFAFAFA\n", TotalCount);
|
||||
Display->SetBuffer(SBIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint64_t i = 0; i < CountI; i++)
|
||||
{
|
||||
if (EHIntFrames[i])
|
||||
{
|
||||
if (!Memory::Virtual().Check(EHIntFrames[i]))
|
||||
continue;
|
||||
EHPrint("\n\e2565CC%p", EHIntFrames[i]);
|
||||
EHPrint("\e7925CC-");
|
||||
#if defined(__amd64__)
|
||||
if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
|
||||
#elif defined(__i386__)
|
||||
if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i]));
|
||||
else
|
||||
EHPrint("\eFF4CA9Outside Kernel");
|
||||
for (int i = 0; i < 20000; i++)
|
||||
inb(0x80);
|
||||
Display->SetBuffer(SBIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(Input, "main") == 0)
|
||||
{
|
||||
SBIdx = 255;
|
||||
@ -286,11 +329,14 @@ namespace CrashHandler
|
||||
Display->SetBuffer(SBIdx);
|
||||
}
|
||||
|
||||
__no_stack_protector void Handle(void *Data)
|
||||
SafeFunction void Handle(void *Data)
|
||||
{
|
||||
// TODO: SUPPORT SMP
|
||||
CPU::Interrupts(CPU::Disable);
|
||||
error("An exception occurred!");
|
||||
for (size_t i = 0; i < INT_FRAMES_MAX; i++)
|
||||
EHIntFrames[i] = Interrupts::InterruptFrames[i];
|
||||
|
||||
SBIdx = 255;
|
||||
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
|
||||
#if defined(__amd64__)
|
||||
@ -299,27 +345,11 @@ namespace CrashHandler
|
||||
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
|
||||
{
|
||||
debug("Exception in kernel mode");
|
||||
if (Frame->InterruptNumber == CPU::x64::PageFault)
|
||||
{
|
||||
CPUData *data = GetCurrentCPU();
|
||||
if (data)
|
||||
{
|
||||
if (data->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
|
||||
{
|
||||
debug("Stack expanded");
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Stack expansion failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TaskManager)
|
||||
TaskManager->Panic();
|
||||
debug("ePanicSchedStop");
|
||||
Display->CreateBuffer(0, 0, SBIdx);
|
||||
debug("e0");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -348,7 +378,9 @@ namespace CrashHandler
|
||||
{
|
||||
SBIdx = 255;
|
||||
Display->ClearBuffer(SBIdx);
|
||||
debug("e0-1");
|
||||
Display->SetBufferCursor(SBIdx, 0, 0);
|
||||
debug("e0-2");
|
||||
|
||||
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
|
||||
CPU::x64::CR2 cr2 = CPU::x64::readcr2();
|
||||
@ -405,6 +437,7 @@ namespace CrashHandler
|
||||
}
|
||||
|
||||
ExceptionOccurred = true;
|
||||
Interrupts::RemoveAll();
|
||||
|
||||
debug("Reading control registers...");
|
||||
crashdata.Frame = Frame;
|
||||
|
@ -103,11 +103,11 @@ namespace CrashHandler
|
||||
static char UserInputBuffer[1024];
|
||||
|
||||
#if defined(__amd64__)
|
||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
||||
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
||||
#elif defined(__i386__)
|
||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||
#elif defined(__aarch64__)
|
||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||
#endif
|
||||
{
|
||||
uint8_t scanCode = inb(0x60);
|
||||
@ -155,10 +155,10 @@ namespace CrashHandler
|
||||
}
|
||||
}
|
||||
|
||||
__no_stack_protector void HookKeyboard()
|
||||
SafeFunction void HookKeyboard()
|
||||
{
|
||||
CrashKeyboardDriver kbd; // We don't want to allocate memory.
|
||||
asmv("Loop: nop; jmp Loop;");
|
||||
asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;");
|
||||
// CPU::Halt(true); // This is an infinite loop.
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace CrashHandler
|
||||
uint64_t rip;
|
||||
};
|
||||
|
||||
__no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count)
|
||||
SafeFunction void TraceFrames(CHArchTrapFrame *Frame, int Count)
|
||||
{
|
||||
|
||||
#if defined(__amd64__)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayConsoleScreen(CRData data)
|
||||
SafeFunction void DisplayConsoleScreen(CRData data)
|
||||
{
|
||||
EHPrint("TODO");
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayDetailsScreen(CRData data)
|
||||
SafeFunction void DisplayDetailsScreen(CRData data)
|
||||
{
|
||||
if (data.Process)
|
||||
EHPrint("\e7981FCCurrent Process: %s(%ld)\n",
|
||||
|
@ -27,7 +27,7 @@ static const char *PagefaultDescriptions[8] = {
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayMainScreen(CRData data)
|
||||
SafeFunction void DisplayMainScreen(CRData data)
|
||||
{
|
||||
CHArchTrapFrame *Frame = data.Frame;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "../../crashhandler.hpp"
|
||||
#include "../chfcts.hpp"
|
||||
|
||||
#include <interrupts.hpp>
|
||||
#include <display.hpp>
|
||||
#include <printf.h>
|
||||
#include <debug.h>
|
||||
@ -17,9 +18,29 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayStackFrameScreen(CRData data)
|
||||
SafeFunction void DisplayStackFrameScreen(CRData data)
|
||||
{
|
||||
EHPrint("\eFAFAFATracing 40 frames...\n");
|
||||
TraceFrames(data.Frame, 40);
|
||||
EHPrint("\n\n\eFAFAFATracing interrupt frames...\n");
|
||||
for (uint64_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (EHIntFrames[i])
|
||||
{
|
||||
if (!Memory::Virtual().Check(EHIntFrames[i]))
|
||||
continue;
|
||||
EHPrint("\n\e2565CC%p", EHIntFrames[i]);
|
||||
EHPrint("\e7925CC-");
|
||||
#if defined(__amd64__)
|
||||
if ((uint64_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
|
||||
#elif defined(__i386__)
|
||||
if ((uint64_t)EHIntFrames[i] >= 0xC0000000 && (uint64_t)EHIntFrames[i] <= (uint64_t)&_kernel_end)
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uint64_t)EHIntFrames[i]));
|
||||
else
|
||||
EHPrint("\eFF4CA9Outside Kernel");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
__no_stack_protector void DisplayTasksScreen(CRData data)
|
||||
SafeFunction void DisplayTasksScreen(CRData data)
|
||||
{
|
||||
const char *StatusColor[7] = {
|
||||
"FF0000", // Unknown
|
||||
|
@ -25,7 +25,7 @@ static const char *PagefaultDescriptions[8] = {
|
||||
"User process tried to write to a non-present page entry\n",
|
||||
"User process tried to write a page and caused a protection fault\n"};
|
||||
|
||||
__no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
{
|
||||
CriticalSection cs;
|
||||
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");
|
||||
|
@ -8,13 +8,13 @@ NewLock(DebuggerLock);
|
||||
|
||||
using namespace UniversalAsynchronousReceiverTransmitter;
|
||||
|
||||
static inline void uart_wrapper(char c, void *unused)
|
||||
static inline __no_instrument_function void uart_wrapper(char c, void *unused)
|
||||
{
|
||||
UART(COM1).Write(c);
|
||||
(void)unused;
|
||||
}
|
||||
|
||||
static inline void WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function)
|
||||
static inline __no_instrument_function void WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function)
|
||||
{
|
||||
const char *DbgLvlString;
|
||||
switch (Level)
|
||||
@ -52,7 +52,7 @@ static inline void WritePrefix(DebugLevel Level, const char *File, int Line, con
|
||||
|
||||
namespace SysDbg
|
||||
{
|
||||
void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
__no_instrument_function void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
{
|
||||
WritePrefix(Level, File, Line, Function);
|
||||
va_list args;
|
||||
@ -61,7 +61,7 @@ namespace SysDbg
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
__no_instrument_function void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
{
|
||||
// SmartLock(DebuggerLock);
|
||||
WritePrefix(Level, File, Line, Function);
|
||||
@ -74,7 +74,7 @@ namespace SysDbg
|
||||
}
|
||||
|
||||
// C compatibility
|
||||
extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
extern "C" __no_instrument_function void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
{
|
||||
WritePrefix(Level, File, Line, Function);
|
||||
va_list args;
|
||||
@ -84,7 +84,7 @@ extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, c
|
||||
}
|
||||
|
||||
// C compatibility
|
||||
extern "C" void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
extern "C" __no_instrument_function void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...)
|
||||
{
|
||||
WritePrefix(Level, File, Line, Function);
|
||||
va_list args;
|
||||
|
@ -2,19 +2,19 @@
|
||||
|
||||
#include <interrupts.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <dumper.hpp>
|
||||
#include <task.hpp>
|
||||
#include <lock.hpp>
|
||||
#include <printf.h>
|
||||
#include <cwalk.h>
|
||||
#include <md5.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
#include "../DAPI.hpp"
|
||||
#include "../Fex.hpp"
|
||||
#include "../../kernel.h"
|
||||
#include "../../DAPI.hpp"
|
||||
#include "../../Fex.hpp"
|
||||
#include "api.hpp"
|
||||
|
||||
NewLock(DriverInitLock);
|
||||
NewLock(DriverDisplayPrintLock);
|
||||
NewLock(DriverInterruptLock);
|
||||
|
||||
namespace Driver
|
||||
{
|
||||
@ -28,127 +28,6 @@ namespace Driver
|
||||
"Input",
|
||||
"Audio"};
|
||||
|
||||
void DriverDebugPrint(char *String, unsigned long DriverUID)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
trace("[%ld] %s", DriverUID, String);
|
||||
}
|
||||
|
||||
void DriverDisplayPrint(char *String)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
for (unsigned long i = 0; i < strlen(String); i++)
|
||||
Display->Print(String[i], 0, true);
|
||||
}
|
||||
|
||||
void *RequestPage(unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Requesting %ld pages from the kernel...", Size);
|
||||
void *ret = KernelAllocator.RequestPages(Size);
|
||||
debug("Got %#lx", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreePage(void *Page, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Freeing %ld pages from the address %#lx...", Size, (unsigned long)Page);
|
||||
KernelAllocator.FreePages(Page, Size);
|
||||
}
|
||||
|
||||
void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags);
|
||||
Memory::Virtual().Map(VirtualAddress, PhysicalAddress, Flags);
|
||||
}
|
||||
|
||||
void UnmapMemory(void *VirtualAddress)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Unmapping %#lx...", (unsigned long)VirtualAddress);
|
||||
Memory::Virtual().Unmap(VirtualAddress);
|
||||
}
|
||||
|
||||
void *Drivermemcpy(void *Destination, void *Source, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Copying %ld bytes from %#lx to %#lx...", Size, (unsigned long)Source, (unsigned long)Destination);
|
||||
return memcpy(Destination, Source, Size);
|
||||
}
|
||||
|
||||
void *Drivermemset(void *Destination, int Value, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Setting %ld bytes from %#lx to %#x...", Size, (unsigned long)Destination, Value);
|
||||
return memset(Destination, Value, Size);
|
||||
}
|
||||
|
||||
void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
DumpData("DriverNetSend", Data, Size);
|
||||
}
|
||||
|
||||
void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
DumpData("DriverNetReceive", Data, Size);
|
||||
}
|
||||
|
||||
void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
|
||||
{
|
||||
DumpData("DriverDiskRead", Data, SectorCount * 512);
|
||||
}
|
||||
|
||||
void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
|
||||
{
|
||||
DumpData("DriverDiskWrite", Data, SectorCount * 512);
|
||||
}
|
||||
|
||||
char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID)
|
||||
{
|
||||
return (char *)"Unknown";
|
||||
}
|
||||
|
||||
KernelAPI KAPI = {
|
||||
.Version = {
|
||||
.Major = 0,
|
||||
.Minor = 0,
|
||||
.Patch = 1},
|
||||
.Info = {
|
||||
.Offset = 0,
|
||||
.DriverUID = 0,
|
||||
},
|
||||
.Memory = {
|
||||
.PageSize = PAGE_SIZE,
|
||||
.RequestPage = RequestPage,
|
||||
.FreePage = FreePage,
|
||||
.Map = MapMemory,
|
||||
.Unmap = UnmapMemory,
|
||||
},
|
||||
.PCI = {
|
||||
.GetDeviceName = DriverPCIGetDeviceName,
|
||||
},
|
||||
.Util = {
|
||||
.DebugPrint = DriverDebugPrint,
|
||||
.DisplayPrint = DriverDisplayPrint,
|
||||
.memcpy = Drivermemcpy,
|
||||
.memset = Drivermemset,
|
||||
},
|
||||
.Commmand = {
|
||||
.Network = {
|
||||
.SendPacket = DriverNetSend,
|
||||
.ReceivePacket = DriverNetReceive,
|
||||
},
|
||||
.Disk = {
|
||||
.AHCI = {
|
||||
.ReadSector = DriverAHCIDiskRead,
|
||||
.WriteSector = DriverAHCIDiskWrite,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int Driver::IOCB(unsigned long DUID, void *KCB)
|
||||
{
|
||||
foreach (auto var in Drivers)
|
||||
@ -411,7 +290,48 @@ namespace Driver
|
||||
}
|
||||
case FexDriverType::FexDriverType_Input:
|
||||
{
|
||||
fixme("Input driver: %s", fexExtended->Driver.Name);
|
||||
DriverInterruptHook *InterruptHook = nullptr;
|
||||
if (DrvExtHdr->Driver.Bind.Interrupt.Vector[0] != 0)
|
||||
InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[0] + 32, // x86
|
||||
(void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex),
|
||||
KCallback);
|
||||
|
||||
for (unsigned long i = 0; i < sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector) / sizeof(DrvExtHdr->Driver.Bind.Interrupt.Vector[0]); i++)
|
||||
{
|
||||
if (DrvExtHdr->Driver.Bind.Interrupt.Vector[i] == 0)
|
||||
break;
|
||||
// InterruptHook = new DriverInterruptHook(DrvExtHdr->Driver.Bind.Interrupt.Vector[i] + 32, // x86
|
||||
// (void *)((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex),
|
||||
// KCallback);
|
||||
fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", DrvExtHdr->Driver.Bind.Interrupt.Vector[i]);
|
||||
}
|
||||
|
||||
KCallback->RawPtr = nullptr;
|
||||
KCallback->Reason = CallbackReason::ConfigurationReason;
|
||||
int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback);
|
||||
if (callbackret == DriverReturnCode::NOT_IMPLEMENTED)
|
||||
{
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
|
||||
error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name);
|
||||
break;
|
||||
}
|
||||
else if (callbackret != DriverReturnCode::OK)
|
||||
{
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
|
||||
error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(KCallback, 0, sizeof(KernelCallback));
|
||||
KCallback->Reason = CallbackReason::InterruptReason;
|
||||
|
||||
DriverFile *drvfile = new DriverFile;
|
||||
drvfile->DriverUID = KAPI.Info.DriverUID;
|
||||
drvfile->Address = (void *)fex;
|
||||
drvfile->InterruptHook[0] = InterruptHook;
|
||||
Drivers.push_back(drvfile);
|
||||
break;
|
||||
}
|
||||
case FexDriverType::FexDriverType_Audio:
|
||||
@ -430,6 +350,68 @@ namespace Driver
|
||||
{
|
||||
fixme("Process driver: %s", DrvExtHdr->Driver.Name);
|
||||
}
|
||||
else if (DrvExtHdr->Driver.Bind.Type == DriverBindType::BIND_INPUT)
|
||||
{
|
||||
Fex *fex = (Fex *)KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||
memcpy(fex, (void *)DriverAddress, Size);
|
||||
FexExtended *fexExtended = (FexExtended *)((uint64_t)fex + EXTENDED_SECTION_ADDRESS);
|
||||
#ifdef DEBUG
|
||||
uint8_t *result = md5File((uint8_t *)fex, Size);
|
||||
debug("MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
|
||||
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]);
|
||||
kfree(result);
|
||||
#endif
|
||||
if (CallDriverEntryPoint(fex) != DriverCode::OK)
|
||||
{
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
return DriverCode::DRIVER_RETURNED_ERROR;
|
||||
}
|
||||
debug("Starting driver %s (offset: %#lx)", fexExtended->Driver.Name, fex);
|
||||
|
||||
KernelCallback *KCallback = (KernelCallback *)KernelAllocator.RequestPages(TO_PAGES(sizeof(KernelCallback)));
|
||||
|
||||
switch (fexExtended->Driver.Type)
|
||||
{
|
||||
case FexDriverType::FexDriverType_Input:
|
||||
{
|
||||
fixme("Input driver: %s", fexExtended->Driver.Name);
|
||||
KCallback->RawPtr = nullptr;
|
||||
break;
|
||||
KCallback->Reason = CallbackReason::ConfigurationReason;
|
||||
int callbackret = ((int (*)(KernelCallback *))((uint64_t)fexExtended->Driver.Callback + (uint64_t)fex))(KCallback);
|
||||
if (callbackret == DriverReturnCode::NOT_IMPLEMENTED)
|
||||
{
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
|
||||
error("Driver %s does not implement the configuration callback", fexExtended->Driver.Name);
|
||||
break;
|
||||
}
|
||||
else if (callbackret != DriverReturnCode::OK)
|
||||
{
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
|
||||
error("Driver %s returned error %d", fexExtended->Driver.Name, callbackret);
|
||||
break;
|
||||
}
|
||||
|
||||
KernelAllocator.FreePages(fex, TO_PAGES(Size));
|
||||
KernelAllocator.FreePages(KCallback, TO_PAGES(sizeof(KernelCallback)));
|
||||
|
||||
DriverFile *drvfile = new DriverFile;
|
||||
drvfile->DriverUID = KAPI.Info.DriverUID;
|
||||
drvfile->Address = (void *)fex;
|
||||
drvfile->InterruptHook[0] = nullptr;
|
||||
Drivers.push_back(drvfile);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
warn("Unknown driver type: %d", fexExtended->Driver.Type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type);
|
||||
@ -454,9 +436,9 @@ namespace Driver
|
||||
if (!strcmp(extension, ".fex"))
|
||||
{
|
||||
uint64_t ret = this->LoadDriver(driver->Address, driver->Length);
|
||||
char retstring[64];
|
||||
char retstring[128];
|
||||
if (ret == DriverCode::OK)
|
||||
strcpy(retstring, "\e058C19OK");
|
||||
strncpy(retstring, "\e058C19OK", 64);
|
||||
else
|
||||
sprintf_(retstring, "\eE85230FAILED (%#lx)", ret);
|
||||
KPrint("%s %s", driver->Name, retstring);
|
||||
@ -477,7 +459,7 @@ namespace Driver
|
||||
void DriverInterruptHook::OnInterruptReceived(void *Frame)
|
||||
#endif
|
||||
{
|
||||
CriticalSection cs; // or SmartCriticalSection(DriverInitLock); ?
|
||||
SmartCriticalSection(DriverInterruptLock);
|
||||
((int (*)(void *))(Handle))(Data);
|
||||
}
|
||||
|
131
Core/Driver/DriverAPI.cpp
Normal file
131
Core/Driver/DriverAPI.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <driver.hpp>
|
||||
|
||||
#include <dumper.hpp>
|
||||
#include <lock.hpp>
|
||||
|
||||
#include "../../kernel.h"
|
||||
#include "../../Fex.hpp"
|
||||
#include "api.hpp"
|
||||
|
||||
NewLock(DriverDisplayPrintLock);
|
||||
|
||||
void DriverDebugPrint(char *String, unsigned long DriverUID)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
trace("[%ld] %s", DriverUID, String);
|
||||
}
|
||||
|
||||
void DriverDisplayPrint(char *String)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
for (unsigned long i = 0; i < strlen(String); i++)
|
||||
Display->Print(String[i], 0, true);
|
||||
}
|
||||
|
||||
void *RequestPage(unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
// debug("Requesting %ld pages from the kernel...", Size);
|
||||
void *ret = KernelAllocator.RequestPages(Size);
|
||||
// debug("Got %#lx", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FreePage(void *Page, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Freeing %ld pages from the address %#lx...", Size, (unsigned long)Page);
|
||||
KernelAllocator.FreePages(Page, Size);
|
||||
}
|
||||
|
||||
void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags);
|
||||
Memory::Virtual().Map(VirtualAddress, PhysicalAddress, Flags);
|
||||
}
|
||||
|
||||
void UnmapMemory(void *VirtualAddress)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
debug("Unmapping %#lx...", (unsigned long)VirtualAddress);
|
||||
Memory::Virtual().Unmap(VirtualAddress);
|
||||
}
|
||||
|
||||
void *Drivermemcpy(void *Destination, void *Source, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
// debug("Copying %ld bytes from %#lx to %#lx...", Size, (unsigned long)Source, (unsigned long)Destination);
|
||||
return memcpy(Destination, Source, Size);
|
||||
}
|
||||
|
||||
void *Drivermemset(void *Destination, int Value, unsigned long Size)
|
||||
{
|
||||
SmartLock(DriverDisplayPrintLock);
|
||||
// debug("Setting %ld bytes from %#lx to %#x...", Size, (unsigned long)Destination, Value);
|
||||
return memset(Destination, Value, Size);
|
||||
}
|
||||
|
||||
void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
DumpData("DriverNetSend", Data, Size);
|
||||
}
|
||||
|
||||
void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size)
|
||||
{
|
||||
DumpData("DriverNetReceive", Data, Size);
|
||||
}
|
||||
|
||||
void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
|
||||
{
|
||||
DumpData("DriverDiskRead", Data, SectorCount * 512);
|
||||
}
|
||||
|
||||
void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
|
||||
{
|
||||
DumpData("DriverDiskWrite", Data, SectorCount * 512);
|
||||
}
|
||||
|
||||
char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID)
|
||||
{
|
||||
return (char *)"Unknown";
|
||||
}
|
||||
|
||||
KernelAPI KAPI = {
|
||||
.Version = {
|
||||
.Major = 0,
|
||||
.Minor = 0,
|
||||
.Patch = 1},
|
||||
.Info = {
|
||||
.Offset = 0,
|
||||
.DriverUID = 0,
|
||||
},
|
||||
.Memory = {
|
||||
.PageSize = PAGE_SIZE,
|
||||
.RequestPage = RequestPage,
|
||||
.FreePage = FreePage,
|
||||
.Map = MapMemory,
|
||||
.Unmap = UnmapMemory,
|
||||
},
|
||||
.PCI = {
|
||||
.GetDeviceName = DriverPCIGetDeviceName,
|
||||
},
|
||||
.Util = {
|
||||
.DebugPrint = DriverDebugPrint,
|
||||
.DisplayPrint = DriverDisplayPrint,
|
||||
.memcpy = Drivermemcpy,
|
||||
.memset = Drivermemset,
|
||||
},
|
||||
.Command = {
|
||||
.Network = {
|
||||
.SendPacket = DriverNetSend,
|
||||
.ReceivePacket = DriverNetReceive,
|
||||
},
|
||||
.Disk = {
|
||||
.AHCI = {
|
||||
.ReadSector = DriverAHCIDiskRead,
|
||||
.WriteSector = DriverAHCIDiskWrite,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
10
Core/Driver/api.hpp
Normal file
10
Core/Driver/api.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __FENNIX_KERNEL_DRIVER_API_H__
|
||||
#define __FENNIX_KERNEL_DRIVER_API_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include "../../DAPI.hpp"
|
||||
|
||||
extern KernelAPI KAPI;
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DRIVER_API_H__
|
@ -19,7 +19,7 @@
|
||||
#include "../crashhandler.hpp"
|
||||
#include "../kernel.h"
|
||||
|
||||
extern "C" __no_stack_protector void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); }
|
||||
extern "C" SafeFunction void ExceptionHandler(void *Data) { CrashHandler::Handle(Data); }
|
||||
|
||||
namespace Interrupts
|
||||
{
|
||||
@ -32,6 +32,7 @@ namespace Interrupts
|
||||
/* APIC::APIC */ void *apic[MAX_CPU];
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
void *InterruptFrames[INT_FRAMES_MAX];
|
||||
|
||||
void Initialize(int Core)
|
||||
{
|
||||
@ -103,25 +104,42 @@ namespace Interrupts
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void MainInterruptHandler(void *Data)
|
||||
void RemoveAll()
|
||||
{
|
||||
for (int i = 0; i < CPU::x64::IRQ223; i++)
|
||||
RegisteredEvents->DeleteNode(i);
|
||||
}
|
||||
|
||||
extern "C" SafeFunction void MainInterruptHandler(void *Data)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
|
||||
int Core = GetCurrentCPU()->ID;
|
||||
|
||||
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
|
||||
if (handler != (Handler *)0xdeadbeef)
|
||||
handler->OnInterruptReceived(Frame);
|
||||
else
|
||||
error("Unhandled IRQ%d on CPU %d.", Frame->InterruptNumber - 32, Core);
|
||||
memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0]));
|
||||
InterruptFrames[0] = (void *)Frame->rip;
|
||||
|
||||
CPUData *CoreData = GetCurrentCPU();
|
||||
int Core = 0;
|
||||
if (likely(CoreData != nullptr))
|
||||
Core = CoreData->ID;
|
||||
|
||||
if (apic[Core])
|
||||
// If this is false, we have a big problem.
|
||||
if (likely(Frame->InterruptNumber < CPU::x64::IRQ223 && Frame->InterruptNumber > CPU::x64::ISR0))
|
||||
{
|
||||
((APIC::APIC *)Interrupts::apic[Core])->EOI();
|
||||
// TODO: Handle PIC too
|
||||
return;
|
||||
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
|
||||
if (likely(handler != (Handler *)0xdeadbeef))
|
||||
handler->OnInterruptReceived(Frame);
|
||||
else
|
||||
error("Unhandled IRQ%ld on CPU %d.", Frame->InterruptNumber - 32, Core);
|
||||
|
||||
if (likely(apic[Core]))
|
||||
{
|
||||
((APIC::APIC *)Interrupts::apic[Core])->EOI();
|
||||
// TODO: Handle PIC too
|
||||
return;
|
||||
}
|
||||
// TODO: PIC
|
||||
}
|
||||
// TODO: PIC
|
||||
#elif defined(__i386__)
|
||||
void *Frame = Data;
|
||||
#elif defined(__aarch64__)
|
||||
|
@ -20,6 +20,15 @@ void LockClass::DeadLock(SpinLockData Lock)
|
||||
|
||||
this->DeadLocks++;
|
||||
|
||||
if (Config.UnlockDeadLock && this->DeadLocks > 10)
|
||||
{
|
||||
warn("Unlocking lock '%s' held by '%s'! %ld locks in queue. Core %ld is being held by %ld.",
|
||||
Lock.AttemptingToGet, Lock.CurrentHolder,
|
||||
Lock.Count, CCore, Lock.Core);
|
||||
this->DeadLocks = 0;
|
||||
this->Unlock();
|
||||
}
|
||||
|
||||
if (TaskManager)
|
||||
TaskManager->Schedule();
|
||||
}
|
||||
|
@ -2,6 +2,72 @@
|
||||
|
||||
namespace Xalloc
|
||||
{
|
||||
class XLockClass
|
||||
{
|
||||
struct SpinLockData
|
||||
{
|
||||
uint64_t LockData = 0x0;
|
||||
const char *CurrentHolder = "(nul)";
|
||||
const char *AttemptingToGet = "(nul)";
|
||||
uint64_t Count = 0;
|
||||
};
|
||||
|
||||
void DeadLock(SpinLockData Lock)
|
||||
{
|
||||
Xalloc_warn("Potential deadlock in lock '%s' held by '%s'! %ld locks in queue.", Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count);
|
||||
}
|
||||
|
||||
private:
|
||||
SpinLockData LockData;
|
||||
bool IsLocked = false;
|
||||
|
||||
public:
|
||||
int Lock(const char *FunctionName)
|
||||
{
|
||||
LockData.AttemptingToGet = FunctionName;
|
||||
Retry:
|
||||
unsigned int i = 0;
|
||||
while (__atomic_exchange_n(&IsLocked, true, __ATOMIC_ACQUIRE) && ++i < 0x10000000)
|
||||
;
|
||||
if (i >= 0x10000000)
|
||||
{
|
||||
DeadLock(LockData);
|
||||
goto Retry;
|
||||
}
|
||||
LockData.Count++;
|
||||
LockData.CurrentHolder = FunctionName;
|
||||
__sync_synchronize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Unlock()
|
||||
{
|
||||
__sync_synchronize();
|
||||
__atomic_store_n(&IsLocked, false, __ATOMIC_RELEASE);
|
||||
LockData.Count--;
|
||||
IsLocked = false;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class XSmartLock
|
||||
{
|
||||
private:
|
||||
XLockClass *LockPointer = nullptr;
|
||||
|
||||
public:
|
||||
XSmartLock(XLockClass &Lock, const char *FunctionName)
|
||||
{
|
||||
this->LockPointer = &Lock;
|
||||
this->LockPointer->Lock(FunctionName);
|
||||
}
|
||||
~XSmartLock() { this->LockPointer->Unlock(); }
|
||||
};
|
||||
|
||||
XLockClass XLock;
|
||||
|
||||
#define XSL XSmartLock CONCAT(lock##_, __COUNTER__)(XLock, __FUNCTION__)
|
||||
|
||||
class SmartSMAPClass
|
||||
{
|
||||
private:
|
||||
@ -20,6 +86,7 @@ namespace Xalloc
|
||||
AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled)
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
void *Position = Address;
|
||||
UserMapping = UserMode;
|
||||
SMAPUsed = SMAPEnabled;
|
||||
@ -47,6 +114,7 @@ namespace Xalloc
|
||||
AllocatorV1::~AllocatorV1()
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
Xalloc_trace("Destructor not implemented yet.");
|
||||
}
|
||||
|
||||
@ -81,6 +149,7 @@ namespace Xalloc
|
||||
void *AllocatorV1::Malloc(Xuint64_t Size)
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
if (this->HeapStart == nullptr)
|
||||
{
|
||||
Xalloc_err("Memory allocation not initialized yet!");
|
||||
@ -136,12 +205,14 @@ namespace Xalloc
|
||||
CurrentSegment = CurrentSegment->Next;
|
||||
}
|
||||
ExpandHeap(Size);
|
||||
XLock.Unlock();
|
||||
return this->Malloc(Size);
|
||||
}
|
||||
|
||||
void AllocatorV1::Free(void *Address)
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
if (this->HeapStart == nullptr)
|
||||
{
|
||||
Xalloc_err("Memory allocation not initialized yet!");
|
||||
@ -156,6 +227,7 @@ namespace Xalloc
|
||||
void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size)
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
if (this->HeapStart == nullptr)
|
||||
{
|
||||
Xalloc_err("Memory allocation not initialized yet!");
|
||||
@ -168,7 +240,10 @@ namespace Xalloc
|
||||
Size = 0x10;
|
||||
}
|
||||
|
||||
XLock.Unlock();
|
||||
void *Block = this->Malloc(NumberOfBlocks * Size);
|
||||
XLock.Lock(__FUNCTION__);
|
||||
|
||||
if (Block)
|
||||
Xmemset(Block, 0, NumberOfBlocks * Size);
|
||||
return Block;
|
||||
@ -177,6 +252,7 @@ namespace Xalloc
|
||||
void *AllocatorV1::Realloc(void *Address, Xuint64_t Size)
|
||||
{
|
||||
SmartSMAP;
|
||||
XSL;
|
||||
if (this->HeapStart == nullptr)
|
||||
{
|
||||
Xalloc_err("Memory allocation not initialized yet!");
|
||||
@ -184,11 +260,13 @@ namespace Xalloc
|
||||
}
|
||||
if (!Address && Size == 0)
|
||||
{
|
||||
XLock.Unlock();
|
||||
this->Free(Address);
|
||||
return nullptr;
|
||||
}
|
||||
else if (!Address)
|
||||
{
|
||||
XLock.Unlock();
|
||||
return this->Calloc(Size, sizeof(char));
|
||||
}
|
||||
|
||||
@ -198,7 +276,9 @@ namespace Xalloc
|
||||
Size = 0x10;
|
||||
}
|
||||
|
||||
XLock.Unlock();
|
||||
void *newAddress = this->Calloc(Size, sizeof(char));
|
||||
XLock.Lock(__FUNCTION__);
|
||||
Xmemcpy(newAddress, Address, Size);
|
||||
return newAddress;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None;
|
||||
Xalloc::AllocatorV1 *XallocV1Allocator = nullptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
void tracepagetable(PageTable *pt)
|
||||
__no_instrument_function void tracepagetable(PageTable *pt)
|
||||
{
|
||||
for (int i = 0; i < 512; i++)
|
||||
{
|
||||
@ -37,11 +37,12 @@ void tracepagetable(PageTable *pt)
|
||||
}
|
||||
#endif
|
||||
|
||||
void MapFromZero(PageTable *PT, BootInfo *Info)
|
||||
__no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info)
|
||||
{
|
||||
Virtual va = Virtual(PT);
|
||||
uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET;
|
||||
for (uint64_t t = 0; t < Info->Memory.Size; t += PAGE_SIZE)
|
||||
uint64_t MemSize = Info->Memory.Size;
|
||||
for (uint64_t t = 0; t < MemSize; t += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)t, (void *)t, PTFlag::RW);
|
||||
va.Map((void *)VirtualOffsetNormalVMA, (void *)t, PTFlag::RW);
|
||||
@ -49,7 +50,7 @@ void MapFromZero(PageTable *PT, BootInfo *Info)
|
||||
}
|
||||
}
|
||||
|
||||
void MapFramebuffer(PageTable *PT, BootInfo *Info)
|
||||
__no_instrument_function void MapFramebuffer(PageTable *PT, BootInfo *Info)
|
||||
{
|
||||
Virtual va = Virtual(PT);
|
||||
int itrfb = 0;
|
||||
@ -66,7 +67,7 @@ void MapFramebuffer(PageTable *PT, BootInfo *Info)
|
||||
}
|
||||
}
|
||||
|
||||
void MapKernel(PageTable *PT, BootInfo *Info)
|
||||
__no_instrument_function void MapKernel(PageTable *PT, BootInfo *Info)
|
||||
{
|
||||
/* KernelStart KernelTextEnd KernelRoDataEnd KernelEnd
|
||||
Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End
|
||||
@ -79,28 +80,30 @@ void MapKernel(PageTable *PT, BootInfo *Info)
|
||||
uint64_t KernelEnd = (uint64_t)&_kernel_end;
|
||||
|
||||
uint64_t BaseKernelMapAddress = (uint64_t)Info->Kernel.PhysicalBase;
|
||||
for (uint64_t k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
|
||||
uint64_t k;
|
||||
|
||||
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
for (uint64_t k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
|
||||
for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
for (uint64_t k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
|
||||
for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::P);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
BaseKernelMapAddress += PAGE_SIZE;
|
||||
}
|
||||
|
||||
for (uint64_t k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
|
||||
for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||
@ -111,8 +114,9 @@ void MapKernel(PageTable *PT, BootInfo *Info)
|
||||
KernelStart, KernelTextEnd, KernelRoDataEnd, KernelEnd, Info->Kernel.PhysicalBase, BaseKernelMapAddress - PAGE_SIZE);
|
||||
}
|
||||
|
||||
void InitializeMemoryManagement(BootInfo *Info)
|
||||
__no_instrument_function void InitializeMemoryManagement(BootInfo *Info)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||
{
|
||||
uint64_t Base = reinterpret_cast<uint64_t>(Info->Memory.Entry[i].BaseAddress);
|
||||
@ -122,7 +126,7 @@ void InitializeMemoryManagement(BootInfo *Info)
|
||||
|
||||
switch (Info->Memory.Entry[i].Type)
|
||||
{
|
||||
case Usable:
|
||||
case likely(Usable):
|
||||
Type = "Usable";
|
||||
break;
|
||||
case Reserved:
|
||||
@ -150,12 +154,13 @@ void InitializeMemoryManagement(BootInfo *Info)
|
||||
break;
|
||||
}
|
||||
|
||||
trace("%lld: %#016llx-%#016llx %s",
|
||||
debug("%lld: %#016llx-%#016llx %s",
|
||||
i,
|
||||
Base,
|
||||
End,
|
||||
Type);
|
||||
}
|
||||
#endif
|
||||
|
||||
trace("Initializing Physical Memory Manager");
|
||||
KernelAllocator = Physical();
|
||||
@ -177,7 +182,8 @@ void InitializeMemoryManagement(BootInfo *Info)
|
||||
debug("Mapping from 0x0 to %#llx", Info->Memory.Size);
|
||||
MapFromZero(KernelPageTable, Info);
|
||||
debug("Mapping from 0x0 %#llx for Userspace Page Table", Info->Memory.Size);
|
||||
MapFromZero(UserspaceKernelOnlyPageTable, Info);
|
||||
UserspaceKernelOnlyPageTable[0] = KernelPageTable[0]; // TODO: This is a hack to speed up the boot process
|
||||
// MapFromZero(UserspaceKernelOnlyPageTable, Info);
|
||||
|
||||
/* Mapping Framebuffer address */
|
||||
debug("Mapping Framebuffer");
|
||||
@ -219,10 +225,14 @@ void *HeapMalloc(uint64_t Size)
|
||||
{
|
||||
switch (AllocatorType)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
case unlikely(MemoryAllocatorType::Pages):
|
||||
return KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||
case MemoryAllocatorType::XallocV1:
|
||||
return XallocV1Allocator->Malloc(Size);
|
||||
{
|
||||
void *ret = XallocV1Allocator->Malloc(Size);
|
||||
memset(ret, 0, Size);
|
||||
return ret;
|
||||
}
|
||||
case MemoryAllocatorType::liballoc11:
|
||||
{
|
||||
void *ret = PREFIX(malloc)(Size);
|
||||
@ -238,10 +248,14 @@ void *HeapCalloc(uint64_t n, uint64_t Size)
|
||||
{
|
||||
switch (AllocatorType)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
case unlikely(MemoryAllocatorType::Pages):
|
||||
return KernelAllocator.RequestPages(TO_PAGES(n * Size));
|
||||
case MemoryAllocatorType::XallocV1:
|
||||
return XallocV1Allocator->Calloc(n, Size);
|
||||
{
|
||||
void *ret = XallocV1Allocator->Calloc(n, Size);
|
||||
memset(ret, 0, n * Size);
|
||||
return ret;
|
||||
}
|
||||
case MemoryAllocatorType::liballoc11:
|
||||
{
|
||||
void *ret = PREFIX(calloc)(n, Size);
|
||||
@ -257,10 +271,14 @@ void *HeapRealloc(void *Address, uint64_t Size)
|
||||
{
|
||||
switch (AllocatorType)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
case unlikely(MemoryAllocatorType::Pages):
|
||||
return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak
|
||||
case MemoryAllocatorType::XallocV1:
|
||||
return XallocV1Allocator->Realloc(Address, Size);
|
||||
{
|
||||
void *ret = XallocV1Allocator->Realloc(Address, Size);
|
||||
memset(ret, 0, Size);
|
||||
return ret;
|
||||
}
|
||||
case MemoryAllocatorType::liballoc11:
|
||||
{
|
||||
void *ret = PREFIX(realloc)(Address, Size);
|
||||
@ -276,11 +294,12 @@ void HeapFree(void *Address)
|
||||
{
|
||||
switch (AllocatorType)
|
||||
{
|
||||
case MemoryAllocatorType::Pages:
|
||||
case unlikely(MemoryAllocatorType::Pages):
|
||||
KernelAllocator.FreePage(Address); // WARNING: Potential memory leak
|
||||
break;
|
||||
case MemoryAllocatorType::XallocV1:
|
||||
XallocV1Allocator->Free(Address);
|
||||
if (XallocV1Allocator)
|
||||
XallocV1Allocator->Free(Address);
|
||||
break;
|
||||
case MemoryAllocatorType::liballoc11:
|
||||
PREFIX(free)
|
||||
@ -291,20 +310,32 @@ void HeapFree(void *Address)
|
||||
}
|
||||
}
|
||||
|
||||
void *operator new(size_t Size) {
|
||||
return HeapMalloc(Size); }
|
||||
void *operator new[](size_t Size) {
|
||||
return HeapMalloc(Size); }
|
||||
void *operator new(size_t Size)
|
||||
{
|
||||
return HeapMalloc(Size);
|
||||
}
|
||||
void *operator new[](size_t Size)
|
||||
{
|
||||
return HeapMalloc(Size);
|
||||
}
|
||||
void *operator new(unsigned long Size, std::align_val_t Alignment)
|
||||
{
|
||||
fixme("operator new with alignment(%#lx) is not implemented", Alignment);
|
||||
return HeapMalloc(Size);
|
||||
}
|
||||
void operator delete(void *Pointer) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete(void *Pointer, long unsigned int Size) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer, long unsigned int Size) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete(void *Pointer)
|
||||
{
|
||||
HeapFree(Pointer);
|
||||
}
|
||||
void operator delete[](void *Pointer)
|
||||
{
|
||||
HeapFree(Pointer);
|
||||
}
|
||||
void operator delete(void *Pointer, long unsigned int Size)
|
||||
{
|
||||
HeapFree(Pointer);
|
||||
}
|
||||
void operator delete[](void *Pointer, long unsigned int Size)
|
||||
{
|
||||
HeapFree(Pointer);
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ namespace Memory
|
||||
|
||||
trace("Reserving pages...");
|
||||
this->ReservePages(0, MemorySize / PAGE_SIZE + 1);
|
||||
trace("Unreserving usable pages...");
|
||||
trace("Unreserve usable pages...");
|
||||
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||
if (Info->Memory.Entry[i].Type == Usable)
|
||||
this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);
|
||||
|
@ -14,6 +14,8 @@ namespace Power
|
||||
{
|
||||
void Power::Reboot()
|
||||
{
|
||||
BeforeShutdown();
|
||||
|
||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||
((ACPI::DSDT *)this->dsdt)->Reboot();
|
||||
@ -42,6 +44,8 @@ namespace Power
|
||||
|
||||
void Power::Shutdown()
|
||||
{
|
||||
BeforeShutdown();
|
||||
|
||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||
((ACPI::DSDT *)this->dsdt)->Shutdown();
|
||||
|
@ -5,37 +5,32 @@
|
||||
|
||||
#ifndef STACK_CHK_GUARD_VALUE
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
#define STACK_CHK_GUARD_VALUE 0x25F6CC8D
|
||||
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC
|
||||
#else
|
||||
#define STACK_CHK_GUARD_VALUE 0xBADFE2EC255A8572
|
||||
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC00000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) uintptr_t __stack_chk_guard = 0;
|
||||
|
||||
__attribute__((weak)) uintptr_t __stack_chk_guard_init(void)
|
||||
__attribute__((weak, no_stack_protector)) uintptr_t __stack_chk_guard_init(void)
|
||||
{
|
||||
return STACK_CHK_GUARD_VALUE;
|
||||
}
|
||||
|
||||
static void __attribute__((constructor, no_stack_protector)) __construct_stk_chk_guard()
|
||||
extern __attribute__((constructor, no_stack_protector)) void __guard_setup(void)
|
||||
{
|
||||
debug("StackGuard: __guard_setup");
|
||||
if (__stack_chk_guard == 0)
|
||||
__stack_chk_guard = __stack_chk_guard_init();
|
||||
}
|
||||
|
||||
// https://opensource.apple.com/source/xnu/xnu-1504.7.4/libkern/stack_protector.c.auto.html
|
||||
// static void __guard_setup(void) __attribute__((constructor));
|
||||
|
||||
// static void __guard_setup(void)
|
||||
// {
|
||||
// read_random(__stack_chk_guard, sizeof(__stack_chk_guard));
|
||||
// }
|
||||
|
||||
__attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
||||
{
|
||||
TaskingPanic();
|
||||
error("Stack smashing detected!");
|
||||
for (short i = 0; i < 10; i++)
|
||||
error("Stack smashing detected!");
|
||||
debug("%#lx", __stack_chk_guard);
|
||||
KPrint("\eFF0000Stack smashing detected!");
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
while (1)
|
||||
@ -49,7 +44,8 @@ __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
||||
__attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
|
||||
{
|
||||
TaskingPanic();
|
||||
error("Buffer overflow detected!");
|
||||
for (short i = 0; i < 10; i++)
|
||||
error("Buffer overflow detected!");
|
||||
KPrint("\eFF0000Buffer overflow detected!");
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
while (1)
|
||||
|
@ -123,7 +123,7 @@ namespace SymbolResolver
|
||||
|
||||
Symbols::~Symbols() {}
|
||||
|
||||
const char *Symbols::GetSymbolFromAddress(uint64_t Address)
|
||||
const __no_instrument_function char *Symbols::GetSymbolFromAddress(uint64_t Address)
|
||||
{
|
||||
Symbols::SymbolTable Result{0, (char *)"<unknown>"};
|
||||
for (size_t i = 0; i < TotalEntries; i++)
|
||||
|
@ -115,27 +115,41 @@ const char *Type_Check_Kinds[] = {
|
||||
"Cast to virtual base of",
|
||||
};
|
||||
|
||||
// Prevent huge spam from ubsan
|
||||
bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
|
||||
{
|
||||
// blacklist
|
||||
if (strstr(file, "liballoc") || strstr(file, "cwalk"))
|
||||
// if (strstr(file, "liballoc") ||
|
||||
// strstr(file, "cwalk") ||
|
||||
// strstr(file, "AdvancedConfigurationandPowerInterface") ||
|
||||
// strstr(file, "SystemManagementBIOS"))
|
||||
// return false;
|
||||
|
||||
if (strstr(file, "AdvancedConfigurationandPowerInterface.cpp") &&
|
||||
(line == 17 && column == 47))
|
||||
return false;
|
||||
|
||||
static char *onceFile[512] = {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"};
|
||||
static uint32_t onceLine[512] = {0};
|
||||
static uint32_t onceColumn[512] = {0};
|
||||
static uint32_t onceCount = 0;
|
||||
if (strstr(file, "SystemManagementBIOS.cpp") &&
|
||||
((line == 30 && column == 21) ||
|
||||
(line == 27 && column == 49) ||
|
||||
(line == 45 && column == 26)))
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < onceCount; i++)
|
||||
if ((!strcmp(onceFile[i], file)) && onceLine[i] == line && onceColumn[i] == column)
|
||||
return false;
|
||||
if (strstr(file, "cwalk.c") &&
|
||||
((line == 1047 && column == 15)))
|
||||
return false;
|
||||
|
||||
if (strstr(file, "liballoc_1_1.c"))
|
||||
return false;
|
||||
|
||||
if (strstr(file, "display.hpp") &&
|
||||
((line == 113 && column == 43)))
|
||||
return false;
|
||||
|
||||
if (strstr(file, "Xalloc.hpp") &&
|
||||
(line == 48 && column == 28))
|
||||
return false;
|
||||
|
||||
onceFile[onceCount] = (char *)file;
|
||||
onceLine[onceCount] = line;
|
||||
onceColumn[onceCount] = column;
|
||||
ubsan("\t\tIn File: %s:%i:%i", file, line, column);
|
||||
onceCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,28 @@
|
||||
|
||||
#include <vector.hpp>
|
||||
#include <debug.h>
|
||||
#include <io.h>
|
||||
|
||||
volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
|
||||
Vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents;
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
__no_instrument_function uint8_t NoProfiler_inportb(uint16_t Port)
|
||||
{
|
||||
uint8_t Result;
|
||||
asm("in %%dx, %%al"
|
||||
: "=a"(Result)
|
||||
: "d"(Port));
|
||||
return Result;
|
||||
}
|
||||
|
||||
__no_instrument_function void NoProfiler_outportb(uint16_t Port, uint8_t Data)
|
||||
{
|
||||
asmv("out %%al, %%dx"
|
||||
:
|
||||
: "a"(Data), "d"(Port));
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace UniversalAsynchronousReceiverTransmitter
|
||||
{
|
||||
#define SERIAL_ENABLE_DLAB 0x80
|
||||
@ -14,7 +31,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
#define SERIAL_RATE_38400_HI 0x00
|
||||
#define SERIAL_BUFFER_EMPTY 0x20
|
||||
|
||||
UART::UART(SerialPorts Port)
|
||||
SafeFunction __no_instrument_function UART::UART(SerialPorts Port)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
if (Port == COMNULL)
|
||||
@ -57,16 +74,16 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
return;
|
||||
|
||||
// Initialize the serial port
|
||||
outb(Port + 1, 0x00); // Disable all interrupts
|
||||
outb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor)
|
||||
outb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud
|
||||
outb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte)
|
||||
outb(Port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
outb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
outb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
NoProfiler_outportb(Port + 1, 0x00); // Disable all interrupts
|
||||
NoProfiler_outportb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor)
|
||||
NoProfiler_outportb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud
|
||||
NoProfiler_outportb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte)
|
||||
NoProfiler_outportb(Port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
NoProfiler_outportb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
NoProfiler_outportb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
|
||||
// Check if the serial port is faulty.
|
||||
if (inb(Port + 0) != 0xAE)
|
||||
if (NoProfiler_inportb(Port + 0) != 0xAE)
|
||||
{
|
||||
static int once = 0;
|
||||
if (!once++)
|
||||
@ -76,50 +93,50 @@ namespace UniversalAsynchronousReceiverTransmitter
|
||||
}
|
||||
|
||||
// Set to normal operation mode.
|
||||
outb(Port + 4, 0x0F);
|
||||
NoProfiler_outportb(Port + 4, 0x0F);
|
||||
serialports[PortNumber] = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
UART::~UART() {}
|
||||
SafeFunction __no_instrument_function UART::~UART() {}
|
||||
|
||||
void UART::Write(uint8_t Char)
|
||||
SafeFunction __no_instrument_function void UART::Write(uint8_t Char)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
while ((inb(Port + 5) & SERIAL_BUFFER_EMPTY) == 0)
|
||||
while ((NoProfiler_inportb(Port + 5) & SERIAL_BUFFER_EMPTY) == 0)
|
||||
;
|
||||
outb(Port, Char);
|
||||
NoProfiler_outportb(Port, Char);
|
||||
#endif
|
||||
foreach (auto e in RegisteredEvents)
|
||||
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
||||
e->OnSent(Char);
|
||||
}
|
||||
|
||||
uint8_t UART::Read()
|
||||
SafeFunction __no_instrument_function uint8_t UART::Read()
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
while ((inb(Port + 5) & 1) == 0)
|
||||
while ((NoProfiler_inportb(Port + 5) & 1) == 0)
|
||||
;
|
||||
return inb(Port);
|
||||
return NoProfiler_inportb(Port);
|
||||
#endif
|
||||
foreach (auto e in RegisteredEvents)
|
||||
{
|
||||
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
e->OnReceived(inb(Port));
|
||||
e->OnReceived(NoProfiler_inportb(Port));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Events::Events(SerialPorts Port)
|
||||
SafeFunction __no_instrument_function Events::Events(SerialPorts Port)
|
||||
{
|
||||
this->Port = Port;
|
||||
RegisteredEvents.push_back(this);
|
||||
}
|
||||
|
||||
Events::~Events()
|
||||
SafeFunction __no_instrument_function Events::~Events()
|
||||
{
|
||||
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
||||
if (RegisteredEvents[i] == this)
|
||||
|
@ -2,10 +2,14 @@
|
||||
#define __FENNIX_KERNEL_CRASH_HANDELR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <interrupts.hpp>
|
||||
#include <cpu.hpp>
|
||||
|
||||
namespace CrashHandler
|
||||
{
|
||||
extern void *EHIntFrames[INT_FRAMES_MAX];
|
||||
|
||||
void EHPrint(const char *Format, ...);
|
||||
void Handle(void *Data);
|
||||
}
|
||||
|
Reference in New Issue
Block a user