Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more

This commit is contained in:
Alex
2022-11-28 08:25:37 +02:00
parent 2fba834d41
commit 0289054900
62 changed files with 1462 additions and 558 deletions

View File

@ -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"); }

View File

@ -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;

View File

@ -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.
}
}

View File

@ -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__)

View File

@ -17,7 +17,7 @@
namespace CrashHandler
{
__no_stack_protector void DisplayConsoleScreen(CRData data)
SafeFunction void DisplayConsoleScreen(CRData data)
{
EHPrint("TODO");
}

View File

@ -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",

View File

@ -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;

View File

@ -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");
}
}
}
}

View File

@ -17,7 +17,7 @@
namespace CrashHandler
{
__no_stack_protector void DisplayTasksScreen(CRData data)
SafeFunction void DisplayTasksScreen(CRData data)
{
const char *StatusColor[7] = {
"FF0000", // Unknown

View File

@ -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");

View File

@ -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;

View File

@ -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
View 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
View 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__

View File

@ -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__)

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -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)

View File

@ -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++)

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}