mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
Changed a lot of files. Summary: profiler support; "SafeFunction"; UnlockDeadLock kernel config; Code optimization & more
This commit is contained in:
parent
2fba834d41
commit
0289054900
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,8 @@
|
|||||||
*.o
|
*.o
|
||||||
|
*.su
|
||||||
|
*.gcno
|
||||||
*.map
|
*.map
|
||||||
*.fsys
|
*.fsys
|
||||||
*.log
|
*.log
|
||||||
Files/*.psf
|
Files/*.psf
|
||||||
|
.dccache
|
||||||
|
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -40,7 +40,8 @@
|
|||||||
"-Wl,-static,--no-dynamic-linker,-ztext",
|
"-Wl,-static,--no-dynamic-linker,-ztext",
|
||||||
"-shared",
|
"-shared",
|
||||||
"-zmax-page-size=0x1000",
|
"-zmax-page-size=0x1000",
|
||||||
"-nostdinc++"
|
"-nostdinc++",
|
||||||
|
"-fsanitize=undefined"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -42,7 +42,7 @@ static volatile struct limine_smbios_request SmbiosRequest = {
|
|||||||
.id = LIMINE_SMBIOS_REQUEST,
|
.id = LIMINE_SMBIOS_REQUEST,
|
||||||
.revision = 0};
|
.revision = 0};
|
||||||
|
|
||||||
void init_limine()
|
SafeFunction __no_instrument_function void init_limine()
|
||||||
{
|
{
|
||||||
struct BootInfo binfo;
|
struct BootInfo binfo;
|
||||||
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response;
|
struct limine_bootloader_info_response *BootloaderInfoResponse = BootloaderInfoRequest.response;
|
||||||
@ -211,8 +211,12 @@ void init_limine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000);
|
binfo.Modules[i].Address = (void *)((uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000);
|
||||||
strcpy(binfo.Modules[i].Path, ModuleResponse->modules[i]->path);
|
strncpy(binfo.Modules[i].Path,
|
||||||
strcpy(binfo.Modules[i].CommandLine, ModuleResponse->modules[i]->cmdline);
|
ModuleResponse->modules[i]->path,
|
||||||
|
strlen(ModuleResponse->modules[i]->path) + 1);
|
||||||
|
strncpy(binfo.Modules[i].CommandLine,
|
||||||
|
ModuleResponse->modules[i]->cmdline,
|
||||||
|
strlen(ModuleResponse->modules[i]->cmdline) + 1);
|
||||||
binfo.Modules[i].Size = ModuleResponse->modules[i]->size;
|
binfo.Modules[i].Size = ModuleResponse->modules[i]->size;
|
||||||
debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i,
|
debug("Module %d:\nAddress: %p\nPath: %s\nCommand Line: %s\nSize: %ld", i,
|
||||||
(uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000, ModuleResponse->modules[i]->path,
|
(uint64_t)ModuleResponse->modules[i]->address - 0xffff800000000000, ModuleResponse->modules[i]->path,
|
||||||
@ -234,13 +238,19 @@ void init_limine()
|
|||||||
binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base;
|
binfo.Kernel.PhysicalBase = (void *)KernelAddressResponse->physical_base;
|
||||||
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base;
|
binfo.Kernel.VirtualBase = (void *)KernelAddressResponse->virtual_base;
|
||||||
binfo.Kernel.FileBase = KernelFileResponse->kernel_file->address;
|
binfo.Kernel.FileBase = KernelFileResponse->kernel_file->address;
|
||||||
strcpy(binfo.Kernel.CommandLine, KernelFileResponse->kernel_file->cmdline);
|
strncpy(binfo.Kernel.CommandLine,
|
||||||
|
KernelFileResponse->kernel_file->cmdline,
|
||||||
|
strlen(KernelFileResponse->kernel_file->cmdline) + 1);
|
||||||
binfo.Kernel.Size = KernelFileResponse->kernel_file->size;
|
binfo.Kernel.Size = KernelFileResponse->kernel_file->size;
|
||||||
trace("Kernel physical address: %p", KernelAddressResponse->physical_base);
|
trace("Kernel physical address: %p", KernelAddressResponse->physical_base);
|
||||||
trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base);
|
trace("Kernel virtual address: %p", KernelAddressResponse->virtual_base);
|
||||||
|
|
||||||
strcpy(binfo.Bootloader.Name, BootloaderInfoResponse->name);
|
strncpy(binfo.Bootloader.Name,
|
||||||
strcpy(binfo.Bootloader.Version, BootloaderInfoResponse->version);
|
BootloaderInfoResponse->name,
|
||||||
|
strlen(BootloaderInfoResponse->name) + 1);
|
||||||
|
strncpy(binfo.Bootloader.Version,
|
||||||
|
BootloaderInfoResponse->version,
|
||||||
|
strlen(BootloaderInfoResponse->version) + 1);
|
||||||
|
|
||||||
// Call kernel entry point
|
// Call kernel entry point
|
||||||
Entry(&binfo);
|
Entry(&binfo);
|
||||||
|
@ -89,7 +89,7 @@ namespace GlobalDescriptorTable
|
|||||||
|
|
||||||
void *CPUStackPointer[MAX_CPU];
|
void *CPUStackPointer[MAX_CPU];
|
||||||
|
|
||||||
__no_stack_protector void Init(int Core)
|
SafeFunction void Init(int Core)
|
||||||
{
|
{
|
||||||
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
|
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
|
||||||
gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
|
gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
|
||||||
@ -143,7 +143,7 @@ namespace GlobalDescriptorTable
|
|||||||
trace("Global Descriptor Table initialized");
|
trace("Global Descriptor Table initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void SetKernelStack(void *Stack)
|
SafeFunction void SetKernelStack(void *Stack)
|
||||||
{
|
{
|
||||||
if (Stack)
|
if (Stack)
|
||||||
tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack;
|
tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack;
|
||||||
|
@ -29,6 +29,24 @@ SECTIONS
|
|||||||
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
|
_kernel_rodata_end = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||||
. += CONSTANT(MAXPAGESIZE);
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN(__init_array_start = .);
|
||||||
|
KEEP(*(.init_array .ctors))
|
||||||
|
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||||
|
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP(*(.fini_array .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
}
|
||||||
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
|
@ -92,12 +92,16 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
|
|||||||
{
|
{
|
||||||
case MULTIBOOT_TAG_TYPE_CMDLINE:
|
case MULTIBOOT_TAG_TYPE_CMDLINE:
|
||||||
{
|
{
|
||||||
strcpy(binfo.Kernel.CommandLine, ((multiboot_tag_string *)Tag)->string);
|
strncpy(binfo.Kernel.CommandLine,
|
||||||
|
((multiboot_tag_string *)Tag)->string,
|
||||||
|
strlen(((multiboot_tag_string *)Tag)->string));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
|
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
|
||||||
{
|
{
|
||||||
strcpy(binfo.Bootloader.Name, ((multiboot_tag_string *)Tag)->string);
|
strncpy(binfo.Bootloader.Name,
|
||||||
|
((multiboot_tag_string *)Tag)->string,
|
||||||
|
strlen(((multiboot_tag_string *)Tag)->string));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MULTIBOOT_TAG_TYPE_MODULE:
|
case MULTIBOOT_TAG_TYPE_MODULE:
|
||||||
@ -106,8 +110,9 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
|
|||||||
static int module_count = 0;
|
static int module_count = 0;
|
||||||
binfo.Modules[module_count++].Address = (void *)module->mod_start;
|
binfo.Modules[module_count++].Address = (void *)module->mod_start;
|
||||||
binfo.Modules[module_count++].Size = module->size;
|
binfo.Modules[module_count++].Size = module->size;
|
||||||
strcpy(binfo.Modules[module_count++].Path, "(null)");
|
strncpy(binfo.Modules[module_count++].Path, "(null)", 6);
|
||||||
strcpy(binfo.Modules[module_count++].CommandLine, module->cmdline);
|
strncpy(binfo.Modules[module_count++].CommandLine, module->cmdline,
|
||||||
|
strlen(module->cmdline));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
|
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
|
||||||
@ -332,7 +337,7 @@ EXTERNC void x32Multiboot2Entry(multiboot_info *Info, unsigned int Magic)
|
|||||||
vm[12] = 0x0579;
|
vm[12] = 0x0579;
|
||||||
vm[13] = 0x0565;
|
vm[13] = 0x0565;
|
||||||
vm[14] = 0x0574;
|
vm[14] = 0x0574;
|
||||||
|
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
// Entry(&binfo);
|
// Entry(&binfo);
|
||||||
}
|
}
|
||||||
|
@ -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 to a non-present page entry\n",
|
||||||
"User process tried to write a page and caused a protection fault\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");
|
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("\eDD2920System crashed!\n");
|
||||||
CrashHandler::EHPrint("Kernel triggered debug exception.\n");
|
CrashHandler::EHPrint("Kernel triggered debug exception.\n");
|
||||||
}
|
}
|
||||||
__no_stack_protector void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
|
SafeFunction void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
|
||||||
__no_stack_protector void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
|
SafeFunction void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
|
||||||
__no_stack_protector void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
|
SafeFunction void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
|
||||||
__no_stack_protector void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
|
SafeFunction void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
|
||||||
__no_stack_protector void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
|
SafeFunction void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
|
||||||
{
|
{
|
||||||
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
||||||
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n");
|
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n");
|
||||||
}
|
}
|
||||||
__no_stack_protector void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
|
SafeFunction void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
|
||||||
__no_stack_protector void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
|
SafeFunction void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
|
||||||
__no_stack_protector void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
|
SafeFunction void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
|
||||||
__no_stack_protector void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
|
SafeFunction void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
|
||||||
__no_stack_protector void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
|
SafeFunction void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
|
||||||
__no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
|
SafeFunction void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
|
||||||
{
|
{
|
||||||
CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode};
|
CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode};
|
||||||
CrashHandler::EHPrint("\eDD2920System crashed!\n");
|
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("Index: %#x\n", SelCode.Idx);
|
||||||
CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode);
|
CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode);
|
||||||
}
|
}
|
||||||
__no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
|
SafeFunction void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
|
||||||
{
|
{
|
||||||
// staticbuffer(descbuf);
|
// staticbuffer(descbuf);
|
||||||
// staticbuffer(desc_ext);
|
// staticbuffer(desc_ext);
|
||||||
@ -97,7 +97,7 @@ __no_stack_protector void GeneralProtectionExceptionHandler(CHArchTrapFrame *Fra
|
|||||||
CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
|
CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
|
||||||
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx);
|
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};
|
CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
|
||||||
CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF");
|
CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF");
|
||||||
@ -120,10 +120,10 @@ __no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
|
|||||||
else
|
else
|
||||||
CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
|
CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
|
||||||
}
|
}
|
||||||
__no_stack_protector void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
|
SafeFunction void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
|
||||||
__no_stack_protector void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
|
SafeFunction void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
|
||||||
__no_stack_protector void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
|
SafeFunction void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
|
||||||
__no_stack_protector void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
|
SafeFunction void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
|
||||||
__no_stack_protector void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
|
SafeFunction void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
|
||||||
__no_stack_protector void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
|
SafeFunction void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
|
||||||
__no_stack_protector void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }
|
SafeFunction void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }
|
||||||
|
@ -22,15 +22,16 @@ NewLock(UserInputLock);
|
|||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
|
void *EHIntFrames[INT_FRAMES_MAX];
|
||||||
static bool ExceptionOccurred = false;
|
static bool ExceptionOccurred = false;
|
||||||
int SBIdx = 255;
|
int SBIdx = 255;
|
||||||
__no_stack_protector void printfWrapper(char c, void *unused)
|
SafeFunction void printfWrapper(char c, void *unused)
|
||||||
{
|
{
|
||||||
Display->Print(c, SBIdx, true);
|
Display->Print(c, SBIdx, true);
|
||||||
UNUSED(unused);
|
UNUSED(unused);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void EHPrint(const char *Format, ...)
|
SafeFunction void EHPrint(const char *Format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, Format);
|
va_start(args, Format);
|
||||||
@ -38,7 +39,7 @@ namespace CrashHandler
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector char *trimwhitespace(char *str)
|
SafeFunction char *TrimWhiteSpace(char *str)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
while (*str == ' ')
|
while (*str == ' ')
|
||||||
@ -54,7 +55,7 @@ namespace CrashHandler
|
|||||||
|
|
||||||
CRData crashdata = {};
|
CRData crashdata = {};
|
||||||
|
|
||||||
__no_stack_protector void DisplayTopOverlay()
|
SafeFunction void DisplayTopOverlay()
|
||||||
{
|
{
|
||||||
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
||||||
Video::Font *f = Display->GetCurrentFont();
|
Video::Font *f = Display->GetCurrentFont();
|
||||||
@ -108,7 +109,7 @@ namespace CrashHandler
|
|||||||
Display->SetBufferCursor(SBIdx, 0, fi.Height + 10);
|
Display->SetBufferCursor(SBIdx, 0, fi.Height + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void DisplayBottomOverlay()
|
SafeFunction void DisplayBottomOverlay()
|
||||||
{
|
{
|
||||||
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx);
|
||||||
Video::Font *f = Display->GetCurrentFont();
|
Video::Font *f = Display->GetCurrentFont();
|
||||||
@ -122,7 +123,7 @@ namespace CrashHandler
|
|||||||
EHPrint("\eAAAAAA> \eFAFAFA");
|
EHPrint("\eAAAAAA> \eFAFAFA");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void ArrowInput(uint8_t key)
|
SafeFunction void ArrowInput(uint8_t key)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
@ -193,7 +194,7 @@ namespace CrashHandler
|
|||||||
Display->SetBuffer(SBIdx);
|
Display->SetBuffer(SBIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void UserInput(char *Input)
|
SafeFunction void UserInput(char *Input)
|
||||||
{
|
{
|
||||||
SmartCriticalSection(UserInputLock);
|
SmartCriticalSection(UserInputLock);
|
||||||
Display->ClearBuffer(SBIdx);
|
Display->ClearBuffer(SBIdx);
|
||||||
@ -209,6 +210,7 @@ namespace CrashHandler
|
|||||||
EHPrint("showbuf <INDEX> - Display the contents of a screen buffer.\n");
|
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(" - 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(" - \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("main - Show the main screen.\n");
|
||||||
EHPrint("details - Show the details screen.\n");
|
EHPrint("details - Show the details screen.\n");
|
||||||
EHPrint("frames - Show the stack frame screen.\n");
|
EHPrint("frames - Show the stack frame screen.\n");
|
||||||
@ -223,25 +225,66 @@ namespace CrashHandler
|
|||||||
{
|
{
|
||||||
PowerManager->Shutdown();
|
PowerManager->Shutdown();
|
||||||
EHPrint("\eFFFFFFNow it's safe to turn off your computer.");
|
EHPrint("\eFFFFFFNow it's safe to turn off your computer.");
|
||||||
|
Display->SetBuffer(SBIdx);
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
else if (strcmp(Input, "reboot") == 0)
|
else if (strcmp(Input, "reboot") == 0)
|
||||||
{
|
{
|
||||||
PowerManager->Reboot();
|
PowerManager->Reboot();
|
||||||
EHPrint("\eFFFFFFNow it's safe to reboot your computer.");
|
EHPrint("\eFFFFFFNow it's safe to reboot your computer.");
|
||||||
|
Display->SetBuffer(SBIdx);
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
else if (strncmp(Input, "showbuf", 7) == 0)
|
else if (strncmp(Input, "showbuf", 7) == 0)
|
||||||
{
|
{
|
||||||
char *arg = trimwhitespace(Input + 7);
|
char *arg = TrimWhiteSpace(Input + 7);
|
||||||
int tmpidx = SBIdx;
|
int tmpidx = SBIdx;
|
||||||
SBIdx = atoi(arg);
|
SBIdx = atoi(arg);
|
||||||
Display->SetBuffer(SBIdx);
|
Display->SetBuffer(SBIdx);
|
||||||
for (int i = 0; i < 1000000; i++)
|
for (int i = 0; i < 5000000; i++)
|
||||||
inb(0x80);
|
inb(0x80);
|
||||||
SBIdx = tmpidx;
|
SBIdx = tmpidx;
|
||||||
Display->SetBuffer(SBIdx);
|
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)
|
else if (strcmp(Input, "main") == 0)
|
||||||
{
|
{
|
||||||
SBIdx = 255;
|
SBIdx = 255;
|
||||||
@ -286,11 +329,14 @@ namespace CrashHandler
|
|||||||
Display->SetBuffer(SBIdx);
|
Display->SetBuffer(SBIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Handle(void *Data)
|
SafeFunction void Handle(void *Data)
|
||||||
{
|
{
|
||||||
// TODO: SUPPORT SMP
|
// TODO: SUPPORT SMP
|
||||||
CPU::Interrupts(CPU::Disable);
|
CPU::Interrupts(CPU::Disable);
|
||||||
error("An exception occurred!");
|
error("An exception occurred!");
|
||||||
|
for (size_t i = 0; i < INT_FRAMES_MAX; i++)
|
||||||
|
EHIntFrames[i] = Interrupts::InterruptFrames[i];
|
||||||
|
|
||||||
SBIdx = 255;
|
SBIdx = 255;
|
||||||
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
|
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -299,27 +345,11 @@ namespace CrashHandler
|
|||||||
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
|
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
|
||||||
{
|
{
|
||||||
debug("Exception in kernel mode");
|
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)
|
if (TaskManager)
|
||||||
TaskManager->Panic();
|
TaskManager->Panic();
|
||||||
|
debug("ePanicSchedStop");
|
||||||
Display->CreateBuffer(0, 0, SBIdx);
|
Display->CreateBuffer(0, 0, SBIdx);
|
||||||
|
debug("e0");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -348,7 +378,9 @@ namespace CrashHandler
|
|||||||
{
|
{
|
||||||
SBIdx = 255;
|
SBIdx = 255;
|
||||||
Display->ClearBuffer(SBIdx);
|
Display->ClearBuffer(SBIdx);
|
||||||
|
debug("e0-1");
|
||||||
Display->SetBufferCursor(SBIdx, 0, 0);
|
Display->SetBufferCursor(SBIdx, 0, 0);
|
||||||
|
debug("e0-2");
|
||||||
|
|
||||||
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
|
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
|
||||||
CPU::x64::CR2 cr2 = CPU::x64::readcr2();
|
CPU::x64::CR2 cr2 = CPU::x64::readcr2();
|
||||||
@ -405,6 +437,7 @@ namespace CrashHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExceptionOccurred = true;
|
ExceptionOccurred = true;
|
||||||
|
Interrupts::RemoveAll();
|
||||||
|
|
||||||
debug("Reading control registers...");
|
debug("Reading control registers...");
|
||||||
crashdata.Frame = Frame;
|
crashdata.Frame = Frame;
|
||||||
|
@ -103,11 +103,11 @@ namespace CrashHandler
|
|||||||
static char UserInputBuffer[1024];
|
static char UserInputBuffer[1024];
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
__no_stack_protector void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t scanCode = inb(0x60);
|
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.
|
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.
|
// CPU::Halt(true); // This is an infinite loop.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace CrashHandler
|
|||||||
uint64_t rip;
|
uint64_t rip;
|
||||||
};
|
};
|
||||||
|
|
||||||
__no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count)
|
SafeFunction void TraceFrames(CHArchTrapFrame *Frame, int Count)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
__no_stack_protector void DisplayConsoleScreen(CRData data)
|
SafeFunction void DisplayConsoleScreen(CRData data)
|
||||||
{
|
{
|
||||||
EHPrint("TODO");
|
EHPrint("TODO");
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
__no_stack_protector void DisplayDetailsScreen(CRData data)
|
SafeFunction void DisplayDetailsScreen(CRData data)
|
||||||
{
|
{
|
||||||
if (data.Process)
|
if (data.Process)
|
||||||
EHPrint("\e7981FCCurrent Process: %s(%ld)\n",
|
EHPrint("\e7981FCCurrent Process: %s(%ld)\n",
|
||||||
|
@ -27,7 +27,7 @@ static const char *PagefaultDescriptions[8] = {
|
|||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
__no_stack_protector void DisplayMainScreen(CRData data)
|
SafeFunction void DisplayMainScreen(CRData data)
|
||||||
{
|
{
|
||||||
CHArchTrapFrame *Frame = data.Frame;
|
CHArchTrapFrame *Frame = data.Frame;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "../../crashhandler.hpp"
|
#include "../../crashhandler.hpp"
|
||||||
#include "../chfcts.hpp"
|
#include "../chfcts.hpp"
|
||||||
|
|
||||||
|
#include <interrupts.hpp>
|
||||||
#include <display.hpp>
|
#include <display.hpp>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
@ -17,9 +18,29 @@
|
|||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
__no_stack_protector void DisplayStackFrameScreen(CRData data)
|
SafeFunction void DisplayStackFrameScreen(CRData data)
|
||||||
{
|
{
|
||||||
EHPrint("\eFAFAFATracing 40 frames...\n");
|
EHPrint("\eFAFAFATracing 40 frames...\n");
|
||||||
TraceFrames(data.Frame, 40);
|
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
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
__no_stack_protector void DisplayTasksScreen(CRData data)
|
SafeFunction void DisplayTasksScreen(CRData data)
|
||||||
{
|
{
|
||||||
const char *StatusColor[7] = {
|
const char *StatusColor[7] = {
|
||||||
"FF0000", // Unknown
|
"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 to a non-present page entry\n",
|
||||||
"User process tried to write a page and caused a protection fault\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;
|
CriticalSection cs;
|
||||||
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");
|
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");
|
||||||
|
@ -8,13 +8,13 @@ NewLock(DebuggerLock);
|
|||||||
|
|
||||||
using namespace UniversalAsynchronousReceiverTransmitter;
|
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);
|
UART(COM1).Write(c);
|
||||||
(void)unused;
|
(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;
|
const char *DbgLvlString;
|
||||||
switch (Level)
|
switch (Level)
|
||||||
@ -52,7 +52,7 @@ static inline void WritePrefix(DebugLevel Level, const char *File, int Line, con
|
|||||||
|
|
||||||
namespace SysDbg
|
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);
|
WritePrefix(Level, File, Line, Function);
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -61,7 +61,7 @@ namespace SysDbg
|
|||||||
va_end(args);
|
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);
|
// SmartLock(DebuggerLock);
|
||||||
WritePrefix(Level, File, Line, Function);
|
WritePrefix(Level, File, Line, Function);
|
||||||
@ -74,7 +74,7 @@ namespace SysDbg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// C compatibility
|
// 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);
|
WritePrefix(Level, File, Line, Function);
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -84,7 +84,7 @@ extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// C compatibility
|
// 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);
|
WritePrefix(Level, File, Line, Function);
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -2,19 +2,19 @@
|
|||||||
|
|
||||||
#include <interrupts.hpp>
|
#include <interrupts.hpp>
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
#include <dumper.hpp>
|
|
||||||
#include <task.hpp>
|
#include <task.hpp>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
#include <cwalk.h>
|
#include <cwalk.h>
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
|
|
||||||
#include "../kernel.h"
|
#include "../../kernel.h"
|
||||||
#include "../DAPI.hpp"
|
#include "../../DAPI.hpp"
|
||||||
#include "../Fex.hpp"
|
#include "../../Fex.hpp"
|
||||||
|
#include "api.hpp"
|
||||||
|
|
||||||
NewLock(DriverInitLock);
|
NewLock(DriverInitLock);
|
||||||
NewLock(DriverDisplayPrintLock);
|
NewLock(DriverInterruptLock);
|
||||||
|
|
||||||
namespace Driver
|
namespace Driver
|
||||||
{
|
{
|
||||||
@ -28,127 +28,6 @@ namespace Driver
|
|||||||
"Input",
|
"Input",
|
||||||
"Audio"};
|
"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)
|
int Driver::IOCB(unsigned long DUID, void *KCB)
|
||||||
{
|
{
|
||||||
foreach (auto var in Drivers)
|
foreach (auto var in Drivers)
|
||||||
@ -411,7 +290,48 @@ namespace Driver
|
|||||||
}
|
}
|
||||||
case FexDriverType::FexDriverType_Input:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case FexDriverType::FexDriverType_Audio:
|
case FexDriverType::FexDriverType_Audio:
|
||||||
@ -430,6 +350,68 @@ namespace Driver
|
|||||||
{
|
{
|
||||||
fixme("Process driver: %s", DrvExtHdr->Driver.Name);
|
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
|
else
|
||||||
{
|
{
|
||||||
error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type);
|
error("Unknown driver bind type: %d", DrvExtHdr->Driver.Bind.Type);
|
||||||
@ -454,9 +436,9 @@ namespace Driver
|
|||||||
if (!strcmp(extension, ".fex"))
|
if (!strcmp(extension, ".fex"))
|
||||||
{
|
{
|
||||||
uint64_t ret = this->LoadDriver(driver->Address, driver->Length);
|
uint64_t ret = this->LoadDriver(driver->Address, driver->Length);
|
||||||
char retstring[64];
|
char retstring[128];
|
||||||
if (ret == DriverCode::OK)
|
if (ret == DriverCode::OK)
|
||||||
strcpy(retstring, "\e058C19OK");
|
strncpy(retstring, "\e058C19OK", 64);
|
||||||
else
|
else
|
||||||
sprintf_(retstring, "\eE85230FAILED (%#lx)", ret);
|
sprintf_(retstring, "\eE85230FAILED (%#lx)", ret);
|
||||||
KPrint("%s %s", driver->Name, retstring);
|
KPrint("%s %s", driver->Name, retstring);
|
||||||
@ -477,7 +459,7 @@ namespace Driver
|
|||||||
void DriverInterruptHook::OnInterruptReceived(void *Frame)
|
void DriverInterruptHook::OnInterruptReceived(void *Frame)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
CriticalSection cs; // or SmartCriticalSection(DriverInitLock); ?
|
SmartCriticalSection(DriverInterruptLock);
|
||||||
((int (*)(void *))(Handle))(Data);
|
((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 "../crashhandler.hpp"
|
||||||
#include "../kernel.h"
|
#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
|
namespace Interrupts
|
||||||
{
|
{
|
||||||
@ -32,6 +32,7 @@ namespace Interrupts
|
|||||||
/* APIC::APIC */ void *apic[MAX_CPU];
|
/* APIC::APIC */ void *apic[MAX_CPU];
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#endif
|
#endif
|
||||||
|
void *InterruptFrames[INT_FRAMES_MAX];
|
||||||
|
|
||||||
void Initialize(int Core)
|
void Initialize(int Core)
|
||||||
{
|
{
|
||||||
@ -103,25 +104,42 @@ namespace Interrupts
|
|||||||
#endif
|
#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__)
|
#if defined(__amd64__)
|
||||||
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
|
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
|
||||||
int Core = GetCurrentCPU()->ID;
|
|
||||||
|
|
||||||
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
|
memmove(InterruptFrames + 1, InterruptFrames, sizeof(InterruptFrames) - sizeof(InterruptFrames[0]));
|
||||||
if (handler != (Handler *)0xdeadbeef)
|
InterruptFrames[0] = (void *)Frame->rip;
|
||||||
handler->OnInterruptReceived(Frame);
|
|
||||||
else
|
CPUData *CoreData = GetCurrentCPU();
|
||||||
error("Unhandled IRQ%d on CPU %d.", Frame->InterruptNumber - 32, Core);
|
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();
|
Handler *handler = (Handler *)RegisteredEvents->Get(Frame->InterruptNumber);
|
||||||
// TODO: Handle PIC too
|
if (likely(handler != (Handler *)0xdeadbeef))
|
||||||
return;
|
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__)
|
#elif defined(__i386__)
|
||||||
void *Frame = Data;
|
void *Frame = Data;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
@ -20,6 +20,15 @@ void LockClass::DeadLock(SpinLockData Lock)
|
|||||||
|
|
||||||
this->DeadLocks++;
|
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)
|
if (TaskManager)
|
||||||
TaskManager->Schedule();
|
TaskManager->Schedule();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,72 @@
|
|||||||
|
|
||||||
namespace Xalloc
|
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
|
class SmartSMAPClass
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -20,6 +86,7 @@ namespace Xalloc
|
|||||||
AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled)
|
AllocatorV1::AllocatorV1(void *Address, bool UserMode, bool SMAPEnabled)
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
void *Position = Address;
|
void *Position = Address;
|
||||||
UserMapping = UserMode;
|
UserMapping = UserMode;
|
||||||
SMAPUsed = SMAPEnabled;
|
SMAPUsed = SMAPEnabled;
|
||||||
@ -47,6 +114,7 @@ namespace Xalloc
|
|||||||
AllocatorV1::~AllocatorV1()
|
AllocatorV1::~AllocatorV1()
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
Xalloc_trace("Destructor not implemented yet.");
|
Xalloc_trace("Destructor not implemented yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +149,7 @@ namespace Xalloc
|
|||||||
void *AllocatorV1::Malloc(Xuint64_t Size)
|
void *AllocatorV1::Malloc(Xuint64_t Size)
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
if (this->HeapStart == nullptr)
|
if (this->HeapStart == nullptr)
|
||||||
{
|
{
|
||||||
Xalloc_err("Memory allocation not initialized yet!");
|
Xalloc_err("Memory allocation not initialized yet!");
|
||||||
@ -136,12 +205,14 @@ namespace Xalloc
|
|||||||
CurrentSegment = CurrentSegment->Next;
|
CurrentSegment = CurrentSegment->Next;
|
||||||
}
|
}
|
||||||
ExpandHeap(Size);
|
ExpandHeap(Size);
|
||||||
|
XLock.Unlock();
|
||||||
return this->Malloc(Size);
|
return this->Malloc(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocatorV1::Free(void *Address)
|
void AllocatorV1::Free(void *Address)
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
if (this->HeapStart == nullptr)
|
if (this->HeapStart == nullptr)
|
||||||
{
|
{
|
||||||
Xalloc_err("Memory allocation not initialized yet!");
|
Xalloc_err("Memory allocation not initialized yet!");
|
||||||
@ -156,6 +227,7 @@ namespace Xalloc
|
|||||||
void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size)
|
void *AllocatorV1::Calloc(Xuint64_t NumberOfBlocks, Xuint64_t Size)
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
if (this->HeapStart == nullptr)
|
if (this->HeapStart == nullptr)
|
||||||
{
|
{
|
||||||
Xalloc_err("Memory allocation not initialized yet!");
|
Xalloc_err("Memory allocation not initialized yet!");
|
||||||
@ -168,7 +240,10 @@ namespace Xalloc
|
|||||||
Size = 0x10;
|
Size = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XLock.Unlock();
|
||||||
void *Block = this->Malloc(NumberOfBlocks * Size);
|
void *Block = this->Malloc(NumberOfBlocks * Size);
|
||||||
|
XLock.Lock(__FUNCTION__);
|
||||||
|
|
||||||
if (Block)
|
if (Block)
|
||||||
Xmemset(Block, 0, NumberOfBlocks * Size);
|
Xmemset(Block, 0, NumberOfBlocks * Size);
|
||||||
return Block;
|
return Block;
|
||||||
@ -177,6 +252,7 @@ namespace Xalloc
|
|||||||
void *AllocatorV1::Realloc(void *Address, Xuint64_t Size)
|
void *AllocatorV1::Realloc(void *Address, Xuint64_t Size)
|
||||||
{
|
{
|
||||||
SmartSMAP;
|
SmartSMAP;
|
||||||
|
XSL;
|
||||||
if (this->HeapStart == nullptr)
|
if (this->HeapStart == nullptr)
|
||||||
{
|
{
|
||||||
Xalloc_err("Memory allocation not initialized yet!");
|
Xalloc_err("Memory allocation not initialized yet!");
|
||||||
@ -184,11 +260,13 @@ namespace Xalloc
|
|||||||
}
|
}
|
||||||
if (!Address && Size == 0)
|
if (!Address && Size == 0)
|
||||||
{
|
{
|
||||||
|
XLock.Unlock();
|
||||||
this->Free(Address);
|
this->Free(Address);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
else if (!Address)
|
else if (!Address)
|
||||||
{
|
{
|
||||||
|
XLock.Unlock();
|
||||||
return this->Calloc(Size, sizeof(char));
|
return this->Calloc(Size, sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +276,9 @@ namespace Xalloc
|
|||||||
Size = 0x10;
|
Size = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XLock.Unlock();
|
||||||
void *newAddress = this->Calloc(Size, sizeof(char));
|
void *newAddress = this->Calloc(Size, sizeof(char));
|
||||||
|
XLock.Lock(__FUNCTION__);
|
||||||
Xmemcpy(newAddress, Address, Size);
|
Xmemcpy(newAddress, Address, Size);
|
||||||
return newAddress;
|
return newAddress;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None;
|
|||||||
Xalloc::AllocatorV1 *XallocV1Allocator = nullptr;
|
Xalloc::AllocatorV1 *XallocV1Allocator = nullptr;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void tracepagetable(PageTable *pt)
|
__no_instrument_function void tracepagetable(PageTable *pt)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 512; i++)
|
for (int i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
@ -37,11 +37,12 @@ void tracepagetable(PageTable *pt)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void MapFromZero(PageTable *PT, BootInfo *Info)
|
__no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info)
|
||||||
{
|
{
|
||||||
Virtual va = Virtual(PT);
|
Virtual va = Virtual(PT);
|
||||||
uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET;
|
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 *)t, (void *)t, PTFlag::RW);
|
||||||
va.Map((void *)VirtualOffsetNormalVMA, (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);
|
Virtual va = Virtual(PT);
|
||||||
int itrfb = 0;
|
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
|
/* KernelStart KernelTextEnd KernelRoDataEnd KernelEnd
|
||||||
Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End
|
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 KernelEnd = (uint64_t)&_kernel_end;
|
||||||
|
|
||||||
uint64_t BaseKernelMapAddress = (uint64_t)Info->Kernel.PhysicalBase;
|
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);
|
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||||
BaseKernelMapAddress += PAGE_SIZE;
|
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);
|
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||||
BaseKernelMapAddress += PAGE_SIZE;
|
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);
|
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::P);
|
||||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||||
BaseKernelMapAddress += PAGE_SIZE;
|
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);
|
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
||||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||||
@ -111,8 +114,9 @@ void MapKernel(PageTable *PT, BootInfo *Info)
|
|||||||
KernelStart, KernelTextEnd, KernelRoDataEnd, KernelEnd, Info->Kernel.PhysicalBase, BaseKernelMapAddress - PAGE_SIZE);
|
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++)
|
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||||
{
|
{
|
||||||
uint64_t Base = reinterpret_cast<uint64_t>(Info->Memory.Entry[i].BaseAddress);
|
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)
|
switch (Info->Memory.Entry[i].Type)
|
||||||
{
|
{
|
||||||
case Usable:
|
case likely(Usable):
|
||||||
Type = "Usable";
|
Type = "Usable";
|
||||||
break;
|
break;
|
||||||
case Reserved:
|
case Reserved:
|
||||||
@ -150,12 +154,13 @@ void InitializeMemoryManagement(BootInfo *Info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace("%lld: %#016llx-%#016llx %s",
|
debug("%lld: %#016llx-%#016llx %s",
|
||||||
i,
|
i,
|
||||||
Base,
|
Base,
|
||||||
End,
|
End,
|
||||||
Type);
|
Type);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
trace("Initializing Physical Memory Manager");
|
trace("Initializing Physical Memory Manager");
|
||||||
KernelAllocator = Physical();
|
KernelAllocator = Physical();
|
||||||
@ -177,7 +182,8 @@ void InitializeMemoryManagement(BootInfo *Info)
|
|||||||
debug("Mapping from 0x0 to %#llx", Info->Memory.Size);
|
debug("Mapping from 0x0 to %#llx", Info->Memory.Size);
|
||||||
MapFromZero(KernelPageTable, Info);
|
MapFromZero(KernelPageTable, Info);
|
||||||
debug("Mapping from 0x0 %#llx for Userspace Page Table", Info->Memory.Size);
|
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 */
|
/* Mapping Framebuffer address */
|
||||||
debug("Mapping Framebuffer");
|
debug("Mapping Framebuffer");
|
||||||
@ -219,10 +225,14 @@ void *HeapMalloc(uint64_t Size)
|
|||||||
{
|
{
|
||||||
switch (AllocatorType)
|
switch (AllocatorType)
|
||||||
{
|
{
|
||||||
case MemoryAllocatorType::Pages:
|
case unlikely(MemoryAllocatorType::Pages):
|
||||||
return KernelAllocator.RequestPages(TO_PAGES(Size));
|
return KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||||
case MemoryAllocatorType::XallocV1:
|
case MemoryAllocatorType::XallocV1:
|
||||||
return XallocV1Allocator->Malloc(Size);
|
{
|
||||||
|
void *ret = XallocV1Allocator->Malloc(Size);
|
||||||
|
memset(ret, 0, Size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case MemoryAllocatorType::liballoc11:
|
case MemoryAllocatorType::liballoc11:
|
||||||
{
|
{
|
||||||
void *ret = PREFIX(malloc)(Size);
|
void *ret = PREFIX(malloc)(Size);
|
||||||
@ -238,10 +248,14 @@ void *HeapCalloc(uint64_t n, uint64_t Size)
|
|||||||
{
|
{
|
||||||
switch (AllocatorType)
|
switch (AllocatorType)
|
||||||
{
|
{
|
||||||
case MemoryAllocatorType::Pages:
|
case unlikely(MemoryAllocatorType::Pages):
|
||||||
return KernelAllocator.RequestPages(TO_PAGES(n * Size));
|
return KernelAllocator.RequestPages(TO_PAGES(n * Size));
|
||||||
case MemoryAllocatorType::XallocV1:
|
case MemoryAllocatorType::XallocV1:
|
||||||
return XallocV1Allocator->Calloc(n, Size);
|
{
|
||||||
|
void *ret = XallocV1Allocator->Calloc(n, Size);
|
||||||
|
memset(ret, 0, n * Size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case MemoryAllocatorType::liballoc11:
|
case MemoryAllocatorType::liballoc11:
|
||||||
{
|
{
|
||||||
void *ret = PREFIX(calloc)(n, Size);
|
void *ret = PREFIX(calloc)(n, Size);
|
||||||
@ -257,10 +271,14 @@ void *HeapRealloc(void *Address, uint64_t Size)
|
|||||||
{
|
{
|
||||||
switch (AllocatorType)
|
switch (AllocatorType)
|
||||||
{
|
{
|
||||||
case MemoryAllocatorType::Pages:
|
case unlikely(MemoryAllocatorType::Pages):
|
||||||
return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak
|
return KernelAllocator.RequestPages(TO_PAGES(Size)); // WARNING: Potential memory leak
|
||||||
case MemoryAllocatorType::XallocV1:
|
case MemoryAllocatorType::XallocV1:
|
||||||
return XallocV1Allocator->Realloc(Address, Size);
|
{
|
||||||
|
void *ret = XallocV1Allocator->Realloc(Address, Size);
|
||||||
|
memset(ret, 0, Size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case MemoryAllocatorType::liballoc11:
|
case MemoryAllocatorType::liballoc11:
|
||||||
{
|
{
|
||||||
void *ret = PREFIX(realloc)(Address, Size);
|
void *ret = PREFIX(realloc)(Address, Size);
|
||||||
@ -276,11 +294,12 @@ void HeapFree(void *Address)
|
|||||||
{
|
{
|
||||||
switch (AllocatorType)
|
switch (AllocatorType)
|
||||||
{
|
{
|
||||||
case MemoryAllocatorType::Pages:
|
case unlikely(MemoryAllocatorType::Pages):
|
||||||
KernelAllocator.FreePage(Address); // WARNING: Potential memory leak
|
KernelAllocator.FreePage(Address); // WARNING: Potential memory leak
|
||||||
break;
|
break;
|
||||||
case MemoryAllocatorType::XallocV1:
|
case MemoryAllocatorType::XallocV1:
|
||||||
XallocV1Allocator->Free(Address);
|
if (XallocV1Allocator)
|
||||||
|
XallocV1Allocator->Free(Address);
|
||||||
break;
|
break;
|
||||||
case MemoryAllocatorType::liballoc11:
|
case MemoryAllocatorType::liballoc11:
|
||||||
PREFIX(free)
|
PREFIX(free)
|
||||||
@ -291,20 +310,32 @@ void HeapFree(void *Address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new(size_t Size) {
|
void *operator new(size_t Size)
|
||||||
return HeapMalloc(Size); }
|
{
|
||||||
void *operator new[](size_t Size) {
|
return HeapMalloc(Size);
|
||||||
return HeapMalloc(Size); }
|
}
|
||||||
|
void *operator new[](size_t Size)
|
||||||
|
{
|
||||||
|
return HeapMalloc(Size);
|
||||||
|
}
|
||||||
void *operator new(unsigned long Size, std::align_val_t Alignment)
|
void *operator new(unsigned long Size, std::align_val_t Alignment)
|
||||||
{
|
{
|
||||||
fixme("operator new with alignment(%#lx) is not implemented", Alignment);
|
fixme("operator new with alignment(%#lx) is not implemented", Alignment);
|
||||||
return HeapMalloc(Size);
|
return HeapMalloc(Size);
|
||||||
}
|
}
|
||||||
void operator delete(void *Pointer) {
|
void operator delete(void *Pointer)
|
||||||
HeapFree(Pointer); }
|
{
|
||||||
void operator delete[](void *Pointer) {
|
HeapFree(Pointer);
|
||||||
HeapFree(Pointer); }
|
}
|
||||||
void operator delete(void *Pointer, long unsigned int Size) {
|
void operator delete[](void *Pointer)
|
||||||
HeapFree(Pointer); }
|
{
|
||||||
void operator delete[](void *Pointer, long unsigned int Size) {
|
HeapFree(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...");
|
trace("Reserving pages...");
|
||||||
this->ReservePages(0, MemorySize / PAGE_SIZE + 1);
|
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++)
|
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
|
||||||
if (Info->Memory.Entry[i].Type == Usable)
|
if (Info->Memory.Entry[i].Type == Usable)
|
||||||
this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);
|
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()
|
void Power::Reboot()
|
||||||
{
|
{
|
||||||
|
BeforeShutdown();
|
||||||
|
|
||||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||||
((ACPI::DSDT *)this->dsdt)->Reboot();
|
((ACPI::DSDT *)this->dsdt)->Reboot();
|
||||||
@ -42,6 +44,8 @@ namespace Power
|
|||||||
|
|
||||||
void Power::Shutdown()
|
void Power::Shutdown()
|
||||||
{
|
{
|
||||||
|
BeforeShutdown();
|
||||||
|
|
||||||
if (((ACPI::ACPI *)this->acpi)->FADT)
|
if (((ACPI::ACPI *)this->acpi)->FADT)
|
||||||
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
if (((ACPI::DSDT *)this->dsdt)->ACPIShutdownSupported)
|
||||||
((ACPI::DSDT *)this->dsdt)->Shutdown();
|
((ACPI::DSDT *)this->dsdt)->Shutdown();
|
||||||
|
@ -5,37 +5,32 @@
|
|||||||
|
|
||||||
#ifndef STACK_CHK_GUARD_VALUE
|
#ifndef STACK_CHK_GUARD_VALUE
|
||||||
#if UINTPTR_MAX == UINT32_MAX
|
#if UINTPTR_MAX == UINT32_MAX
|
||||||
#define STACK_CHK_GUARD_VALUE 0x25F6CC8D
|
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC
|
||||||
#else
|
#else
|
||||||
#define STACK_CHK_GUARD_VALUE 0xBADFE2EC255A8572
|
#define STACK_CHK_GUARD_VALUE 0xDEAD57AC00000000
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__attribute__((weak)) uintptr_t __stack_chk_guard = 0;
|
__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;
|
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)
|
if (__stack_chk_guard == 0)
|
||||||
__stack_chk_guard = __stack_chk_guard_init();
|
__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)
|
__attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
||||||
{
|
{
|
||||||
TaskingPanic();
|
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!");
|
KPrint("\eFF0000Stack smashing detected!");
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
while (1)
|
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)
|
__attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
|
||||||
{
|
{
|
||||||
TaskingPanic();
|
TaskingPanic();
|
||||||
error("Buffer overflow detected!");
|
for (short i = 0; i < 10; i++)
|
||||||
|
error("Buffer overflow detected!");
|
||||||
KPrint("\eFF0000Buffer overflow detected!");
|
KPrint("\eFF0000Buffer overflow detected!");
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -123,7 +123,7 @@ namespace SymbolResolver
|
|||||||
|
|
||||||
Symbols::~Symbols() {}
|
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>"};
|
Symbols::SymbolTable Result{0, (char *)"<unknown>"};
|
||||||
for (size_t i = 0; i < TotalEntries; i++)
|
for (size_t i = 0; i < TotalEntries; i++)
|
||||||
|
@ -115,27 +115,41 @@ const char *Type_Check_Kinds[] = {
|
|||||||
"Cast to virtual base of",
|
"Cast to virtual base of",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prevent huge spam from ubsan
|
|
||||||
bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
|
bool UBSANMsg(const char *file, uint32_t line, uint32_t column)
|
||||||
{
|
{
|
||||||
// blacklist
|
// 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;
|
return false;
|
||||||
|
|
||||||
static char *onceFile[512] = {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"};
|
if (strstr(file, "SystemManagementBIOS.cpp") &&
|
||||||
static uint32_t onceLine[512] = {0};
|
((line == 30 && column == 21) ||
|
||||||
static uint32_t onceColumn[512] = {0};
|
(line == 27 && column == 49) ||
|
||||||
static uint32_t onceCount = 0;
|
(line == 45 && column == 26)))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < onceCount; i++)
|
if (strstr(file, "cwalk.c") &&
|
||||||
if ((!strcmp(onceFile[i], file)) && onceLine[i] == line && onceColumn[i] == column)
|
((line == 1047 && column == 15)))
|
||||||
return false;
|
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);
|
ubsan("\t\tIn File: %s:%i:%i", file, line, column);
|
||||||
onceCount++;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,28 @@
|
|||||||
|
|
||||||
#include <vector.hpp>
|
#include <vector.hpp>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <io.h>
|
|
||||||
|
|
||||||
volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
|
volatile bool serialports[8] = {false, false, false, false, false, false, false, false};
|
||||||
Vector<UniversalAsynchronousReceiverTransmitter::Events *> RegisteredEvents;
|
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
|
namespace UniversalAsynchronousReceiverTransmitter
|
||||||
{
|
{
|
||||||
#define SERIAL_ENABLE_DLAB 0x80
|
#define SERIAL_ENABLE_DLAB 0x80
|
||||||
@ -14,7 +31,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
|||||||
#define SERIAL_RATE_38400_HI 0x00
|
#define SERIAL_RATE_38400_HI 0x00
|
||||||
#define SERIAL_BUFFER_EMPTY 0x20
|
#define SERIAL_BUFFER_EMPTY 0x20
|
||||||
|
|
||||||
UART::UART(SerialPorts Port)
|
SafeFunction __no_instrument_function UART::UART(SerialPorts Port)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
if (Port == COMNULL)
|
if (Port == COMNULL)
|
||||||
@ -57,16 +74,16 @@ namespace UniversalAsynchronousReceiverTransmitter
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Initialize the serial port
|
// Initialize the serial port
|
||||||
outb(Port + 1, 0x00); // Disable all interrupts
|
NoProfiler_outportb(Port + 1, 0x00); // Disable all interrupts
|
||||||
outb(Port + 3, SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor)
|
NoProfiler_outportb(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
|
NoProfiler_outportb(Port + 0, SERIAL_RATE_38400_LO); // Set divisor to 3 (lo byte) 38400 baud
|
||||||
outb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte)
|
NoProfiler_outportb(Port + 1, SERIAL_RATE_38400_HI); // (hi byte)
|
||||||
outb(Port + 3, 0x03); // 8 bits, no parity, one stop bit
|
NoProfiler_outportb(Port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||||
outb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
NoProfiler_outportb(Port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||||
outb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
NoProfiler_outportb(Port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||||
|
|
||||||
// Check if the serial port is faulty.
|
// Check if the serial port is faulty.
|
||||||
if (inb(Port + 0) != 0xAE)
|
if (NoProfiler_inportb(Port + 0) != 0xAE)
|
||||||
{
|
{
|
||||||
static int once = 0;
|
static int once = 0;
|
||||||
if (!once++)
|
if (!once++)
|
||||||
@ -76,50 +93,50 @@ namespace UniversalAsynchronousReceiverTransmitter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set to normal operation mode.
|
// Set to normal operation mode.
|
||||||
outb(Port + 4, 0x0F);
|
NoProfiler_outportb(Port + 4, 0x0F);
|
||||||
serialports[PortNumber] = true;
|
serialports[PortNumber] = true;
|
||||||
#endif
|
#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__)
|
#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
|
#endif
|
||||||
foreach (auto e in RegisteredEvents)
|
foreach (auto e in RegisteredEvents)
|
||||||
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
||||||
e->OnSent(Char);
|
e->OnSent(Char);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t UART::Read()
|
SafeFunction __no_instrument_function uint8_t UART::Read()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#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
|
#endif
|
||||||
foreach (auto e in RegisteredEvents)
|
foreach (auto e in RegisteredEvents)
|
||||||
{
|
{
|
||||||
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
if (e->GetRegisteredPort() == Port || e->GetRegisteredPort() == COMNULL)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
e->OnReceived(inb(Port));
|
e->OnReceived(NoProfiler_inportb(Port));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Events::Events(SerialPorts Port)
|
SafeFunction __no_instrument_function Events::Events(SerialPorts Port)
|
||||||
{
|
{
|
||||||
this->Port = Port;
|
this->Port = Port;
|
||||||
RegisteredEvents.push_back(this);
|
RegisteredEvents.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Events::~Events()
|
SafeFunction __no_instrument_function Events::~Events()
|
||||||
{
|
{
|
||||||
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
for (uint64_t i = 0; i < RegisteredEvents.size(); i++)
|
||||||
if (RegisteredEvents[i] == this)
|
if (RegisteredEvents[i] == this)
|
||||||
|
@ -2,10 +2,14 @@
|
|||||||
#define __FENNIX_KERNEL_CRASH_HANDELR_H__
|
#define __FENNIX_KERNEL_CRASH_HANDELR_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
#include <interrupts.hpp>
|
||||||
#include <cpu.hpp>
|
#include <cpu.hpp>
|
||||||
|
|
||||||
namespace CrashHandler
|
namespace CrashHandler
|
||||||
{
|
{
|
||||||
|
extern void *EHIntFrames[INT_FRAMES_MAX];
|
||||||
|
|
||||||
void EHPrint(const char *Format, ...);
|
void EHPrint(const char *Format, ...);
|
||||||
void Handle(void *Data);
|
void Handle(void *Data);
|
||||||
}
|
}
|
||||||
|
25
DAPI.hpp
25
DAPI.hpp
@ -14,6 +14,7 @@ enum DriverReturnCode
|
|||||||
NOT_ACCEPTED,
|
NOT_ACCEPTED,
|
||||||
INVALID_KERNEL_API,
|
INVALID_KERNEL_API,
|
||||||
DEVICE_NOT_SUPPORTED,
|
DEVICE_NOT_SUPPORTED,
|
||||||
|
SYSTEM_NOT_SUPPORTED,
|
||||||
KERNEL_API_VERSION_NOT_SUPPORTED
|
KERNEL_API_VERSION_NOT_SUPPORTED
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,7 +23,8 @@ enum DriverBindType
|
|||||||
BIND_NULL,
|
BIND_NULL,
|
||||||
BIND_INTERRUPT,
|
BIND_INTERRUPT,
|
||||||
BIND_PROCESS,
|
BIND_PROCESS,
|
||||||
BIND_PCI
|
BIND_PCI,
|
||||||
|
BIND_INPUT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KernelAPI
|
struct KernelAPI
|
||||||
@ -80,7 +82,7 @@ struct KernelAPI
|
|||||||
void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
|
void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
|
||||||
} AHCI;
|
} AHCI;
|
||||||
} Disk;
|
} Disk;
|
||||||
} Commmand;
|
} Command;
|
||||||
|
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
@ -95,7 +97,8 @@ enum CallbackReason
|
|||||||
BindReason,
|
BindReason,
|
||||||
UnbindReason,
|
UnbindReason,
|
||||||
InterruptReason,
|
InterruptReason,
|
||||||
ProcessReason
|
ProcessReason,
|
||||||
|
InputReason,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KernelCallback
|
struct KernelCallback
|
||||||
@ -130,6 +133,22 @@ struct KernelCallback
|
|||||||
} Fetch;
|
} Fetch;
|
||||||
} DiskCallback;
|
} DiskCallback;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned long X;
|
||||||
|
unsigned long Y;
|
||||||
|
unsigned long Z;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool Left;
|
||||||
|
bool Right;
|
||||||
|
bool Middle;
|
||||||
|
} Buttons;
|
||||||
|
} Mouse;
|
||||||
|
} InputCallback;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned char Vector;
|
unsigned char Vector;
|
||||||
|
6
Fex.hpp
6
Fex.hpp
@ -87,6 +87,12 @@ struct FexExtended
|
|||||||
unsigned short SubClass;
|
unsigned short SubClass;
|
||||||
unsigned short ProgIF;
|
unsigned short ProgIF;
|
||||||
} PCI;
|
} PCI;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool AttachToMouse;
|
||||||
|
bool AttachToKeyboard;
|
||||||
|
} Input;
|
||||||
} Bind;
|
} Bind;
|
||||||
} Driver;
|
} Driver;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -19,7 +19,7 @@ namespace FileSystem
|
|||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemOpeations ustar = {
|
FileSystemOperations ustar = {
|
||||||
.Name = "ustar",
|
.Name = "ustar",
|
||||||
.Read = USTAR_Read,
|
.Read = USTAR_Read,
|
||||||
};
|
};
|
||||||
|
@ -60,7 +60,7 @@ namespace FileSystem
|
|||||||
if (strcmp(Parent->Name, Path))
|
if (strcmp(Parent->Name, Path))
|
||||||
{
|
{
|
||||||
cwk_segment segment;
|
cwk_segment segment;
|
||||||
if (!cwk_path_get_first_segment(Path, &segment))
|
if (unlikely(!cwk_path_get_first_segment(Path, &segment)))
|
||||||
{
|
{
|
||||||
error("Path doesn't have any segments.");
|
error("Path doesn't have any segments.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -104,13 +104,13 @@ namespace FileSystem
|
|||||||
vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
||||||
FileSystemNode *newNode = new FileSystemNode;
|
FileSystemNode *newNode = new FileSystemNode;
|
||||||
newNode->Parent = Parent;
|
newNode->Parent = Parent;
|
||||||
strcpy(newNode->Name, Name);
|
strncpy(newNode->Name, Name, FILENAME_LENGTH);
|
||||||
if (Parent)
|
if (likely(Parent))
|
||||||
newNode->Operator = Parent->Operator;
|
newNode->Operator = Parent->Operator;
|
||||||
else
|
else
|
||||||
newNode->Operator = nullptr;
|
newNode->Operator = nullptr;
|
||||||
|
|
||||||
if (Parent)
|
if (likely(Parent))
|
||||||
Parent->Children.push_back(newNode);
|
Parent->Children.push_back(newNode);
|
||||||
vfsdbg("AddNewChild()->\"%s\"", newNode->Name);
|
vfsdbg("AddNewChild()->\"%s\"", newNode->Name);
|
||||||
return newNode;
|
return newNode;
|
||||||
@ -119,7 +119,7 @@ namespace FileSystem
|
|||||||
FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name)
|
FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name)
|
||||||
{
|
{
|
||||||
vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
||||||
if (Parent)
|
if (likely(Parent))
|
||||||
foreach (auto var in Parent->Children)
|
foreach (auto var in Parent->Children)
|
||||||
if (strcmp(var->Name, Name) == 0)
|
if (strcmp(var->Name, Name) == 0)
|
||||||
{
|
{
|
||||||
@ -181,7 +181,7 @@ namespace FileSystem
|
|||||||
char *NormalizedPath = NormalizePath(Parent, Path);
|
char *NormalizedPath = NormalizePath(Parent, Path);
|
||||||
FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath);
|
FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath);
|
||||||
|
|
||||||
if (Node == nullptr)
|
if (!Node)
|
||||||
{
|
{
|
||||||
vfsdbg("FileExists()->NOT_FOUND");
|
vfsdbg("FileExists()->NOT_FOUND");
|
||||||
return FileStatus::NOT_FOUND;
|
return FileStatus::NOT_FOUND;
|
||||||
@ -204,7 +204,7 @@ namespace FileSystem
|
|||||||
|
|
||||||
FileSystemNode *CurrentParent = nullptr;
|
FileSystemNode *CurrentParent = nullptr;
|
||||||
|
|
||||||
if (Parent == nullptr)
|
if (!Parent)
|
||||||
{
|
{
|
||||||
if (FileSystemRoot->Children.size() >= 1)
|
if (FileSystemRoot->Children.size() >= 1)
|
||||||
{
|
{
|
||||||
@ -270,27 +270,27 @@ namespace FileSystem
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemNode *Virtual::CreateRoot(FileSystemOpeations *Operator, const char *RootName)
|
FileSystemNode *Virtual::CreateRoot(FileSystemOperations *Operator, const char *RootName)
|
||||||
{
|
{
|
||||||
if (Operator == nullptr)
|
if (Operator == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
vfsdbg("Setting root to %s", RootName);
|
vfsdbg("Setting root to %s", RootName);
|
||||||
FileSystemNode *newNode = new FileSystemNode;
|
FileSystemNode *newNode = new FileSystemNode;
|
||||||
strcpy(newNode->Name, RootName);
|
strncpy(newNode->Name, RootName, FILENAME_LENGTH);
|
||||||
newNode->Flags = NodeFlags::FS_DIRECTORY;
|
newNode->Flags = NodeFlags::FS_DIRECTORY;
|
||||||
newNode->Operator = Operator;
|
newNode->Operator = Operator;
|
||||||
FileSystemRoot->Children.push_back(newNode);
|
FileSystemRoot->Children.push_back(newNode);
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *Virtual::Mount(FileSystemOpeations *Operator, const char *Path)
|
FILE *Virtual::Mount(FileSystemOperations *Operator, const char *Path)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
|
|
||||||
if (Operator == nullptr)
|
if (unlikely(!Operator))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (isempty((char *)Path))
|
if (unlikely(isempty((char *)Path)))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
vfsdbg("Mounting %s", Path);
|
vfsdbg("Mounting %s", Path);
|
||||||
@ -306,7 +306,7 @@ namespace FileSystem
|
|||||||
FileStatus Virtual::Unmount(FILE *File)
|
FileStatus Virtual::Unmount(FILE *File)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (File == nullptr)
|
if (unlikely(File))
|
||||||
return FileStatus::INVALID_PARAMETER;
|
return FileStatus::INVALID_PARAMETER;
|
||||||
vfsdbg("Unmounting %s", File->Name);
|
vfsdbg("Unmounting %s", File->Name);
|
||||||
return FileStatus::OK;
|
return FileStatus::OK;
|
||||||
@ -322,7 +322,7 @@ namespace FileSystem
|
|||||||
FILE *file = new FILE;
|
FILE *file = new FILE;
|
||||||
FileStatus filestatus = FileStatus::OK;
|
FileStatus filestatus = FileStatus::OK;
|
||||||
file->Node = Parent;
|
file->Node = Parent;
|
||||||
if (file->Node == nullptr)
|
if (unlikely(!file->Node))
|
||||||
file->Status = FileStatus::NOT_FOUND;
|
file->Status = FileStatus::NOT_FOUND;
|
||||||
const char *basename;
|
const char *basename;
|
||||||
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
||||||
@ -338,7 +338,7 @@ namespace FileSystem
|
|||||||
FILE *file = new FILE;
|
FILE *file = new FILE;
|
||||||
FileStatus filestatus = FileStatus::OK;
|
FileStatus filestatus = FileStatus::OK;
|
||||||
file->Node = Parent;
|
file->Node = Parent;
|
||||||
if (file->Node == nullptr)
|
if (!file->Node)
|
||||||
file->Status = FileStatus::NOT_FOUND;
|
file->Status = FileStatus::NOT_FOUND;
|
||||||
const char *basename;
|
const char *basename;
|
||||||
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
||||||
@ -388,7 +388,7 @@ namespace FileSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath);
|
file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath);
|
||||||
if (file->Node != nullptr)
|
if (file->Node)
|
||||||
{
|
{
|
||||||
const char *basename;
|
const char *basename;
|
||||||
cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr);
|
||||||
@ -403,7 +403,7 @@ namespace FileSystem
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
file->Node = GetNodeFromPath(Parent, CleanPath);
|
file->Node = GetNodeFromPath(Parent, CleanPath);
|
||||||
if (file->Node == nullptr)
|
if (unlikely(!file->Node))
|
||||||
file->Status = FileStatus::NOT_FOUND;
|
file->Status = FileStatus::NOT_FOUND;
|
||||||
const char *basename;
|
const char *basename;
|
||||||
cwk_path_get_basename(CleanPath, &basename, nullptr);
|
cwk_path_get_basename(CleanPath, &basename, nullptr);
|
||||||
@ -417,18 +417,18 @@ namespace FileSystem
|
|||||||
uint64_t Virtual::Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
uint64_t Virtual::Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (File == nullptr)
|
if (unlikely(!File))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
File->Status = FileStatus::OK;
|
File->Status = FileStatus::OK;
|
||||||
|
|
||||||
if (File->Node == nullptr)
|
if (unlikely(!File->Node))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::INVALID_PARAMETER;
|
File->Status = FileStatus::INVALID_PARAMETER;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File->Node->Operator == nullptr)
|
if (unlikely(!File->Node->Operator))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::INVALID_PARAMETER;
|
File->Status = FileStatus::INVALID_PARAMETER;
|
||||||
return 0;
|
return 0;
|
||||||
@ -440,18 +440,18 @@ namespace FileSystem
|
|||||||
uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (File == nullptr)
|
if (unlikely(!File))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
File->Status = FileStatus::OK;
|
File->Status = FileStatus::OK;
|
||||||
|
|
||||||
if (File->Node == nullptr)
|
if (unlikely(!File->Node))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::INVALID_PARAMETER;
|
File->Status = FileStatus::INVALID_PARAMETER;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File->Node->Operator == nullptr)
|
if (unlikely(!File->Node->Operator))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::INVALID_PARAMETER;
|
File->Status = FileStatus::INVALID_PARAMETER;
|
||||||
return 0;
|
return 0;
|
||||||
@ -463,7 +463,7 @@ namespace FileSystem
|
|||||||
FileStatus Virtual::Close(FILE *File)
|
FileStatus Virtual::Close(FILE *File)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (File == nullptr)
|
if (unlikely(!File))
|
||||||
return FileStatus::INVALID_HANDLE;
|
return FileStatus::INVALID_HANDLE;
|
||||||
vfsdbg("Closing %s", File->Name);
|
vfsdbg("Closing %s", File->Name);
|
||||||
delete File;
|
delete File;
|
||||||
@ -477,12 +477,12 @@ namespace FileSystem
|
|||||||
FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT;
|
FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT;
|
||||||
FileSystemRoot->Operator = nullptr;
|
FileSystemRoot->Operator = nullptr;
|
||||||
FileSystemRoot->Parent = nullptr;
|
FileSystemRoot->Parent = nullptr;
|
||||||
strcpy(FileSystemRoot->Name, "root");
|
strncpy(FileSystemRoot->Name, "root", 4);
|
||||||
cwk_path_set_style(CWK_STYLE_UNIX);
|
cwk_path_set_style(CWK_STYLE_UNIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
Virtual::~Virtual()
|
Virtual::~Virtual()
|
||||||
{
|
{
|
||||||
warn("Tried to uninitialize Virtual File System!");
|
warn("Tried to deinitialize Virtual File System!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
KConfig.cpp
22
KConfig.cpp
@ -49,11 +49,17 @@ static struct cag_option ConfigOptions[] = {
|
|||||||
.value_name = "PATH",
|
.value_name = "PATH",
|
||||||
.description = "Path to init program"},
|
.description = "Path to init program"},
|
||||||
|
|
||||||
|
{.identifier = 'l',
|
||||||
|
.access_letters = NULL,
|
||||||
|
.access_name = "udl",
|
||||||
|
.value_name = "BOOL",
|
||||||
|
.description = "Unlock the deadlock after 10 retries"},
|
||||||
|
|
||||||
{.identifier = 'o',
|
{.identifier = 'o',
|
||||||
.access_letters = NULL,
|
.access_letters = NULL,
|
||||||
.access_name = "ioc",
|
.access_name = "ioc",
|
||||||
.value_name = "BOOL",
|
.value_name = "BOOL",
|
||||||
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash."},
|
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash"},
|
||||||
|
|
||||||
{.identifier = 'h',
|
{.identifier = 'h',
|
||||||
.access_letters = "h",
|
.access_letters = "h",
|
||||||
@ -71,7 +77,8 @@ KernelConfig ParseConfig(char *Config)
|
|||||||
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
|
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'd', 'r', 'i', 'v', 'e', 'r', 's', '\0'},
|
||||||
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
|
{'/', 's', 'y', 's', 't', 'e', 'm', '/', 'i', 'n', 'i', 't', '\0'},
|
||||||
false,
|
false,
|
||||||
0};
|
0,
|
||||||
|
false};
|
||||||
|
|
||||||
if (Config == NULL)
|
if (Config == NULL)
|
||||||
{
|
{
|
||||||
@ -331,14 +338,14 @@ ParseSuccess:
|
|||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
value = cag_option_get_value(&context);
|
value = cag_option_get_value(&context);
|
||||||
strcpy(config.DriverDirectory, value);
|
strncpy(config.DriverDirectory, value, strlen(value));
|
||||||
KPrint("\eAAFFAAUsing %s as driver directory", value);
|
KPrint("\eAAFFAAUsing %s as driver directory", value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
value = cag_option_get_value(&context);
|
value = cag_option_get_value(&context);
|
||||||
strcpy(config.InitPath, value);
|
strncpy(config.InitPath, value, strlen(value));
|
||||||
KPrint("\eAAFFAAUsing %s as init program", value);
|
KPrint("\eAAFFAAUsing %s as init program", value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -349,6 +356,13 @@ ParseSuccess:
|
|||||||
KPrint("\eAAFFAAInterrupts on crash: %s", value);
|
KPrint("\eAAFFAAInterrupts on crash: %s", value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'l':
|
||||||
|
{
|
||||||
|
value = cag_option_get_value(&context);
|
||||||
|
strcmp(value, "true") ? config.UnlockDeadLock = false : config.UnlockDeadLock = true;
|
||||||
|
KPrint("\eAAFFAAUnlocking the deadlock after 10 retires");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'h':
|
case 'h':
|
||||||
{
|
{
|
||||||
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");
|
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");
|
||||||
|
64
KThread.cpp
64
KThread.cpp
@ -14,65 +14,33 @@
|
|||||||
Driver::Driver *DriverManager = nullptr;
|
Driver::Driver *DriverManager = nullptr;
|
||||||
Disk::Manager *DiskManager = nullptr;
|
Disk::Manager *DiskManager = nullptr;
|
||||||
|
|
||||||
void StartFilesystem()
|
|
||||||
{
|
|
||||||
KPrint("Initializing Filesystem...");
|
|
||||||
vfs = new FileSystem::Virtual;
|
|
||||||
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
|
||||||
KPrint("Initializing Disk Manager...");
|
|
||||||
DiskManager = new Disk::Manager;
|
|
||||||
/* ... */
|
|
||||||
TEXIT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadDrivers()
|
|
||||||
{
|
|
||||||
KPrint("Loading Drivers...");
|
|
||||||
DriverManager = new Driver::Driver;
|
|
||||||
TEXIT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FetchDisks()
|
|
||||||
{
|
|
||||||
KPrint("Fetching Disks...");
|
|
||||||
foreach (auto Driver in DriverManager->GetDrivers())
|
|
||||||
{
|
|
||||||
FexExtended *DrvExtHdr = (FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS);
|
|
||||||
|
|
||||||
if (DrvExtHdr->Driver.Type == FexDriverType::FexDriverType_Storage)
|
|
||||||
DiskManager->FetchDisks(Driver->DriverUID);
|
|
||||||
}
|
|
||||||
TEXIT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KernelMainThread()
|
void KernelMainThread()
|
||||||
{
|
{
|
||||||
TaskManager->InitIPC();
|
TaskManager->InitIPC();
|
||||||
|
TaskManager->GetCurrentThread()->SetPriority(100);
|
||||||
Vector<AuxiliaryVector> auxv;
|
Vector<AuxiliaryVector> auxv;
|
||||||
|
|
||||||
Tasking::TCB *CurrentWorker = nullptr;
|
Tasking::TCB *CurrentWorker = nullptr;
|
||||||
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
|
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
|
||||||
KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus);
|
KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus);
|
||||||
TaskManager->GetCurrentThread()->SetPriority(1);
|
|
||||||
|
|
||||||
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv);
|
KPrint("Initializing Filesystem...");
|
||||||
CurrentWorker->Rename("Filesystems");
|
vfs = new FileSystem::Virtual;
|
||||||
CurrentWorker->SetPriority(100);
|
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
||||||
TaskManager->WaitForThread(CurrentWorker);
|
KPrint("Initializing Disk Manager...");
|
||||||
|
DiskManager = new Disk::Manager;
|
||||||
|
|
||||||
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)LoadDrivers, nullptr, nullptr, auxv);
|
KPrint("Loading Drivers...");
|
||||||
CurrentWorker->Rename("Drivers");
|
DriverManager = new Driver::Driver;
|
||||||
CurrentWorker->SetPriority(100);
|
|
||||||
TaskManager->WaitForThread(CurrentWorker);
|
|
||||||
|
|
||||||
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv);
|
KPrint("Fetching Disks...");
|
||||||
CurrentWorker->Rename("Disks");
|
foreach (auto Driver in DriverManager->GetDrivers())
|
||||||
CurrentWorker->SetPriority(100);
|
if (((FexExtended *)((uint64_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Storage)
|
||||||
TaskManager->WaitForThread(CurrentWorker);
|
DiskManager->FetchDisks(Driver->DriverUID);
|
||||||
|
|
||||||
KPrint("Setting up userspace...");
|
KPrint("Setting up userspace...");
|
||||||
|
|
||||||
const char *envp[] = {
|
const char *envp[9] = {
|
||||||
"PATH=/system:/system/bin",
|
"PATH=/system:/system/bin",
|
||||||
"TERM=tty",
|
"TERM=tty",
|
||||||
"HOME=/",
|
"HOME=/",
|
||||||
@ -83,12 +51,11 @@ void KernelMainThread()
|
|||||||
"TZ=UTC",
|
"TZ=UTC",
|
||||||
nullptr};
|
nullptr};
|
||||||
|
|
||||||
const char *argv[] = {
|
const char *argv[3] = {
|
||||||
"--init",
|
"--init",
|
||||||
"--critical",
|
"--critical",
|
||||||
nullptr};
|
nullptr};
|
||||||
|
|
||||||
// TODO: Untested!
|
|
||||||
bool ien = CPU::Interrupts(CPU::Check);
|
bool ien = CPU::Interrupts(CPU::Check);
|
||||||
CPU::Interrupts(CPU::Disable);
|
CPU::Interrupts(CPU::Disable);
|
||||||
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp);
|
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp);
|
||||||
@ -100,9 +67,12 @@ void KernelMainThread()
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
ret.Thread->SetCritical(true);
|
ret.Thread->SetCritical(true);
|
||||||
|
debug("%s interrupts", ien ? "Enabling" : "Disabling");
|
||||||
if (ien)
|
if (ien)
|
||||||
CPU::Interrupts(CPU::Enable);
|
CPU::Interrupts(CPU::Enable);
|
||||||
|
debug("After interrupts boolean");
|
||||||
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
|
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
|
||||||
|
TaskManager->GetCurrentThread()->SetPriority(1);
|
||||||
TaskManager->WaitForThread(ret.Thread);
|
TaskManager->WaitForThread(ret.Thread);
|
||||||
KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode());
|
KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode());
|
||||||
error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode());
|
error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode());
|
||||||
|
34
Kernel.cpp
34
Kernel.cpp
@ -27,6 +27,8 @@ FileSystem::Virtual *vfs = nullptr;
|
|||||||
KernelConfig Config;
|
KernelConfig Config;
|
||||||
Time::Clock BootClock;
|
Time::Clock BootClock;
|
||||||
|
|
||||||
|
extern bool EnableProfiler;
|
||||||
|
|
||||||
// For the Display class. Printing on first buffer as default.
|
// For the Display class. Printing on first buffer as default.
|
||||||
EXTERNC void putchar(char c) { Display->Print(c, 0); }
|
EXTERNC void putchar(char c) { Display->Print(c, 0); }
|
||||||
|
|
||||||
@ -43,10 +45,8 @@ EXTERNC void KPrint(const char *Format, ...)
|
|||||||
Display->SetBuffer(0);
|
Display->SetBuffer(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERNC void Entry(BootInfo *Info)
|
EXTERNC __no_instrument_function void PostEntry(BootInfo *Info)
|
||||||
{
|
{
|
||||||
trace("Hello, World!");
|
|
||||||
InitializeMemoryManagement(Info);
|
|
||||||
BootClock = Time::ReadClock();
|
BootClock = Time::ReadClock();
|
||||||
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo)));
|
||||||
memcpy(bInfo, Info, sizeof(BootInfo));
|
memcpy(bInfo, Info, sizeof(BootInfo));
|
||||||
@ -167,6 +167,34 @@ EXTERNC void Entry(BootInfo *Info)
|
|||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXTERNC void __guard_setup(void);
|
||||||
|
|
||||||
|
typedef void (*CallPtr)(void);
|
||||||
|
extern CallPtr __init_array_start[0], __init_array_end[0];
|
||||||
|
extern CallPtr __fini_array_start[0], __fini_array_end[0];
|
||||||
|
|
||||||
|
EXTERNC __no_stack_protector __no_instrument_function void Entry(BootInfo *Info)
|
||||||
|
{
|
||||||
|
trace("Hello, World!");
|
||||||
|
|
||||||
|
// https://wiki.osdev.org/Calling_Global_Constructors
|
||||||
|
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
||||||
|
(*func)();
|
||||||
|
|
||||||
|
InitializeMemoryManagement(Info);
|
||||||
|
EnableProfiler = true;
|
||||||
|
PostEntry(Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC __no_stack_protector __no_instrument_function void BeforeShutdown()
|
||||||
|
{
|
||||||
|
// https://wiki.osdev.org/Calling_Global_Constructors
|
||||||
|
debug("Calling destructors...");
|
||||||
|
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
||||||
|
(*func)();
|
||||||
|
debug("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
EXTERNC void TaskingPanic()
|
EXTERNC void TaskingPanic()
|
||||||
{
|
{
|
||||||
if (TaskManager)
|
if (TaskManager)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <convert.h>
|
#include <convert.h>
|
||||||
#include <types.h>
|
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
// TODO: Replace mem* with assembly code
|
// TODO: Replace mem* with assembly code
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, size_t n)
|
void *memcpy_unsafe(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char *d = dest;
|
unsigned char *d = dest;
|
||||||
const unsigned char *s = src;
|
const unsigned char *s = src;
|
||||||
@ -193,7 +194,7 @@ void *memcpy(void *dest, const void *src, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *dest, int c, size_t n)
|
void *memset_unsafe(void *dest, int c, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char *s = dest;
|
unsigned char *s = dest;
|
||||||
size_t k;
|
size_t k;
|
||||||
@ -264,7 +265,7 @@ void *memset(void *dest, int c, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t n)
|
void *memmove_unsafe(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
typedef __attribute__((__may_alias__)) size_t WT;
|
typedef __attribute__((__may_alias__)) size_t WT;
|
||||||
@ -362,9 +363,9 @@ long unsigned strlen(const char s[])
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcat(char *destination, const char *source)
|
char *strcat_unsafe(char *destination, const char *source)
|
||||||
{
|
{
|
||||||
if ((destination == NULL) && (source == NULL))
|
if ((destination == NULL) || (source == NULL))
|
||||||
return NULL;
|
return NULL;
|
||||||
char *start = destination;
|
char *start = destination;
|
||||||
while (*start != '\0')
|
while (*start != '\0')
|
||||||
@ -379,7 +380,7 @@ char *strcat(char *destination, const char *source)
|
|||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcpy(char *destination, const char *source)
|
char *strcpy_unsafe(char *destination, const char *source)
|
||||||
{
|
{
|
||||||
if (destination == NULL)
|
if (destination == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -446,7 +447,7 @@ char *strchr(const char *String, int Char)
|
|||||||
char *strdup(const char *String)
|
char *strdup(const char *String)
|
||||||
{
|
{
|
||||||
char *OutBuffer = kmalloc(strlen((char *)String) + 1);
|
char *OutBuffer = kmalloc(strlen((char *)String) + 1);
|
||||||
strcpy(OutBuffer, String);
|
strncpy(OutBuffer, String, strlen(String) + 1);
|
||||||
return OutBuffer;
|
return OutBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,3 +612,232 @@ char *itoa(int Value, char *Buffer, int Base)
|
|||||||
Buffer[i] = '\0';
|
Buffer[i] = '\0';
|
||||||
return reverse(Buffer, 0, i - 1);
|
return reverse(Buffer, 0, i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ltoa(long Value, char *Buffer, int Base)
|
||||||
|
{
|
||||||
|
if (Base < 2 || Base > 32)
|
||||||
|
return Buffer;
|
||||||
|
|
||||||
|
long n = abs(Value);
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
int r = n % Base;
|
||||||
|
if (r >= 10)
|
||||||
|
Buffer[i++] = 65 + (r - 10);
|
||||||
|
else
|
||||||
|
Buffer[i++] = 48 + r;
|
||||||
|
n = n / Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
Buffer[i++] = '0';
|
||||||
|
|
||||||
|
if (Value < 0 && Base == 10)
|
||||||
|
Buffer[i++] = '-';
|
||||||
|
|
||||||
|
Buffer[i] = '\0';
|
||||||
|
return reverse(Buffer, 0, i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ultoa(unsigned long Value, char *Buffer, int Base)
|
||||||
|
{
|
||||||
|
if (Base < 2 || Base > 32)
|
||||||
|
return Buffer;
|
||||||
|
|
||||||
|
unsigned long n = Value;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
int r = n % Base;
|
||||||
|
if (r >= 10)
|
||||||
|
Buffer[i++] = 65 + (r - 10);
|
||||||
|
else
|
||||||
|
Buffer[i++] = 48 + r;
|
||||||
|
n = n / Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
Buffer[i++] = '0';
|
||||||
|
|
||||||
|
Buffer[i] = '\0';
|
||||||
|
return reverse(Buffer, 0, i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void __chk_fail(void) __attribute__((__noreturn__));
|
||||||
|
|
||||||
|
// #define DBG_CHK 1
|
||||||
|
|
||||||
|
__no_stack_protector void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen)
|
||||||
|
{
|
||||||
|
#ifdef DBG_CHK
|
||||||
|
debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen);
|
||||||
|
#endif
|
||||||
|
if (unlikely(dest == NULL))
|
||||||
|
{
|
||||||
|
error("dest is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(src == NULL))
|
||||||
|
{
|
||||||
|
error("src is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len == 0))
|
||||||
|
{
|
||||||
|
error("len is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(slen == 0))
|
||||||
|
{
|
||||||
|
error("slen is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len > slen))
|
||||||
|
__chk_fail();
|
||||||
|
return memcpy_unsafe(dest, src, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_stack_protector void *__memset_chk(void *dest, int val, size_t len, size_t slen)
|
||||||
|
{
|
||||||
|
#ifdef DBG_CHK
|
||||||
|
debug("( dest:%#lx val:%#x len:%llu slen:%llu )", dest, val, len, slen);
|
||||||
|
#endif
|
||||||
|
if (unlikely(dest == NULL))
|
||||||
|
{
|
||||||
|
error("dest is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len == 0))
|
||||||
|
{
|
||||||
|
error("len is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(slen == 0))
|
||||||
|
{
|
||||||
|
error("slen is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len > slen))
|
||||||
|
__chk_fail();
|
||||||
|
return memset_unsafe(dest, val, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_stack_protector void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen)
|
||||||
|
{
|
||||||
|
#ifdef DBG_CHK
|
||||||
|
debug("( dest:%#lx src:%#lx len:%llu slen:%llu )", dest, src, len, slen);
|
||||||
|
#endif
|
||||||
|
if (unlikely(dest == NULL))
|
||||||
|
{
|
||||||
|
error("dest is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(src == NULL))
|
||||||
|
{
|
||||||
|
error("src is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len == 0))
|
||||||
|
{
|
||||||
|
error("len is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(slen == 0))
|
||||||
|
{
|
||||||
|
error("slen is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(len > slen))
|
||||||
|
__chk_fail();
|
||||||
|
return memmove_unsafe(dest, src, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_stack_protector char *__strcat_chk(char *dest, const char *src, size_t slen)
|
||||||
|
{
|
||||||
|
#ifdef DBG_CHK
|
||||||
|
debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen);
|
||||||
|
#endif
|
||||||
|
if (unlikely(dest == NULL))
|
||||||
|
{
|
||||||
|
error("dest is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(src == NULL))
|
||||||
|
{
|
||||||
|
error("src is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(slen == 0))
|
||||||
|
{
|
||||||
|
error("slen is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t dest_len = strlen(dest);
|
||||||
|
if (unlikely(dest_len + strlen(src) + 1 > slen))
|
||||||
|
__chk_fail();
|
||||||
|
return strcat_unsafe(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_stack_protector char *__strcpy_chk(char *dest, const char *src, size_t slen)
|
||||||
|
{
|
||||||
|
#ifdef DBG_CHK
|
||||||
|
debug("( dest:%#lx src:%#lx slen:%llu )", dest, src, slen);
|
||||||
|
#endif
|
||||||
|
if (unlikely(dest == NULL))
|
||||||
|
{
|
||||||
|
error("dest is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(src == NULL))
|
||||||
|
{
|
||||||
|
error("src is NULL");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(slen == 0))
|
||||||
|
{
|
||||||
|
error("slen is 0");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = strlen(src);
|
||||||
|
|
||||||
|
if (unlikely(len >= slen))
|
||||||
|
__chk_fail();
|
||||||
|
return strcpy_unsafe(dest, src);
|
||||||
|
}
|
||||||
|
@ -208,6 +208,8 @@ uint8_t *md5String(char *input)
|
|||||||
md5Finalize(&ctx);
|
md5Finalize(&ctx);
|
||||||
|
|
||||||
uint8_t *result = kmalloc(16);
|
uint8_t *result = kmalloc(16);
|
||||||
|
if (result == NULL)
|
||||||
|
return (uint8_t *)"error";
|
||||||
memcpy(result, ctx.digest, 16);
|
memcpy(result, ctx.digest, 16);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -236,6 +238,8 @@ uint8_t *md5File(uint8_t *buffer, size_t input_len)
|
|||||||
md5Finalize(&ctx);
|
md5Finalize(&ctx);
|
||||||
|
|
||||||
uint8_t *result = kmalloc(16);
|
uint8_t *result = kmalloc(16);
|
||||||
|
if (result == NULL)
|
||||||
|
return (uint8_t *)"error";
|
||||||
memcpy(result, ctx.digest, 16);
|
memcpy(result, ctx.digest, 16);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -266,14 +266,14 @@ typedef union
|
|||||||
// 1. Some compilers are finicky about this;
|
// 1. Some compilers are finicky about this;
|
||||||
// 2. Some people may want to convert this to C89;
|
// 2. Some people may want to convert this to C89;
|
||||||
// 3. If you try to use it as C++, only C++20 supports compound literals
|
// 3. If you try to use it as C++, only C++20 supports compound literals
|
||||||
static inline double_with_bit_access get_bit_access(double x)
|
static inline __no_instrument_function double_with_bit_access get_bit_access(double x)
|
||||||
{
|
{
|
||||||
double_with_bit_access dwba;
|
double_with_bit_access dwba;
|
||||||
dwba.F = x;
|
dwba.F = x;
|
||||||
return dwba;
|
return dwba;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int get_sign_bit(double x)
|
static inline __no_instrument_function int get_sign_bit(double x)
|
||||||
{
|
{
|
||||||
// The sign is stored in the highest bit
|
// The sign is stored in the highest bit
|
||||||
return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
|
return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1));
|
||||||
@ -317,7 +317,7 @@ typedef struct
|
|||||||
// or alternatively, that '\0' can be passed to the function in the output
|
// or alternatively, that '\0' can be passed to the function in the output
|
||||||
// gadget. The former assumption holds within the printf library. It also
|
// gadget. The former assumption holds within the printf library. It also
|
||||||
// assumes that the output gadget has been properly initialized.
|
// assumes that the output gadget has been properly initialized.
|
||||||
static inline void putchar_via_gadget(output_gadget_t *gadget, char c)
|
static inline __no_instrument_function void putchar_via_gadget(output_gadget_t *gadget, char c)
|
||||||
{
|
{
|
||||||
printf_size_t write_pos = gadget->pos++;
|
printf_size_t write_pos = gadget->pos++;
|
||||||
// We're _always_ increasing pos, so as to count how may characters
|
// We're _always_ increasing pos, so as to count how may characters
|
||||||
@ -340,7 +340,7 @@ static inline void putchar_via_gadget(output_gadget_t *gadget, char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Possibly-write the string-terminating '\0' character
|
// Possibly-write the string-terminating '\0' character
|
||||||
static inline void append_termination_with_gadget(output_gadget_t *gadget)
|
static inline __no_instrument_function void append_termination_with_gadget(output_gadget_t *gadget)
|
||||||
{
|
{
|
||||||
if (gadget->function != NULL || gadget->max_chars == 0)
|
if (gadget->function != NULL || gadget->max_chars == 0)
|
||||||
{
|
{
|
||||||
@ -356,13 +356,13 @@ static inline void append_termination_with_gadget(output_gadget_t *gadget)
|
|||||||
|
|
||||||
// We can't use putchar_ as is, since our output gadget
|
// We can't use putchar_ as is, since our output gadget
|
||||||
// only takes pointers to functions with an extra argument
|
// only takes pointers to functions with an extra argument
|
||||||
static inline void putchar_wrapper(char c, void *unused)
|
static inline __no_instrument_function void putchar_wrapper(char c, void *unused)
|
||||||
{
|
{
|
||||||
(void)unused;
|
(void)unused;
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline output_gadget_t discarding_gadget(void)
|
static inline __no_instrument_function output_gadget_t discarding_gadget(void)
|
||||||
{
|
{
|
||||||
output_gadget_t gadget;
|
output_gadget_t gadget;
|
||||||
gadget.function = NULL;
|
gadget.function = NULL;
|
||||||
@ -373,7 +373,7 @@ static inline output_gadget_t discarding_gadget(void)
|
|||||||
return gadget;
|
return gadget;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
|
static inline __no_instrument_function output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t)buffer_size;
|
printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t)buffer_size;
|
||||||
output_gadget_t result = discarding_gadget();
|
output_gadget_t result = discarding_gadget();
|
||||||
@ -385,7 +385,7 @@ static inline output_gadget_t buffer_gadget(char *buffer, size_t buffer_size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg)
|
static inline __no_instrument_function output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg)
|
||||||
{
|
{
|
||||||
output_gadget_t result = discarding_gadget();
|
output_gadget_t result = discarding_gadget();
|
||||||
result.function = function;
|
result.function = function;
|
||||||
@ -394,7 +394,7 @@ static inline output_gadget_t function_gadget(void (*function)(char, void *), vo
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline output_gadget_t extern_putchar_gadget(void)
|
static inline __no_instrument_function output_gadget_t extern_putchar_gadget(void)
|
||||||
{
|
{
|
||||||
return function_gadget(putchar_wrapper, NULL);
|
return function_gadget(putchar_wrapper, NULL);
|
||||||
}
|
}
|
||||||
@ -403,7 +403,7 @@ static inline output_gadget_t extern_putchar_gadget(void)
|
|||||||
// @return The length of the string (excluding the terminating 0) limited by 'maxsize'
|
// @return The length of the string (excluding the terminating 0) limited by 'maxsize'
|
||||||
// @note strlen uses size_t, but wes only use this function with printf_size_t
|
// @note strlen uses size_t, but wes only use this function with printf_size_t
|
||||||
// variables - hence the signature.
|
// variables - hence the signature.
|
||||||
static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
|
static inline __no_instrument_function printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
for (s = str; *s && maxsize--; ++s)
|
for (s = str; *s && maxsize--; ++s)
|
||||||
@ -413,13 +413,13 @@ static inline printf_size_t strnlen_s_(const char *str, printf_size_t maxsize)
|
|||||||
|
|
||||||
// internal test if char is a digit (0-9)
|
// internal test if char is a digit (0-9)
|
||||||
// @return true if char is a digit
|
// @return true if char is a digit
|
||||||
static inline bool is_digit_(char ch)
|
static inline __no_instrument_function bool is_digit_(char ch)
|
||||||
{
|
{
|
||||||
return (ch >= '0') && (ch <= '9');
|
return (ch >= '0') && (ch <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal ASCII string to printf_size_t conversion
|
// internal ASCII string to printf_size_t conversion
|
||||||
static printf_size_t atou_(const char **str)
|
static __no_instrument_function printf_size_t atou_(const char **str)
|
||||||
{
|
{
|
||||||
printf_size_t i = 0U;
|
printf_size_t i = 0U;
|
||||||
while (is_digit_(**str))
|
while (is_digit_(**str))
|
||||||
@ -430,7 +430,7 @@ static printf_size_t atou_(const char **str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// output the specified string in reverse, taking care of any zero-padding
|
// output the specified string in reverse, taking care of any zero-padding
|
||||||
static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
|
static __no_instrument_function void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags)
|
||||||
{
|
{
|
||||||
const printf_size_t start_pos = output->pos;
|
const printf_size_t start_pos = output->pos;
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ static void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len
|
|||||||
|
|
||||||
// Invoked by print_integer after the actual number has been printed, performing necessary
|
// Invoked by print_integer after the actual number has been printed, performing necessary
|
||||||
// work on the number's prefix (as the number is initially printed in reverse order)
|
// work on the number's prefix (as the number is initially printed in reverse order)
|
||||||
static void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
|
static __no_instrument_function void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
|
||||||
{
|
{
|
||||||
printf_size_t unpadded_len = len;
|
printf_size_t unpadded_len = len;
|
||||||
|
|
||||||
@ -545,7 +545,7 @@ static void print_integer_finalization(output_gadget_t *output, char *buf, print
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An internal itoa-like function
|
// An internal itoa-like function
|
||||||
static void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
|
static __no_instrument_function void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags)
|
||||||
{
|
{
|
||||||
char buf[PRINTF_INTEGER_BUFFER_SIZE];
|
char buf[PRINTF_INTEGER_BUFFER_SIZE];
|
||||||
printf_size_t len = 0U;
|
printf_size_t len = 0U;
|
||||||
@ -604,7 +604,7 @@ static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = {
|
|||||||
// Break up a double number - which is known to be a finite non-negative number -
|
// Break up a double number - which is known to be a finite non-negative number -
|
||||||
// into its base-10 parts: integral - before the decimal point, and fractional - after it.
|
// into its base-10 parts: integral - before the decimal point, and fractional - after it.
|
||||||
// Taken the precision into account, but does not change it even internally.
|
// Taken the precision into account, but does not change it even internally.
|
||||||
static struct double_components get_components(double number, printf_size_t precision)
|
static struct __no_instrument_function double_components get_components(double number, printf_size_t precision)
|
||||||
{
|
{
|
||||||
struct double_components number_;
|
struct double_components number_;
|
||||||
number_.is_negative = get_sign_bit(number);
|
number_.is_negative = get_sign_bit(number);
|
||||||
@ -741,7 +741,7 @@ static struct double_components get_normalized_components(bool negative, printf_
|
|||||||
}
|
}
|
||||||
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
|
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
|
||||||
|
|
||||||
static void print_broken_up_decimal(
|
static __no_instrument_function void print_broken_up_decimal(
|
||||||
struct double_components number_, output_gadget_t *output, printf_size_t precision,
|
struct double_components number_, output_gadget_t *output, printf_size_t precision,
|
||||||
printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
||||||
{
|
{
|
||||||
@ -843,7 +843,7 @@ static void print_broken_up_decimal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal ftoa for fixed decimal floating point
|
// internal ftoa for fixed decimal floating point
|
||||||
static void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
static __no_instrument_function void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
||||||
{
|
{
|
||||||
struct double_components value_ = get_components(number, precision);
|
struct double_components value_ = get_components(number, precision);
|
||||||
print_broken_up_decimal(value_, output, precision, width, flags, buf, len);
|
print_broken_up_decimal(value_, output, precision, width, flags, buf, len);
|
||||||
@ -916,7 +916,7 @@ static double pow10_of_int(int floored_exp10)
|
|||||||
return dwba.F;
|
return dwba.F;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
static __no_instrument_function void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len)
|
||||||
{
|
{
|
||||||
const bool negative = get_sign_bit(number);
|
const bool negative = get_sign_bit(number);
|
||||||
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
|
// This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it
|
||||||
@ -1039,7 +1039,7 @@ static void print_exponential_number(output_gadget_t *output, double number, pri
|
|||||||
}
|
}
|
||||||
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
|
#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS
|
||||||
|
|
||||||
static void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential)
|
static __no_instrument_function void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential)
|
||||||
{
|
{
|
||||||
char buf[PRINTF_DECIMAL_BUFFER_SIZE];
|
char buf[PRINTF_DECIMAL_BUFFER_SIZE];
|
||||||
printf_size_t len = 0U;
|
printf_size_t len = 0U;
|
||||||
@ -1098,7 +1098,7 @@ static void print_floating_point(output_gadget_t *output, double value, printf_s
|
|||||||
|
|
||||||
// Advances the format pointer past the flags, and returns the parsed flags
|
// Advances the format pointer past the flags, and returns the parsed flags
|
||||||
// due to the characters passed
|
// due to the characters passed
|
||||||
static printf_flags_t parse_flags(const char **format)
|
static __no_instrument_function printf_flags_t parse_flags(const char **format)
|
||||||
{
|
{
|
||||||
printf_flags_t flags = 0U;
|
printf_flags_t flags = 0U;
|
||||||
do
|
do
|
||||||
@ -1131,7 +1131,7 @@ static printf_flags_t parse_flags(const char **format)
|
|||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void format_string_loop(output_gadget_t *output, const char *format, va_list args)
|
static inline __no_instrument_function void format_string_loop(output_gadget_t *output, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
#if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
|
#if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER
|
||||||
#define ADVANCE_IN_FORMAT_STRING(cptr_) \
|
#define ADVANCE_IN_FORMAT_STRING(cptr_) \
|
||||||
@ -1513,7 +1513,7 @@ static inline void format_string_loop(output_gadget_t *output, const char *forma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal vsnprintf - used for implementing _all library functions
|
// internal vsnprintf - used for implementing _all library functions
|
||||||
static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args)
|
static __no_instrument_function int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
// Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is
|
// Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is
|
||||||
// possible to call this function with a non-zero pos value for some "remedial printing".
|
// possible to call this function with a non-zero pos value for some "remedial printing".
|
||||||
@ -1528,30 +1528,30 @@ static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list a
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int vprintf_(const char *format, va_list arg)
|
__no_instrument_function int vprintf_(const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
output_gadget_t gadget = extern_putchar_gadget();
|
output_gadget_t gadget = extern_putchar_gadget();
|
||||||
return vsnprintf_impl(&gadget, format, arg);
|
return vsnprintf_impl(&gadget, format, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsnprintf_(char *s, size_t n, const char *format, va_list arg)
|
__no_instrument_function int vsnprintf_(char *s, size_t n, const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
output_gadget_t gadget = buffer_gadget(s, n);
|
output_gadget_t gadget = buffer_gadget(s, n);
|
||||||
return vsnprintf_impl(&gadget, format, arg);
|
return vsnprintf_impl(&gadget, format, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf_(char *s, const char *format, va_list arg)
|
__no_instrument_function int vsprintf_(char *s, const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
return vsnprintf_(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg);
|
return vsnprintf_(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg)
|
__no_instrument_function int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
output_gadget_t gadget = function_gadget(out, extra_arg);
|
output_gadget_t gadget = function_gadget(out, extra_arg);
|
||||||
return vsnprintf_impl(&gadget, format, arg);
|
return vsnprintf_impl(&gadget, format, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf_(const char *format, ...)
|
__no_instrument_function int printf_(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
@ -1560,7 +1560,7 @@ int printf_(const char *format, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprintf_(char *s, const char *format, ...)
|
__no_instrument_function int sprintf_(char *s, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
@ -1569,7 +1569,7 @@ int sprintf_(char *s, const char *format, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snprintf_(char *s, size_t n, const char *format, ...)
|
__no_instrument_function int snprintf_(char *s, size_t n, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
@ -1578,7 +1578,7 @@ int snprintf_(char *s, size_t n, const char *format, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...)
|
__no_instrument_function int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
16
Makefile
16
Makefile
@ -36,6 +36,8 @@ CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/a
|
|||||||
endif
|
endif
|
||||||
HEADERS = $(sort $(dir $(wildcard ./include/*)))
|
HEADERS = $(sort $(dir $(wildcard ./include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
||||||
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
|
GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CPP_SOURCES:.cpp=.gcno)
|
||||||
INCLUDE_DIR = ./include
|
INCLUDE_DIR = ./include
|
||||||
|
|
||||||
LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc
|
LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc
|
||||||
@ -79,7 +81,7 @@ LDFLAGS += -TArchitecture/i686/linker.ld \
|
|||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
CFLAGS += -pipe -fno-builtin -fPIC
|
||||||
CFLAG_STACK_PROTECTOR := -fstack-protector-all
|
CFLAG_STACK_PROTECTOR := -fstack-protector-all -fstack-clash-protection
|
||||||
LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC
|
LDFLAGS += -TArchitecture/aarch64/linker.ld -fPIC
|
||||||
|
|
||||||
endif
|
endif
|
||||||
@ -92,8 +94,12 @@ else ifeq ($(OSARCH), aarch64)
|
|||||||
NASMFLAGS :=
|
NASMFLAGS :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
CFLAGS += -DDEBUG -ggdb -O0 -fdiagnostics-color=always -fsanitize=undefined
|
# CFLAGS += --coverage
|
||||||
|
# CFLAGS += -pg
|
||||||
|
# CFLAGS += -finstrument-functions
|
||||||
|
CFLAGS += -DDEBUG -ggdb -g -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fstack-check -fsanitize=undefined
|
||||||
LDFLAGS += -ggdb -O0 -g
|
LDFLAGS += -ggdb -O0 -g
|
||||||
NASMFLAGS += -F dwarf -g
|
NASMFLAGS += -F dwarf -g
|
||||||
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
|
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
|
||||||
@ -117,9 +123,9 @@ ifeq (,$(wildcard $(KERNEL_FILENAME)))
|
|||||||
$(error $(KERNEL_FILENAME) does not exist)
|
$(error $(KERNEL_FILENAME) does not exist)
|
||||||
endif
|
endif
|
||||||
$(info Dumping $(KERNEL_FILENAME) in AT T syntax...)
|
$(info Dumping $(KERNEL_FILENAME) in AT T syntax...)
|
||||||
$(OBJDUMP) -D -d $(KERNEL_FILENAME) > kernel_dump.map
|
$(OBJDUMP) -D -g -s -d $(KERNEL_FILENAME) > kernel_dump.map
|
||||||
$(info Dumping $(KERNEL_FILENAME) in Intel syntax...)
|
$(info Dumping $(KERNEL_FILENAME) in Intel syntax...)
|
||||||
$(OBJDUMP) -M intel -D -d $(KERNEL_FILENAME) > kernel_dump_intel.map
|
$(OBJDUMP) -M intel -D -g -s -d $(KERNEL_FILENAME) > kernel_dump_intel.map
|
||||||
|
|
||||||
$(KERNEL_FILENAME): $(OBJ)
|
$(KERNEL_FILENAME): $(OBJ)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) -o $@
|
$(CC) $(LDFLAGS) $(OBJ) -o $@
|
||||||
@ -168,4 +174,4 @@ endif
|
|||||||
$(NM) $@
|
$(NM) $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(KERNEL_FILENAME)
|
rm -f *.bin *.o *.elf *.sym kernel.map kernel_dump.map kernel_dump_intel.map initrd.tar.gz $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(KERNEL_FILENAME)
|
||||||
|
87
Profiling/cyg.cpp
Normal file
87
Profiling/cyg.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include <types.h>
|
||||||
|
#include <printf.h>
|
||||||
|
#include <uart.hpp>
|
||||||
|
|
||||||
|
#include "../kernel.h"
|
||||||
|
|
||||||
|
bool EnableProfiler = false;
|
||||||
|
bool Wait = false;
|
||||||
|
unsigned long long LogDepth = 0;
|
||||||
|
unsigned int Level = 0;
|
||||||
|
using namespace UniversalAsynchronousReceiverTransmitter;
|
||||||
|
|
||||||
|
static inline SafeFunction __no_instrument_function void profiler_uart_wrapper(char c, void *unused)
|
||||||
|
{
|
||||||
|
bool renable = EnableProfiler;
|
||||||
|
EnableProfiler = false;
|
||||||
|
UART(COM2).Write(c);
|
||||||
|
(void)unused;
|
||||||
|
if (renable)
|
||||||
|
EnableProfiler = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __cyg_profile_func_enter(void *Function, void *CallSite)
|
||||||
|
{
|
||||||
|
if (!EnableProfiler)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (Wait)
|
||||||
|
asmv("pause");
|
||||||
|
Wait = true;
|
||||||
|
|
||||||
|
if (Level > 40)
|
||||||
|
Level--;
|
||||||
|
|
||||||
|
Level++;
|
||||||
|
|
||||||
|
if (!KernelSymbolTable)
|
||||||
|
fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[42m->\033[0m%*c \033[33m%p\033[0m - \033[33m%p\033[0m\n",
|
||||||
|
LogDepth++,
|
||||||
|
Level - 1,
|
||||||
|
Level,
|
||||||
|
' ',
|
||||||
|
Function,
|
||||||
|
CallSite);
|
||||||
|
else
|
||||||
|
fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[42m->\033[0m%*c \033[33m%s\033[0m - \033[33m%s\033[0m\n",
|
||||||
|
LogDepth++,
|
||||||
|
Level - 1,
|
||||||
|
Level,
|
||||||
|
' ',
|
||||||
|
KernelSymbolTable->GetSymbolFromAddress((uint64_t)Function),
|
||||||
|
KernelSymbolTable->GetSymbolFromAddress((uint64_t)CallSite));
|
||||||
|
Wait = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __cyg_profile_func_exit(void *Function, void *CallSite)
|
||||||
|
{
|
||||||
|
if (!EnableProfiler)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (Wait)
|
||||||
|
asmv("pause");
|
||||||
|
Wait = true;
|
||||||
|
|
||||||
|
if (Level > 40)
|
||||||
|
Level--;
|
||||||
|
|
||||||
|
Level--;
|
||||||
|
|
||||||
|
if (!KernelSymbolTable)
|
||||||
|
fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[41m<-\033[0m%*c \033[33m%p\033[0m - \033[33m%p\033[0m\n",
|
||||||
|
LogDepth++,
|
||||||
|
Level - 1,
|
||||||
|
Level,
|
||||||
|
' ',
|
||||||
|
Function,
|
||||||
|
CallSite);
|
||||||
|
else
|
||||||
|
fctprintf(profiler_uart_wrapper, nullptr, "%lld [%02d]: \033[41m<-\033[0m%*c \033[33m%s\033[0m - \033[33m%s\033[0m\n",
|
||||||
|
LogDepth++,
|
||||||
|
Level - 1,
|
||||||
|
Level,
|
||||||
|
' ',
|
||||||
|
KernelSymbolTable->GetSymbolFromAddress((uint64_t)Function),
|
||||||
|
KernelSymbolTable->GetSymbolFromAddress((uint64_t)CallSite));
|
||||||
|
Wait = false;
|
||||||
|
}
|
67
Profiling/gcov.cpp
Normal file
67
Profiling/gcov.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include <types.h>
|
||||||
|
#include <printf.h>
|
||||||
|
#include <uart.hpp>
|
||||||
|
|
||||||
|
#include "../kernel.h"
|
||||||
|
|
||||||
|
using namespace UniversalAsynchronousReceiverTransmitter;
|
||||||
|
|
||||||
|
#if BITS_PER_LONG >= 64
|
||||||
|
typedef long gcov_type;
|
||||||
|
#else
|
||||||
|
typedef long long gcov_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct gcov_fn_info
|
||||||
|
{
|
||||||
|
unsigned int ident;
|
||||||
|
unsigned int checksum;
|
||||||
|
unsigned int n_ctrs[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gcov_ctr_info
|
||||||
|
{
|
||||||
|
unsigned int num;
|
||||||
|
gcov_type *values;
|
||||||
|
void (*merge)(gcov_type *, unsigned int);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gcov_info
|
||||||
|
{
|
||||||
|
unsigned int version;
|
||||||
|
struct gcov_info *next;
|
||||||
|
unsigned int stamp;
|
||||||
|
const char *filename;
|
||||||
|
unsigned int n_functions;
|
||||||
|
const struct gcov_fn_info *functions;
|
||||||
|
unsigned int ctr_mask;
|
||||||
|
struct gcov_ctr_info counts[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline SafeFunction __no_instrument_function void gcov_uart_wrapper(char c, void *unused)
|
||||||
|
{
|
||||||
|
UART(COM2).Write(c);
|
||||||
|
(void)unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __gcov_init(gcov_info *p __unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __gcov_exit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __gcov_flush(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __gcov_merge_add(gcov_type *counters, unsigned int n_counters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void __gcov_merge_single(gcov_type *counters, unsigned int n_counters)
|
||||||
|
{
|
||||||
|
}
|
19
Profiling/gprof.cpp
Normal file
19
Profiling/gprof.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <types.h>
|
||||||
|
#include <printf.h>
|
||||||
|
#include <uart.hpp>
|
||||||
|
|
||||||
|
#include "../kernel.h"
|
||||||
|
|
||||||
|
using namespace UniversalAsynchronousReceiverTransmitter;
|
||||||
|
|
||||||
|
static inline SafeFunction __no_instrument_function void gprof_uart_wrapper(char c, void *unused)
|
||||||
|
{
|
||||||
|
UART(COM2).Write(c);
|
||||||
|
(void)unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNC SafeFunction __no_instrument_function void mcount(unsigned long frompc, unsigned long selfpc)
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
/* https://docs.kernel.org/trace/ftrace-design.html */
|
||||||
|
}
|
2
Recovery/RecoveryMain.cpp
Normal file
2
Recovery/RecoveryMain.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include <recovery.hpp>
|
||||||
|
|
@ -126,24 +126,10 @@ namespace InterProcessCommunication
|
|||||||
return IPCError{IPCIDNotFound};
|
return IPCError{IPCIDNotFound};
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPCServiceStub()
|
|
||||||
{
|
|
||||||
trace("IPC Service Started.");
|
|
||||||
TaskManager->GetCurrentThread()->SetPriority(1);
|
|
||||||
// TODO: do something useful here, like, IPC event viewer or smth...
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
// The scheduler doesn't like CPU::Pause for some reason. :/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IPC::IPC()
|
IPC::IPC()
|
||||||
{
|
{
|
||||||
SmartLock(IPCLock);
|
SmartLock(IPCLock);
|
||||||
trace("Starting IPC Service...");
|
trace("Starting IPC Service...");
|
||||||
Vector<AuxiliaryVector> auxv;
|
|
||||||
Tasking::TCB *thd = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, nullptr, nullptr, auxv);
|
|
||||||
thd->Rename("IPC Service");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::~IPC()
|
IPC::~IPC()
|
||||||
|
@ -29,7 +29,7 @@ NewLock(SchedulerLock);
|
|||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
extern "C" __no_stack_protector void OneShot(int TimeSlice)
|
extern "C" SafeFunction __no_instrument_function void OneShot(int TimeSlice)
|
||||||
{
|
{
|
||||||
if (TimeSlice == 0)
|
if (TimeSlice == 0)
|
||||||
TimeSlice = 10;
|
TimeSlice = 10;
|
||||||
@ -42,14 +42,15 @@ namespace Tasking
|
|||||||
|
|
||||||
void Task::Schedule()
|
void Task::Schedule()
|
||||||
{
|
{
|
||||||
OneShot(100);
|
if (!StopScheduler)
|
||||||
|
OneShot(100);
|
||||||
// APIC::InterruptCommandRegisterLow icr;
|
// APIC::InterruptCommandRegisterLow icr;
|
||||||
// icr.Vector = CPU::x64::IRQ16;
|
// icr.Vector = CPU::x64::IRQ16;
|
||||||
// icr.Level = APIC::APICLevel::Assert;
|
// icr.Level = APIC::APICLevel::Assert;
|
||||||
// ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr);
|
// ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked, used, no_stack_protector)) void IdleProcessLoop()
|
__naked __used __no_stack_protector __no_instrument_function void IdleProcessLoop()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("IdleLoop:\n"
|
asmv("IdleLoop:\n"
|
||||||
@ -62,7 +63,7 @@ namespace Tasking
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::InvalidPCB(PCB *pcb)
|
SafeFunction __no_instrument_function bool Task::InvalidPCB(PCB *pcb)
|
||||||
{
|
{
|
||||||
if (!pcb)
|
if (!pcb)
|
||||||
return true;
|
return true;
|
||||||
@ -73,7 +74,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::InvalidTCB(TCB *tcb)
|
SafeFunction __no_instrument_function bool Task::InvalidTCB(TCB *tcb)
|
||||||
{
|
{
|
||||||
if (!tcb)
|
if (!tcb)
|
||||||
return true;
|
return true;
|
||||||
@ -84,7 +85,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::RemoveThread(TCB *Thread)
|
SafeFunction __no_instrument_function void Task::RemoveThread(TCB *Thread)
|
||||||
{
|
{
|
||||||
for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++)
|
for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++)
|
||||||
if (Thread->Parent->Threads[i] == Thread)
|
if (Thread->Parent->Threads[i] == Thread)
|
||||||
@ -101,7 +102,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::RemoveProcess(PCB *Process)
|
SafeFunction __no_instrument_function void Task::RemoveProcess(PCB *Process)
|
||||||
{
|
{
|
||||||
if (Process == nullptr)
|
if (Process == nullptr)
|
||||||
return;
|
return;
|
||||||
@ -139,19 +140,19 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::UpdateUserTime(TaskInfo *Info)
|
SafeFunction __no_instrument_function void Task::UpdateUserTime(TaskInfo *Info)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
Info->UserTime++;
|
Info->UserTime++;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::UpdateKernelTime(TaskInfo *Info)
|
SafeFunction __no_instrument_function void Task::UpdateKernelTime(TaskInfo *Info)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
Info->KernelTime++;
|
Info->KernelTime++;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::UpdateUsage(TaskInfo *Info, int Core)
|
SafeFunction __no_instrument_function void Task::UpdateUsage(TaskInfo *Info, int Core)
|
||||||
{
|
{
|
||||||
if (Info->Affinity[Core] == true)
|
if (Info->Affinity[Core] == true)
|
||||||
{
|
{
|
||||||
@ -176,7 +177,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer)
|
SafeFunction __no_instrument_function bool Task::FindNewProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
||||||
schedbg("%d processes", ListProcess.size());
|
schedbg("%d processes", ListProcess.size());
|
||||||
@ -225,7 +226,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
SafeFunction __no_instrument_function bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
||||||
|
|
||||||
@ -265,7 +266,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
SafeFunction __no_instrument_function bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
||||||
|
|
||||||
@ -308,7 +309,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::SchedulerCleanupProcesses()
|
SafeFunction __no_instrument_function void Task::SchedulerCleanupProcesses()
|
||||||
{
|
{
|
||||||
foreach (PCB *pcb in ListProcess)
|
foreach (PCB *pcb in ListProcess)
|
||||||
{
|
{
|
||||||
@ -318,7 +319,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
SafeFunction __no_instrument_function bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
||||||
|
|
||||||
@ -346,7 +347,7 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::Schedule(CPU::x64::TrapFrame *Frame)
|
SafeFunction __no_instrument_function void Task::Schedule(CPU::x64::TrapFrame *Frame)
|
||||||
{
|
{
|
||||||
SmartCriticalSection(SchedulerLock);
|
SmartCriticalSection(SchedulerLock);
|
||||||
if (StopScheduler)
|
if (StopScheduler)
|
||||||
@ -491,9 +492,10 @@ namespace Tasking
|
|||||||
if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE ||
|
if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE ||
|
||||||
CurrentCPU->CurrentThread->Registers.ss != GDT_USER_DATA)
|
CurrentCPU->CurrentThread->Registers.ss != GDT_USER_DATA)
|
||||||
{
|
{
|
||||||
warn("Wrong CS or SS for user process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx)",
|
warn("Wrong CS or SS for user thread %s(%ld)! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx)",
|
||||||
CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss,
|
CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss,
|
||||||
GDT_USER_CODE, GDT_USER_DATA);
|
GDT_USER_CODE, GDT_USER_DATA,
|
||||||
|
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID);
|
||||||
CurrentCPU->CurrentThread->Registers.cs = GDT_USER_CODE;
|
CurrentCPU->CurrentThread->Registers.cs = GDT_USER_CODE;
|
||||||
CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA;
|
CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA;
|
||||||
}
|
}
|
||||||
@ -503,9 +505,10 @@ namespace Tasking
|
|||||||
if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE ||
|
if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE ||
|
||||||
CurrentCPU->CurrentThread->Registers.ss != GDT_KERNEL_DATA)
|
CurrentCPU->CurrentThread->Registers.ss != GDT_KERNEL_DATA)
|
||||||
{
|
{
|
||||||
warn("Wrong CS or SS for kernel process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx",
|
warn("Wrong CS or SS for kernel thread %s(%ld)! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx",
|
||||||
CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss,
|
CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss,
|
||||||
GDT_KERNEL_CODE, GDT_KERNEL_DATA);
|
GDT_KERNEL_CODE, GDT_KERNEL_DATA,
|
||||||
|
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID);
|
||||||
CurrentCPU->CurrentThread->Registers.cs = GDT_KERNEL_CODE;
|
CurrentCPU->CurrentThread->Registers.cs = GDT_KERNEL_CODE;
|
||||||
CurrentCPU->CurrentThread->Registers.ss = GDT_KERNEL_DATA;
|
CurrentCPU->CurrentThread->Registers.ss = GDT_KERNEL_DATA;
|
||||||
}
|
}
|
||||||
@ -583,71 +586,71 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); }
|
SafeFunction __no_instrument_function void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); }
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer)
|
SafeFunction bool Task::FindNewProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::SchedulerCleanupProcesses()
|
SafeFunction void Task::SchedulerCleanupProcesses()
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::Schedule(void *Frame)
|
SafeFunction void Task::Schedule(void *Frame)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); }
|
SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); }
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
__no_stack_protector bool Task::FindNewProcess(void *CPUDataPointer)
|
SafeFunction bool Task::FindNewProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::SchedulerCleanupProcesses()
|
SafeFunction void Task::SchedulerCleanupProcesses()
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::Schedule(void *Frame)
|
SafeFunction void Task::Schedule(void *Frame)
|
||||||
{
|
{
|
||||||
fixme("unimplemented");
|
fixme("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); }
|
SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ThreadDoExit()
|
void ThreadDoExit()
|
||||||
@ -853,8 +856,10 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
while (argv[ArgvSize] != nullptr)
|
while (argv[ArgvSize] != nullptr)
|
||||||
{
|
{
|
||||||
|
debug("> ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize);
|
||||||
ArgvSize++;
|
ArgvSize++;
|
||||||
ArgvStrSize += strlen(argv[ArgvSize]) + 1;
|
ArgvStrSize += strlen(argv[ArgvSize]) + 1;
|
||||||
|
debug("< ArgvSize: %d, ArgvStrSize: %d", ArgvSize, ArgvStrSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,8 +869,10 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
while (envp[EnvpSize] != nullptr)
|
while (envp[EnvpSize] != nullptr)
|
||||||
{
|
{
|
||||||
|
debug("> EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize);
|
||||||
EnvpSize++;
|
EnvpSize++;
|
||||||
EnvpStrSize += strlen(envp[EnvpSize]) + 1;
|
EnvpStrSize += strlen(envp[EnvpSize]) + 1;
|
||||||
|
debug("< EnvpSize: %d, EnvpStrSize: %d", EnvpSize, EnvpStrSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -881,15 +888,19 @@ namespace Tasking
|
|||||||
argv[i] = (char *)_argv;
|
argv[i] = (char *)_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug("argv done");
|
||||||
|
|
||||||
for (uint64_t i = 0; i < EnvpSize; i++)
|
for (uint64_t i = 0; i < EnvpSize; i++)
|
||||||
{
|
{
|
||||||
void *Tmp = KernelAllocator.RequestPages(TO_PAGES(strlen(argv[i]) + 1));
|
void *Tmp = KernelAllocator.RequestPages(TO_PAGES(strlen(envp[i]) + 1));
|
||||||
Memory::Virtual().Map(Tmp, Tmp, Memory::PTFlag::RW | Memory::PTFlag::US);
|
Memory::Virtual().Map(Tmp, Tmp, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
_envp = (uint8_t *)Tmp;
|
_envp = (uint8_t *)Tmp;
|
||||||
strcpy((char *)_envp, envp[i]);
|
strcpy((char *)_envp, envp[i]);
|
||||||
envp[i] = (char *)_envp;
|
envp[i] = (char *)_envp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug("envp done");
|
||||||
|
|
||||||
Thread->Registers.rdi = ArgvSize;
|
Thread->Registers.rdi = ArgvSize;
|
||||||
Thread->Registers.rsi = (uint64_t)_argv;
|
Thread->Registers.rsi = (uint64_t)_argv;
|
||||||
Thread->Registers.rdx = (uint64_t)_envp;
|
Thread->Registers.rdx = (uint64_t)_envp;
|
||||||
|
@ -19,15 +19,18 @@ extern "C"
|
|||||||
int atoi(const char *String);
|
int atoi(const char *String);
|
||||||
double atof(const char *String);
|
double atof(const char *String);
|
||||||
char *itoa(int Value, char *Buffer, int Base);
|
char *itoa(int Value, char *Buffer, int Base);
|
||||||
|
char *ltoa(long Value, char *Buffer, int Base);
|
||||||
|
char *ultoa(unsigned long Value, char *Buffer, int Base);
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, size_t n);
|
void *memcpy_unsafe(void *dest, const void *src, size_t n);
|
||||||
void *memset(void *dest, int c, size_t n);
|
void *memset_unsafe(void *dest, int c, size_t n);
|
||||||
void *memmove(void *dest, const void *src, size_t n);
|
void *memmove_unsafe(void *dest, const void *src, size_t n);
|
||||||
int memcmp(const void *vl, const void *vr, size_t n);
|
int memcmp(const void *vl, const void *vr, size_t n);
|
||||||
|
|
||||||
long unsigned strlen(const char s[]);
|
long unsigned strlen(const char s[]);
|
||||||
int strncmp(const char *s1, const char *s2, unsigned long n);
|
int strncmp(const char *s1, const char *s2, unsigned long n);
|
||||||
char *strcat(char *destination, const char *source);
|
char *strcat_unsafe(char *destination, const char *source);
|
||||||
char *strcpy(char *destination, const char *source);
|
char *strcpy_unsafe(char *destination, const char *source);
|
||||||
char *strncpy(char *destination, const char *source, unsigned long num);
|
char *strncpy(char *destination, const char *source, unsigned long num);
|
||||||
int strcmp(const char *l, const char *r);
|
int strcmp(const char *l, const char *r);
|
||||||
char *strstr(const char *haystack, const char *needle);
|
char *strstr(const char *haystack, const char *needle);
|
||||||
@ -38,6 +41,32 @@ extern "C"
|
|||||||
int strcasecmp(const char *lhs, const char *rhs);
|
int strcasecmp(const char *lhs, const char *rhs);
|
||||||
char *strtok(char *src, const char *delim);
|
char *strtok(char *src, const char *delim);
|
||||||
|
|
||||||
|
void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen);
|
||||||
|
void *__memset_chk(void *dest, int val, size_t len, size_t slen);
|
||||||
|
void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen);
|
||||||
|
char *__strcat_chk(char *dest, const char *src, size_t slen);
|
||||||
|
char *__strcpy_chk(char *dest, const char *src, size_t slen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef memcpy
|
||||||
|
#define memcpy(dest, src, n) \
|
||||||
|
__memcpy_chk(dest, src, n, __builtin_object_size(dest, 0))
|
||||||
|
|
||||||
|
#undef memset
|
||||||
|
#define memset(dest, c, n) \
|
||||||
|
__memset_chk(dest, c, n, __builtin_object_size(dest, 0))
|
||||||
|
|
||||||
|
#undef memmove
|
||||||
|
#define memmove(dest, src, n) \
|
||||||
|
__memmove_chk(dest, src, n, __builtin_object_size(dest, 0))
|
||||||
|
|
||||||
|
#undef strcat
|
||||||
|
#define strcat(dest, src) \
|
||||||
|
__strcat_chk(dest, src, __builtin_object_size(dest, 0))
|
||||||
|
|
||||||
|
#undef strcpy
|
||||||
|
#define strcpy(dest, src) \
|
||||||
|
__strcpy_chk(dest, src, __builtin_object_size(dest, 0))
|
||||||
|
@ -143,7 +143,7 @@ namespace CPU
|
|||||||
/**
|
/**
|
||||||
* @brief Pause the CPU
|
* @brief Pause the CPU
|
||||||
*/
|
*/
|
||||||
__no_stack_protector static inline void Pause(bool Loop = false)
|
SafeFunction static inline void Pause(bool Loop = false)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -158,7 +158,7 @@ namespace CPU
|
|||||||
/**
|
/**
|
||||||
* @brief Stop the CPU (infinite loop)
|
* @brief Stop the CPU (infinite loop)
|
||||||
*/
|
*/
|
||||||
__no_stack_protector static inline void Stop()
|
SafeFunction static inline void Stop()
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -177,7 +177,7 @@ namespace CPU
|
|||||||
/**
|
/**
|
||||||
* @brief Halt the CPU
|
* @brief Halt the CPU
|
||||||
*/
|
*/
|
||||||
__no_stack_protector static inline void Halt(bool Loop = false)
|
SafeFunction static inline void Halt(bool Loop = false)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -213,7 +213,7 @@ namespace CPU
|
|||||||
|
|
||||||
namespace MemBar
|
namespace MemBar
|
||||||
{
|
{
|
||||||
__no_stack_protector static inline void Barrier()
|
SafeFunction static inline void Barrier()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("" ::
|
asmv("" ::
|
||||||
@ -224,7 +224,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void Fence()
|
SafeFunction static inline void Fence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("mfence" ::
|
asmv("mfence" ::
|
||||||
@ -235,7 +235,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void StoreFence()
|
SafeFunction static inline void StoreFence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("sfence" ::
|
asmv("sfence" ::
|
||||||
@ -246,7 +246,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void LoadFence()
|
SafeFunction static inline void LoadFence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("lfence" ::
|
asmv("lfence" ::
|
||||||
@ -549,7 +549,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void invlpg(void *Address)
|
SafeFunction static inline void invlpg(void *Address)
|
||||||
{
|
{
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
asmv("invlpg (%0)"
|
asmv("invlpg (%0)"
|
||||||
@ -1670,7 +1670,7 @@ namespace CPU
|
|||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
} SelectorErrorCode;
|
} SelectorErrorCode;
|
||||||
|
|
||||||
__no_stack_protector static inline void lgdt(void *gdt)
|
SafeFunction static inline void lgdt(void *gdt)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("lgdt (%0)"
|
asmv("lgdt (%0)"
|
||||||
@ -1679,7 +1679,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void lidt(void *idt)
|
SafeFunction static inline void lidt(void *idt)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("lidt (%0)"
|
asmv("lidt (%0)"
|
||||||
@ -1688,7 +1688,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void ltr(uint16_t Segment)
|
SafeFunction static inline void ltr(uint16_t Segment)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("ltr %0"
|
asmv("ltr %0"
|
||||||
@ -1697,7 +1697,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void invlpg(void *Address)
|
SafeFunction static inline void invlpg(void *Address)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("invlpg (%0)"
|
asmv("invlpg (%0)"
|
||||||
@ -1716,7 +1716,7 @@ namespace CPU
|
|||||||
* @param ecx ECX
|
* @param ecx ECX
|
||||||
* @param edx EDX
|
* @param edx EDX
|
||||||
*/
|
*/
|
||||||
__no_stack_protector static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
SafeFunction static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("cpuid"
|
asmv("cpuid"
|
||||||
@ -1732,14 +1732,14 @@ namespace CPU
|
|||||||
*
|
*
|
||||||
* @return uint32_t
|
* @return uint32_t
|
||||||
*/
|
*/
|
||||||
__no_stack_protector static inline uint32_t GetHighestLeaf()
|
SafeFunction static inline uint32_t GetHighestLeaf()
|
||||||
{
|
{
|
||||||
uint32_t eax, ebx, ecx, edx;
|
uint32_t eax, ebx, ecx, edx;
|
||||||
cpuid(0x0, &eax, &ebx, &ecx, &edx);
|
cpuid(0x0, &eax, &ebx, &ecx, &edx);
|
||||||
return eax;
|
return eax;
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline uint64_t rdmsr(uint32_t msr)
|
SafeFunction static inline uint64_t rdmsr(uint32_t msr)
|
||||||
{
|
{
|
||||||
uint32_t Low, High;
|
uint32_t Low, High;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1751,7 +1751,7 @@ namespace CPU
|
|||||||
return ((uint64_t)Low) | (((uint64_t)High) << 32);
|
return ((uint64_t)Low) | (((uint64_t)High) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void wrmsr(uint32_t msr, uint64_t Value)
|
SafeFunction static inline void wrmsr(uint32_t msr, uint64_t Value)
|
||||||
{
|
{
|
||||||
uint32_t Low = Value, High = Value >> 32;
|
uint32_t Low = Value, High = Value >> 32;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1762,7 +1762,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline CR0 readcr0()
|
SafeFunction static inline CR0 readcr0()
|
||||||
{
|
{
|
||||||
uint64_t Result;
|
uint64_t Result;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1772,7 +1772,7 @@ namespace CPU
|
|||||||
return (CR0){.raw = Result};
|
return (CR0){.raw = Result};
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline CR2 readcr2()
|
SafeFunction static inline CR2 readcr2()
|
||||||
{
|
{
|
||||||
uint64_t Result;
|
uint64_t Result;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1782,7 +1782,7 @@ namespace CPU
|
|||||||
return (CR2){.raw = Result};
|
return (CR2){.raw = Result};
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline CR3 readcr3()
|
SafeFunction static inline CR3 readcr3()
|
||||||
{
|
{
|
||||||
uint64_t Result;
|
uint64_t Result;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1792,7 +1792,7 @@ namespace CPU
|
|||||||
return (CR3){.raw = Result};
|
return (CR3){.raw = Result};
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline CR4 readcr4()
|
SafeFunction static inline CR4 readcr4()
|
||||||
{
|
{
|
||||||
uint64_t Result;
|
uint64_t Result;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1802,7 +1802,7 @@ namespace CPU
|
|||||||
return (CR4){.raw = Result};
|
return (CR4){.raw = Result};
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline CR8 readcr8()
|
SafeFunction static inline CR8 readcr8()
|
||||||
{
|
{
|
||||||
uint64_t Result;
|
uint64_t Result;
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -1812,7 +1812,7 @@ namespace CPU
|
|||||||
return (CR8){.raw = Result};
|
return (CR8){.raw = Result};
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void writecr0(CR0 ControlRegister)
|
SafeFunction static inline void writecr0(CR0 ControlRegister)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("mov %[ControlRegister], %%cr0"
|
asmv("mov %[ControlRegister], %%cr0"
|
||||||
@ -1822,7 +1822,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void writecr2(CR2 ControlRegister)
|
SafeFunction static inline void writecr2(CR2 ControlRegister)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("mov %[ControlRegister], %%cr2"
|
asmv("mov %[ControlRegister], %%cr2"
|
||||||
@ -1832,7 +1832,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void writecr3(CR3 ControlRegister)
|
SafeFunction static inline void writecr3(CR3 ControlRegister)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("mov %[ControlRegister], %%cr3"
|
asmv("mov %[ControlRegister], %%cr3"
|
||||||
@ -1842,7 +1842,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void writecr4(CR4 ControlRegister)
|
SafeFunction static inline void writecr4(CR4 ControlRegister)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("mov %[ControlRegister], %%cr4"
|
asmv("mov %[ControlRegister], %%cr4"
|
||||||
@ -1852,7 +1852,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void writecr8(CR8 ControlRegister)
|
SafeFunction static inline void writecr8(CR8 ControlRegister)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
asmv("mov %[ControlRegister], %%cr8"
|
asmv("mov %[ControlRegister], %%cr8"
|
||||||
@ -1862,7 +1862,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void fxsave(char *FXSaveArea)
|
SafeFunction static inline void fxsave(char *FXSaveArea)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
|
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
|
||||||
@ -1876,7 +1876,7 @@ namespace CPU
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__no_stack_protector static inline void fxrstor(char *FXRstorArea)
|
SafeFunction static inline void fxrstor(char *FXRstorArea)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
|
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
|
||||||
|
@ -156,8 +156,10 @@ namespace Video
|
|||||||
|
|
||||||
void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index)
|
void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index)
|
||||||
{
|
{
|
||||||
if (X >= this->Buffers[Index]->Width || Y >= this->Buffers[Index]->Height)
|
if (X >= this->Buffers[Index]->Width)
|
||||||
return;
|
X = this->Buffers[Index]->Width - 1;
|
||||||
|
if (Y >= this->Buffers[Index]->Height)
|
||||||
|
Y = this->Buffers[Index]->Height - 1;
|
||||||
uint32_t *Pixel = (uint32_t *)((uint64_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8));
|
uint32_t *Pixel = (uint32_t *)((uint64_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8));
|
||||||
*Pixel = Color;
|
*Pixel = Color;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ namespace FileSystem
|
|||||||
FS_MOUNTPOINT = 0x08
|
FS_MOUNTPOINT = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileSystemOpeations
|
struct FileSystemOperations
|
||||||
{
|
{
|
||||||
char Name[FILENAME_LENGTH];
|
char Name[FILENAME_LENGTH];
|
||||||
OperationMount Mount = nullptr;
|
OperationMount Mount = nullptr;
|
||||||
@ -113,7 +113,7 @@ namespace FileSystem
|
|||||||
uint64_t Address = 0;
|
uint64_t Address = 0;
|
||||||
uint64_t Length = 0;
|
uint64_t Length = 0;
|
||||||
FileSystemNode *Parent = nullptr;
|
FileSystemNode *Parent = nullptr;
|
||||||
FileSystemOpeations *Operator = nullptr;
|
FileSystemOperations *Operator = nullptr;
|
||||||
/* For root node:
|
/* For root node:
|
||||||
0 - root "/"
|
0 - root "/"
|
||||||
1 - etc
|
1 - etc
|
||||||
@ -150,13 +150,13 @@ namespace FileSystem
|
|||||||
char *NormalizePath(FileSystemNode *Parent, const char *Path);
|
char *NormalizePath(FileSystemNode *Parent, const char *Path);
|
||||||
|
|
||||||
FileStatus FileExists(FileSystemNode *Parent, const char *Path);
|
FileStatus FileExists(FileSystemNode *Parent, const char *Path);
|
||||||
FILE *Mount(FileSystemOpeations *Operator, const char *Path);
|
FILE *Mount(FileSystemOperations *Operator, const char *Path);
|
||||||
FileStatus Unmount(FILE *File);
|
FileStatus Unmount(FILE *File);
|
||||||
FILE *Open(const char *Path, FileSystemNode *Parent = nullptr);
|
FILE *Open(const char *Path, FileSystemNode *Parent = nullptr);
|
||||||
uint64_t Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
uint64_t Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
||||||
uint64_t Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
uint64_t Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
||||||
FileStatus Close(FILE *File);
|
FileStatus Close(FILE *File);
|
||||||
FileSystemNode *CreateRoot(FileSystemOpeations *Operator, const char *RootName);
|
FileSystemNode *CreateRoot(FileSystemOperations *Operator, const char *RootName);
|
||||||
FileSystemNode *Create(FileSystemNode *Parent, const char *Path);
|
FileSystemNode *Create(FileSystemNode *Parent, const char *Path);
|
||||||
|
|
||||||
Virtual();
|
Virtual();
|
||||||
|
@ -11,7 +11,7 @@ namespace FileSystem
|
|||||||
class Device
|
class Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileSystemNode *AddFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
FileSystemNode *AddFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||||
Device();
|
Device();
|
||||||
~Device();
|
~Device();
|
||||||
};
|
};
|
||||||
@ -20,7 +20,7 @@ namespace FileSystem
|
|||||||
class Mount
|
class Mount
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileSystemNode *MountFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name);
|
FileSystemNode *MountFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name);
|
||||||
void DetectAndMountFS(void *drive);
|
void DetectAndMountFS(void *drive);
|
||||||
Mount();
|
Mount();
|
||||||
~Mount();
|
~Mount();
|
||||||
@ -38,7 +38,7 @@ namespace FileSystem
|
|||||||
class Driver
|
class Driver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileSystemNode *AddDriver(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
FileSystemNode *AddDriver(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||||
Driver();
|
Driver();
|
||||||
~Driver();
|
~Driver();
|
||||||
};
|
};
|
||||||
@ -47,7 +47,7 @@ namespace FileSystem
|
|||||||
class Network
|
class Network
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileSystemNode *AddNetworkCard(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
FileSystemNode *AddNetworkCard(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||||
Network();
|
Network();
|
||||||
~Network();
|
~Network();
|
||||||
};
|
};
|
||||||
|
@ -6,17 +6,26 @@
|
|||||||
|
|
||||||
namespace Interrupts
|
namespace Interrupts
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG // For performance reasons
|
||||||
|
#define INT_FRAMES_MAX 512
|
||||||
|
#else
|
||||||
|
#define INT_FRAMES_MAX 8
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
||||||
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
||||||
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#endif
|
#endif
|
||||||
|
extern void *InterruptFrames[INT_FRAMES_MAX];
|
||||||
|
|
||||||
void Initialize(int Core);
|
void Initialize(int Core);
|
||||||
void Enable(int Core);
|
void Enable(int Core);
|
||||||
void InitializeTimer(int Core);
|
void InitializeTimer(int Core);
|
||||||
|
void RemoveAll();
|
||||||
|
|
||||||
class Handler
|
class Handler
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@ struct KernelConfig
|
|||||||
char InitPath[256];
|
char InitPath[256];
|
||||||
bool InterruptsOnCrash;
|
bool InterruptsOnCrash;
|
||||||
int Cores;
|
int Cores;
|
||||||
|
bool UnlockDeadLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
KernelConfig ParseConfig(char *Config);
|
KernelConfig ParseConfig(char *Config);
|
||||||
|
11
include/recovery.hpp
Normal file
11
include/recovery.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __FENNIX_KERNEL_RECOVERY_H__
|
||||||
|
#define __FENNIX_KERNEL_RECOVERY_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
namespace Recovery
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_RECOVERY_H__
|
@ -101,6 +101,7 @@ namespace Tasking
|
|||||||
|
|
||||||
void Rename(const char *name)
|
void Rename(const char *name)
|
||||||
{
|
{
|
||||||
|
CriticalSection cs;
|
||||||
if (!Name[0])
|
if (!Name[0])
|
||||||
{
|
{
|
||||||
warn("Tried to rename thread %d to NULL", ID);
|
warn("Tried to rename thread %d to NULL", ID);
|
||||||
@ -117,6 +118,7 @@ namespace Tasking
|
|||||||
|
|
||||||
void SetPriority(int priority)
|
void SetPriority(int priority)
|
||||||
{
|
{
|
||||||
|
CriticalSection cs;
|
||||||
trace("Setting priority of thread %s to %d", Name, priority);
|
trace("Setting priority of thread %s to %d", Name, priority);
|
||||||
Info.Priority = priority;
|
Info.Priority = priority;
|
||||||
}
|
}
|
||||||
@ -125,6 +127,7 @@ namespace Tasking
|
|||||||
|
|
||||||
void SetCritical(bool critical)
|
void SetCritical(bool critical)
|
||||||
{
|
{
|
||||||
|
CriticalSection cs;
|
||||||
trace("Setting criticality of thread %s to %s", Name, critical ? "true" : "false");
|
trace("Setting criticality of thread %s to %s", Name, critical ? "true" : "false");
|
||||||
Security.IsCritical = critical;
|
Security.IsCritical = critical;
|
||||||
}
|
}
|
||||||
@ -215,7 +218,13 @@ namespace Tasking
|
|||||||
Vector<PCB *> GetProcessList() { return ListProcess; }
|
Vector<PCB *> GetProcessList() { return ListProcess; }
|
||||||
void Panic() { StopScheduler = true; }
|
void Panic() { StopScheduler = true; }
|
||||||
void Schedule();
|
void Schedule();
|
||||||
long GetUsage(int Core) { return 100 - IdleProcess->Info.Usage[Core]; }
|
long GetUsage(int Core)
|
||||||
|
{
|
||||||
|
if (IdleProcess)
|
||||||
|
return 100 - IdleProcess->Info.Usage[Core];
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
void KillThread(TCB *tcb, int Code)
|
void KillThread(TCB *tcb, int Code)
|
||||||
{
|
{
|
||||||
tcb->Status = TaskStatus::Terminated;
|
tcb->Status = TaskStatus::Terminated;
|
||||||
|
@ -207,7 +207,6 @@ typedef __SIZE_TYPE__ size_t;
|
|||||||
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
|
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
|
||||||
#define b64(x) __builtin_bswap64(x)
|
#define b64(x) __builtin_bswap64(x)
|
||||||
|
|
||||||
|
|
||||||
#define O0 __attribute__((optimize("O0")))
|
#define O0 __attribute__((optimize("O0")))
|
||||||
#define O1 __attribute__((optimize("O1")))
|
#define O1 __attribute__((optimize("O1")))
|
||||||
#define O2 __attribute__((optimize("O2")))
|
#define O2 __attribute__((optimize("O2")))
|
||||||
@ -220,6 +219,7 @@ typedef __SIZE_TYPE__ size_t;
|
|||||||
|
|
||||||
#define __unused __attribute__((unused))
|
#define __unused __attribute__((unused))
|
||||||
#define __packed __attribute__((packed))
|
#define __packed __attribute__((packed))
|
||||||
|
#define __naked __attribute__((naked))
|
||||||
#define __aligned(x) __attribute__((aligned(x)))
|
#define __aligned(x) __attribute__((aligned(x)))
|
||||||
#define __section(x) __attribute__((section(x)))
|
#define __section(x) __attribute__((section(x)))
|
||||||
#define __noreturn __attribute__((noreturn))
|
#define __noreturn __attribute__((noreturn))
|
||||||
@ -252,12 +252,17 @@ typedef __SIZE_TYPE__ size_t;
|
|||||||
#define __nonnull_all __attribute__((nonnull))
|
#define __nonnull_all __attribute__((nonnull))
|
||||||
#define __warn_unused_result __attribute__((warn_unused_result))
|
#define __warn_unused_result __attribute__((warn_unused_result))
|
||||||
#define __no_stack_protector __attribute__((no_stack_protector))
|
#define __no_stack_protector __attribute__((no_stack_protector))
|
||||||
|
#define __no_instrument_function __attribute__((no_instrument_function))
|
||||||
|
|
||||||
// sanitizer
|
// sanitizer
|
||||||
#define __no_sanitize_address __attribute__((no_sanitize_address))
|
#define __no_sanitize_address __attribute__((no_sanitize_address))
|
||||||
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
|
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
|
||||||
#define __no_address_safety_analysis __attribute__((no_address_safety_analysis))
|
#define __no_address_safety_analysis __attribute__((no_address_safety_analysis))
|
||||||
#define __no_sanitize_thread __attribute__((no_sanitize_thread))
|
#define __no_sanitize_thread __attribute__((no_sanitize_thread))
|
||||||
#define __no_sanitize_memory __attribute__((no_sanitize_memory))
|
|
||||||
#define __no_sanitize_hwaddress __attribute__((no_sanitize_hwaddress))
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
|
||||||
|
#define SafeFunction __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_address_safety_analysis __no_sanitize_thread
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_TYPES_H__
|
#endif // !__FENNIX_KERNEL_TYPES_H__
|
||||||
|
@ -51,7 +51,7 @@ namespace UniversalAsynchronousReceiverTransmitter
|
|||||||
* @brief Get the Registered Port object
|
* @brief Get the Registered Port object
|
||||||
* @return SerialPorts
|
* @return SerialPorts
|
||||||
*/
|
*/
|
||||||
SerialPorts GetRegisteredPort() { return this->Port; }
|
SafeFunction __no_instrument_function SerialPorts GetRegisteredPort() { return this->Port; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a character is sent.
|
* @brief Called when a character is sent.
|
||||||
|
@ -13,7 +13,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
typedef T *iterator;
|
typedef T *iterator;
|
||||||
|
|
||||||
Vector()
|
__no_instrument_function Vector()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MEM_ALLOCATION
|
#ifdef DEBUG_MEM_ALLOCATION
|
||||||
debug("VECTOR INIT: Vector( )");
|
debug("VECTOR INIT: Vector( )");
|
||||||
@ -23,7 +23,7 @@ public:
|
|||||||
VectorBuffer = 0;
|
VectorBuffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(uint64_t Size)
|
__no_instrument_function Vector(uint64_t Size)
|
||||||
{
|
{
|
||||||
VectorCapacity = Size;
|
VectorCapacity = Size;
|
||||||
VectorSize = Size;
|
VectorSize = Size;
|
||||||
@ -33,7 +33,7 @@ public:
|
|||||||
VectorBuffer = new T[Size];
|
VectorBuffer = new T[Size];
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(uint64_t Size, const T &Initial)
|
__no_instrument_function Vector(uint64_t Size, const T &Initial)
|
||||||
{
|
{
|
||||||
VectorSize = Size;
|
VectorSize = Size;
|
||||||
VectorCapacity = Size;
|
VectorCapacity = Size;
|
||||||
@ -45,7 +45,7 @@ public:
|
|||||||
VectorBuffer[i] = Initial;
|
VectorBuffer[i] = Initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(const Vector<T> &Vector)
|
__no_instrument_function Vector(const Vector<T> &Vector)
|
||||||
{
|
{
|
||||||
VectorSize = Vector.VectorSize;
|
VectorSize = Vector.VectorSize;
|
||||||
VectorCapacity = Vector.VectorCapacity;
|
VectorCapacity = Vector.VectorCapacity;
|
||||||
@ -57,7 +57,7 @@ public:
|
|||||||
VectorBuffer[i] = Vector.VectorBuffer[i];
|
VectorBuffer[i] = Vector.VectorBuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
~Vector()
|
__no_instrument_function ~Vector()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MEM_ALLOCATION
|
#ifdef DEBUG_MEM_ALLOCATION
|
||||||
debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer);
|
debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer);
|
||||||
@ -65,7 +65,7 @@ public:
|
|||||||
delete[] VectorBuffer;
|
delete[] VectorBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(uint64_t Position)
|
__no_instrument_function void remove(uint64_t Position)
|
||||||
{
|
{
|
||||||
if (Position >= VectorSize)
|
if (Position >= VectorSize)
|
||||||
return;
|
return;
|
||||||
@ -77,30 +77,30 @@ public:
|
|||||||
VectorSize--;
|
VectorSize--;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t capacity() const { return VectorCapacity; }
|
__no_instrument_function uint64_t capacity() const { return VectorCapacity; }
|
||||||
|
|
||||||
uint64_t size() const { return VectorSize; }
|
__no_instrument_function uint64_t size() const { return VectorSize; }
|
||||||
|
|
||||||
bool empty() const;
|
__no_instrument_function bool empty() const;
|
||||||
|
|
||||||
iterator begin() { return VectorBuffer; }
|
__no_instrument_function iterator begin() { return VectorBuffer; }
|
||||||
|
|
||||||
iterator end() { return VectorBuffer + size(); }
|
__no_instrument_function iterator end() { return VectorBuffer + size(); }
|
||||||
|
|
||||||
T &front() { return VectorBuffer[0]; }
|
__no_instrument_function T &front() { return VectorBuffer[0]; }
|
||||||
|
|
||||||
T &back() { return VectorBuffer[VectorSize - 1]; }
|
__no_instrument_function T &back() { return VectorBuffer[VectorSize - 1]; }
|
||||||
|
|
||||||
void push_back(const T &Value)
|
__no_instrument_function void push_back(const T &Value)
|
||||||
{
|
{
|
||||||
if (VectorSize >= VectorCapacity)
|
if (VectorSize >= VectorCapacity)
|
||||||
reserve(VectorCapacity + 5);
|
reserve(VectorCapacity + 5);
|
||||||
VectorBuffer[VectorSize++] = Value;
|
VectorBuffer[VectorSize++] = Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_back() { VectorSize--; }
|
__no_instrument_function void pop_back() { VectorSize--; }
|
||||||
|
|
||||||
void reverse()
|
__no_instrument_function void reverse()
|
||||||
{
|
{
|
||||||
if (VectorSize <= 1)
|
if (VectorSize <= 1)
|
||||||
return;
|
return;
|
||||||
@ -112,7 +112,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(uint64_t Capacity)
|
__no_instrument_function void reserve(uint64_t Capacity)
|
||||||
{
|
{
|
||||||
if (VectorBuffer == 0)
|
if (VectorBuffer == 0)
|
||||||
{
|
{
|
||||||
@ -134,15 +134,15 @@ public:
|
|||||||
VectorBuffer = Newbuffer;
|
VectorBuffer = Newbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(uint64_t Size)
|
__no_instrument_function void resize(uint64_t Size)
|
||||||
{
|
{
|
||||||
reserve(Size);
|
reserve(Size);
|
||||||
VectorSize = Size;
|
VectorSize = Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
T &operator[](uint64_t Index) { return VectorBuffer[Index]; }
|
__no_instrument_function T &operator[](uint64_t Index) { return VectorBuffer[Index]; }
|
||||||
|
|
||||||
Vector<T> &operator=(const Vector<T> &Vector)
|
__no_instrument_function Vector<T> &operator=(const Vector<T> &Vector)
|
||||||
{
|
{
|
||||||
delete[] VectorBuffer;
|
delete[] VectorBuffer;
|
||||||
VectorSize = Vector.VectorSize;
|
VectorSize = Vector.VectorSize;
|
||||||
@ -156,12 +156,12 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
__no_instrument_function void clear()
|
||||||
{
|
{
|
||||||
VectorCapacity = 0;
|
VectorCapacity = 0;
|
||||||
VectorSize = 0;
|
VectorSize = 0;
|
||||||
VectorBuffer = 0;
|
VectorBuffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *data() { return VectorBuffer; }
|
__no_instrument_function T *data() { return VectorBuffer; }
|
||||||
};
|
};
|
||||||
|
1
kernel.h
1
kernel.h
@ -38,6 +38,7 @@ extern Disk::Manager *DiskManager;
|
|||||||
EXTERNC void putchar(char c);
|
EXTERNC void putchar(char c);
|
||||||
EXTERNC void KPrint(const char *format, ...);
|
EXTERNC void KPrint(const char *format, ...);
|
||||||
EXTERNC void Entry(struct BootInfo *Info);
|
EXTERNC void Entry(struct BootInfo *Info);
|
||||||
|
EXTERNC void BeforeShutdown();
|
||||||
EXTERNC void TaskingPanic();
|
EXTERNC void TaskingPanic();
|
||||||
|
|
||||||
EXTERNC void KernelMainThread();
|
EXTERNC void KernelMainThread();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user