From 9ce301907a76c124eacf51303d628373046e8f80 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 24 Mar 2023 16:22:42 +0200 Subject: [PATCH] QoL improvements --- .../amd64/cpu/GlobalDescriptorTable.cpp | 142 ++++++----- .../amd64/cpu/InterruptDescriptorTable.cpp | 122 ++------- .../amd64/cpu/SymmetricMultiprocessing.cpp | 3 +- Core/InterruptsManager.cpp | 3 +- Core/Lock.cpp | 26 +- Core/Memory/MemoryManager.cpp | 19 +- Core/Memory/PhysicalMemoryManager.cpp | 59 +++-- Core/Memory/StackGuard.cpp | 20 +- Core/Memory/VirtualMemoryManager.cpp | 3 + Core/Video/Display.cpp | 236 +++++++++--------- Core/Video/Font.cpp | 16 +- Kernel.cpp | 20 +- SystemCalls/Native.cpp | 21 +- include/display.hpp | 12 +- include/smp.hpp | 2 +- 15 files changed, 378 insertions(+), 326 deletions(-) diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp index e492f9e..a217ea8 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp @@ -8,72 +8,95 @@ namespace GlobalDescriptorTable { static GlobalDescriptorTableEntries GDTEntriesTemplate = { - // null - {.Length = 0x0, - .BaseLow = 0x0, - .BaseMiddle = 0x0, - .Access = {.Raw = 0x0}, - .Flags = {.Raw = 0x0}, - .BaseHigh = 0x0}, + .Null = + { + .Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.Raw = 0x0}, + .Flags = {.Raw = 0x0}, + .BaseHigh = 0x0, + }, - // kernel code - {.Length = 0x0, - .BaseLow = 0x0, - .BaseMiddle = 0x0, - .Access = {.A = 0, + .Code = + { + .Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = { + .A = 0, .RW = 1, .DC = 0, .E = 1, .S = 1, .DPL = 0, - .P = 1}, - .Flags = {.Unknown = 0x0, .L = 1}, - .BaseHigh = 0x0}, + .P = 1, + }, + .Flags = { + .Unknown = 0x0, + .L = 1, + }, + .BaseHigh = 0x0, + }, - // kernel data - {.Length = 0x0, - .BaseLow = 0x0, - .BaseMiddle = 0x0, - .Access = {.A = 0, - .RW = 1, - .DC = 0, - .E = 0, - .S = 1, - .DPL = 0, - .P = 1}, - .Flags = {.Raw = 0x0}, - .BaseHigh = 0x0}, + .Data = { + .Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = { + .A = 0, + .RW = 1, + .DC = 0, + .E = 0, + .S = 1, + .DPL = 0, + .P = 1, + }, + .Flags = {.Raw = 0x0}, + .BaseHigh = 0x0, + }, - // user data - {.Length = 0x0, - .BaseLow = 0x0, - .BaseMiddle = 0x0, - .Access = {.A = 0, - .RW = 1, - .DC = 0, - .E = 0, - .S = 1, - .DPL = 3, - .P = 1}, - .Flags = {.Raw = 0x0}, - .BaseHigh = 0x0}, + .UserData = { + .Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = { + .A = 0, + .RW = 1, + .DC = 0, + .E = 0, + .S = 1, + .DPL = 3, + .P = 1, + }, + .Flags = { + .Raw = 0x0, + }, + .BaseHigh = 0x0, + }, - // user code - {.Length = 0x0, - .BaseLow = 0x0, - .BaseMiddle = 0x0, - .Access = {.A = 0, - .RW = 1, - .DC = 0, - .E = 1, - .S = 1, - .DPL = 3, - .P = 1}, - .Flags = {.Unknown = 0x0, .L = 1}, - .BaseHigh = 0x0}, + .UserCode = { + .Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = { + .A = 0, + .RW = 1, + .DC = 0, + .E = 1, + .S = 1, + .DPL = 3, + .P = 1, + }, + .Flags = { + .Unknown = 0x0, + .L = 1, + }, + .BaseHigh = 0x0, + }, - // tss - {}}; + .TaskStateSegment = {}, + }; GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; GlobalDescriptorTableDescriptor gdt[MAX_CPU]; @@ -155,7 +178,12 @@ namespace GlobalDescriptorTable else tss[CPUID].StackPointer[0] = (uint64_t)CPUStackPointer[CPUID] + STACK_SIZE; - // TODO: This may cause problems in the future I guess? This should be checked later + /* + FIXME: There's a bug in kernel which if + we won't update "tss[CPUID].StackPointer[0]" + with the current stack pointer, the kernel + will crash. + */ asmv("mov %%rsp, %0" : "=r"(tss[CPUID].StackPointer[0])); } diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp index e14f2ab..79787b0 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp @@ -14,8 +14,10 @@ namespace InterruptDescriptorTable { static InterruptDescriptorTableEntry Entries[0x100]; - InterruptDescriptorTableDescriptor idtd = {.Length = sizeof(Entries) - 1, - .Entries = Entries}; + InterruptDescriptorTableDescriptor idtd = { + .Length = sizeof(Entries) - 1, + .Entries = Entries, + }; void SetEntry(uint8_t Index, void (*Base)(), @@ -36,19 +38,10 @@ namespace InterruptDescriptorTable Entries[Index].Present = 1; } - extern "C" __attribute__((naked, used, no_stack_protector)) void ExceptionHandlerStub() + extern "C" __naked __used __no_stack_protector void ExceptionHandlerStub() { - asm( - // "cmp $0x1000, %rsp\n" // Just in case the stack is corrupted - // "jng .skip_swap_check_1\n" /* if is not greater than */ - // "cmpw $0x8, 0x8(%rsp)\n" - // "je .skip_swap_check_1\n" - // "swapgs\n" - // ".skip_swap_check_1:\n" + asm("cld\n" - "cld\n" // clear direction flag - - // push all registers "pushq %rax\n" "pushq %rbx\n" "pushq %rcx\n" @@ -68,7 +61,6 @@ namespace InterruptDescriptorTable "movq %rsp, %rdi\n" "call ExceptionHandler\n" - // pop all registers "popq %r15\n" "popq %r14\n" "popq %r13\n" @@ -87,44 +79,13 @@ namespace InterruptDescriptorTable "addq $16, %rsp\n" - // "cmp $0x1000, %rsp\n" - // "jng .skip_swap_check_2\n" - // "cmpw $0x8, 0x8(%rsp)\n" - // "je .skip_swap_check_2\n" - // "swapgs\n" - // ".skip_swap_check_2:\n" - "iretq"); // pop CS RIP RFLAGS SS RSP } - extern "C" void WarnSwapgs() { warn("swapgs"); } - - // void *OriginalCR3; - extern "C" __attribute__((naked, used, no_stack_protector)) void InterruptHandlerStub() + extern "C" __naked __used __no_stack_protector void InterruptHandlerStub() { - // // Store cr3 to OriginalCR3 - // asmv("mov %%cr3, %0" - // : "=q"(OriginalCR3) - // : - // : "memory"); - // // Set cr3 to KPT (Kernel Page Table) - // asmv("mov %0, %%cr3" - // : - // : "q"(KPT) - // : "memory"); + asm("cld\n" - // GlobalDescriptorTable::SetKernelStack(nullptr); - - asm( - // "cmp $0x1000, %rsp\n" - // "jng .skip_swap_check__1\n" - // "cmpw $0x8, 0x8(%rsp)\n" - // "je .skip_swap_check__1\n" - // "swapgs\n" - // "call WarnSwapgs\n" - // ".skip_swap_check__1:\n" - - "cld\n" "pushq %rax\n" "pushq %rbx\n" "pushq %rcx\n" @@ -142,28 +103,9 @@ namespace InterruptDescriptorTable "pushq %r15\n" "movq %rsp, %rdi\n" - "call MainInterruptHandler\n"); + "call MainInterruptHandler\n" - // // Check if the current cr3 is the same as the KPT - // // If not, then we need to restore the cr3 - // asmv("pushq %rax\n" // push rax - // "pushq %rbx\n" // push rbx - // "movq %cr3, %rbx\n"); // mov cr3 to rbx - // asmv("movq %0, %%rax\n" // mov KPT to rax - // : - // : "q"(KPT) - // : "memory"); - // asmv("cmpq %rax, %rbx\n" // compare cr3 to rax - // "jne .skip_restore_cr3\n"); // if not equal, skip restore cr3 - // asmv("movq %0, %%cr3\n" // restore cr3 - // : - // : "q"(OriginalCR3) - // : "memory"); - // asm(".skip_restore_cr3:\n" // skip restore cr3 label - // "popq %rax\n" // KPT - // "popq %rbx\n"); // cr3 - - asm("popq %r15\n" + "popq %r15\n" "popq %r14\n" "popq %r13\n" "popq %r12\n" @@ -181,38 +123,30 @@ namespace InterruptDescriptorTable "addq $16, %rsp\n" - // "cmp $0x1000, %rsp\n" - // "jng .skip_swap_check__2\n" - // "cmpw $0x8, 0x8(%rsp)\n" - // "je .skip_swap_check__2\n" - // "call WarnSwapgs\n" - // "swapgs\n" - // ".skip_swap_check__2:\n" - - "iretq"); + "iretq"); // pop CS RIP RFLAGS SS RSP } #pragma region Exceptions -#define EXCEPTION_HANDLER(num) \ - __attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ - { \ - asm("pushq $0\npushq $" #num "\n" \ - "jmp ExceptionHandlerStub"); \ +#define EXCEPTION_HANDLER(num) \ + __naked __used __no_stack_protector static void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ } -#define EXCEPTION_ERROR_HANDLER(num) \ - __attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ - { \ - asm("pushq $" #num "\n" \ - "jmp ExceptionHandlerStub"); \ +#define EXCEPTION_ERROR_HANDLER(num) \ + __naked __used __no_stack_protector static void InterruptHandler_##num() \ + { \ + asm("pushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ } -#define INTERRUPT_HANDLER(num) \ - __attribute__((naked, used, no_stack_protector)) void InterruptHandler_##num() \ - { \ - asm("pushq $0\npushq $" #num "\n" \ - "jmp InterruptHandlerStub\n"); \ +#define INTERRUPT_HANDLER(num) \ + __naked __used __no_stack_protector void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp InterruptHandlerStub\n"); \ } /* ISR */ @@ -487,9 +421,7 @@ namespace InterruptDescriptorTable void Init(int Core) { - UNUSED(Core); - static int once = 0; - if (!once++) + if (Core == 0) /* Disable PIC using BSP */ { // PIC outb(0x20, 0x10 | 0x1); diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp index 0bcbdc0..3b7f8bd 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp @@ -25,7 +25,7 @@ enum SMPTrampolineAddress volatile bool CPUEnabled = false; #pragma GCC diagnostic ignored "-Wmissing-field-initializers" -static __attribute__((aligned(PAGE_SIZE))) CPUData CPUs[MAX_CPU] = {0}; +static __aligned(PAGE_SIZE) CPUData CPUs[MAX_CPU] = {0}; SafeFunction CPUData *GetCPU(long id) { return &CPUs[id]; } @@ -33,6 +33,7 @@ SafeFunction CPUData *GetCurrentCPU() { if (unlikely(!Interrupts::apic[0])) return &CPUs[0]; /* No APIC means we are on the BSP. */ + int CoreID = ((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24; if (unlikely((&CPUs[CoreID])->IsActive != true)) diff --git a/Core/InterruptsManager.cpp b/Core/InterruptsManager.cpp index 5fc8487..7967e41 100644 --- a/Core/InterruptsManager.cpp +++ b/Core/InterruptsManager.cpp @@ -58,7 +58,8 @@ namespace Interrupts CPU::Stop(); } debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE); - asmv("movq %0, %%rsp" ::"r"(CoreData->Stack)); + /* TODO: Implement a proper way to set the stack pointer. */ + // asmv("movq %0, %%rsp" ::"r"(CoreData->Stack)); InitializeSystemCalls(); #elif defined(a32) warn("i386 is not supported yet"); diff --git a/Core/Lock.cpp b/Core/Lock.cpp index 0073ccc..ba1bf04 100644 --- a/Core/Lock.cpp +++ b/Core/Lock.cpp @@ -50,33 +50,38 @@ int LockClass::Lock(const char *FunctionName) { LockData.AttemptingToGet = FunctionName; LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0); + Retry: - unsigned int i = 0; + int i = 0; while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000)) CPU::Pause(); + if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000)) { DeadLock(LockData); goto Retry; } + LockData.Count++; LockData.CurrentHolder = FunctionName; LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0); + CPUData *CoreData = GetCurrentCPU(); if (CoreData != nullptr) LockData.Core = CoreData->ID; - LocksCount++; - __sync; + LocksCount++; + + __sync; return 0; } int LockClass::Unlock() { __sync; + IsLocked.Store(false, MemoryOrder::Release); LockData.Count--; - IsLocked = false; LocksCount--; return 0; @@ -86,6 +91,7 @@ void LockClass::TimeoutDeadLock(SpinLockData Lock, uint64_t Timeout) { CPUData *CoreData = GetCurrentCPU(); long CCore = 0xdead; + if (CoreData != nullptr) CCore = CoreData->ID; @@ -111,13 +117,16 @@ int LockClass::TimeoutLock(const char *FunctionName, uint64_t Timeout) { if (!TimeManager) return Lock(FunctionName); + LockData.AttemptingToGet = FunctionName; LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0); + Atomic Target = 0; Retry: - unsigned int i = 0; + int i = 0; while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000)) CPU::Pause(); + if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000)) { if (Target.Load() == 0) @@ -125,14 +134,17 @@ Retry: TimeoutDeadLock(LockData, Target.Load()); goto Retry; } + LockData.Count++; LockData.CurrentHolder = FunctionName; LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0); + CPUData *CoreData = GetCurrentCPU(); if (CoreData != nullptr) LockData.Core = CoreData->ID; - LocksCount++; - __sync; + LocksCount++; + + __sync; return 0; } diff --git a/Core/Memory/MemoryManager.cpp b/Core/Memory/MemoryManager.cpp index 7d355c2..d2e1226 100644 --- a/Core/Memory/MemoryManager.cpp +++ b/Core/Memory/MemoryManager.cpp @@ -107,6 +107,7 @@ namespace Memory int Flags = Memory::PTFlag::RW; if (User) Flags |= Memory::PTFlag::US; + Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Flags); } @@ -125,16 +126,18 @@ namespace Memory AllocatedPagesList.push_back({Address, Count}); - /* For security reasons, we clear the memory - if the page is user accessible. */ + /* For security reasons, we clear the allocated page + if it's a user page. */ if (User) memset(Address, 0, Count * PAGE_SIZE); + return Address; } void MemMgr::FreePages(void *Address, size_t Count) { for (size_t i = 0; i < AllocatedPagesList.size(); i++) + { if (AllocatedPagesList[i].Address == Address) { /** TODO: Advanced checks. Allow if the page count is less than the requested one. @@ -150,9 +153,12 @@ namespace Memory } KernelAllocator.FreePages(Address, Count); + for (size_t i = 0; i < Count; i++) + { Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Memory::PTFlag::RW); - // Memory::Virtual(this->PageTable).Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); + // Memory::Virtual(this->PageTable).Unmap((void *)((uintptr_t)Address + (i * PAGE_SIZE))); + } if (this->Directory) { @@ -166,11 +172,13 @@ namespace Memory AllocatedPagesList.remove(i); return; } + } } void MemMgr::DetachAddress(void *Address) { for (size_t i = 0; i < AllocatedPagesList.size(); i++) + { if (AllocatedPagesList[i].Address == Address) { if (this->Directory) @@ -185,6 +193,7 @@ namespace Memory AllocatedPagesList.remove(i); return; } + } } MemMgr::MemMgr(PageTable4 *PageTable, VirtualFileSystem::Node *Directory) @@ -192,11 +201,13 @@ namespace Memory if (PageTable) this->PageTable = PageTable; else + { #if defined(a64) this->PageTable = (PageTable4 *)CPU::x64::readcr3().raw; #elif defined(a32) this->PageTable = (PageTable4 *)CPU::x32::readcr3().raw; #endif + } this->Directory = Directory; debug("+ %#lx", this); @@ -212,8 +223,10 @@ namespace Memory } if (this->Directory) + { foreach (auto Child in this->Directory->Children) vfs->Delete(Child, true); + } debug("- %#lx", this); } diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index 2455824..c41fe02 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -42,8 +42,10 @@ namespace Memory bool Physical::SwapPages(void *Address, size_t PageCount) { for (size_t i = 0; i < PageCount; i++) + { if (!this->SwapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE)))) return false; + } return false; } @@ -56,20 +58,23 @@ namespace Memory bool Physical::UnswapPages(void *Address, size_t PageCount) { for (size_t i = 0; i < PageCount; i++) + { if (!this->UnswapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE)))) return false; + } return false; } void *Physical::RequestPage() { SmartLock(this->MemoryLock); + for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) { if (PageBitmap[PageBitmapIndex] == true) continue; - this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE)); + this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE)); #ifdef DEBUG if (EnableExternalMemoryTracer) { @@ -106,6 +111,7 @@ namespace Memory void *Physical::RequestPages(size_t Count) { SmartLock(this->MemoryLock); + for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) { if (PageBitmap[PageBitmapIndex] == true) @@ -117,8 +123,10 @@ namespace Memory continue; for (size_t i = 0; i < Count; i++) + { if (PageBitmap[Index + i] == true) goto NextPage; + } this->LockPages((void *)(Index * PAGE_SIZE), Count); #ifdef DEBUG @@ -152,26 +160,6 @@ namespace Memory if (this->SwapPages((void *)(PageBitmapIndex * PAGE_SIZE), Count)) { this->LockPages((void *)(PageBitmapIndex * PAGE_SIZE), Count); -#ifdef DEBUG - if (EnableExternalMemoryTracer) - { - char LockTmpStr[64]; - strcpy_unsafe(LockTmpStr, __FUNCTION__); - strcat_unsafe(LockTmpStr, "_memTrk"); - mExtTrkLock.TimeoutLock(LockTmpStr, 10000); - sprintf(mExtTrkLog, "RequestPages( %ld )=%p~%p\n\r", - Count, - (void *)(PageBitmapIndex * PAGE_SIZE), __builtin_return_address(0)); - UniversalAsynchronousReceiverTransmitter::UART mTrkUART = UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM3); - for (short i = 0; i < MEM_TRK_MAX_SIZE; i++) - { - if (mExtTrkLog[i] == '\r') - break; - mTrkUART.Write(mExtTrkLog[i]); - } - mExtTrkLock.Unlock(); - } -#endif return (void *)(PageBitmapIndex * PAGE_SIZE); } @@ -183,12 +171,15 @@ namespace Memory void Physical::FreePage(void *Address) { SmartLock(this->MemoryLock); + if (unlikely(Address == nullptr)) { warn("Null pointer passed to FreePage."); return; } + size_t Index = (size_t)Address / PAGE_SIZE; + if (unlikely(PageBitmap[Index] == false)) { warn("Tried to free an already free page. (%p)", Address); @@ -262,8 +253,10 @@ namespace Memory warn("Trying to lock null address."); uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; + if (unlikely(PageBitmap[Index] == true)) return; + if (PageBitmap.Set(Index, true)) { FreeMemory -= PAGE_SIZE; @@ -286,6 +279,7 @@ namespace Memory warn("Trying to reserve null address."); uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; + if (unlikely(PageBitmap[Index] == true)) return; @@ -311,6 +305,7 @@ namespace Memory warn("Trying to unreserve null address."); uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; + if (unlikely(PageBitmap[Index] == false)) return; @@ -335,25 +330,33 @@ namespace Memory void Physical::Init(BootInfo *Info) { SmartLock(this->MemoryLock); + + uint64_t MemorySize = Info->Memory.Size; + TotalMemory = MemorySize; + FreeMemory = MemorySize; + void *LargestFreeMemorySegment = nullptr; uint64_t LargestFreeMemorySegmentSize = 0; - uint64_t MemorySize = Info->Memory.Size; for (uint64_t i = 0; i < Info->Memory.Entries; i++) + { if (Info->Memory.Entry[i].Type == Usable) + { if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize) { - // We don't want to use 0 as a memory address. - if (Info->Memory.Entry[i].BaseAddress == nullptr) + /* We don't want to use 0 as a memory address. */ + if (Info->Memory.Entry[i].BaseAddress == 0x0) continue; + LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; + debug("Largest free memory segment: %llp (%lldMB)", (void *)Info->Memory.Entry[i].BaseAddress, TO_MB(Info->Memory.Entry[i].Length)); } - TotalMemory = MemorySize; - FreeMemory = MemorySize; + } + } if (LargestFreeMemorySegment == nullptr) { @@ -366,6 +369,7 @@ namespace Memory LargestFreeMemorySegment, (void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize), BitmapSize); + PageBitmap.Size = BitmapSize; PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment; for (size_t i = 0; i < BitmapSize; i++) @@ -373,8 +377,11 @@ namespace Memory trace("Reserving pages..."); for (uint64_t i = 0; i < Info->Memory.Entries; i++) + { if (Info->Memory.Entry[i].Type != Usable) this->ReservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1); + } + trace("Locking bitmap pages..."); this->ReservePages(0, 0x100); this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1); diff --git a/Core/Memory/StackGuard.cpp b/Core/Memory/StackGuard.cpp index 507aada..5c71aac 100644 --- a/Core/Memory/StackGuard.cpp +++ b/Core/Memory/StackGuard.cpp @@ -8,35 +8,45 @@ namespace Memory { this->UserMode = User; this->Table = Table; + if (this->UserMode) { void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE)); - debug("AllocatedStack: %p", AllocatedStack); memset(AllocatedStack, 0, USER_STACK_SIZE); + debug("AllocatedStack: %p", AllocatedStack); + for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) { Virtual(Table).Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), PTFlag::RW | PTFlag::US); + debug("Mapped %p to %p", (void *)(USER_STACK_BASE + (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE))); } + this->StackBottom = (void *)USER_STACK_BASE; this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); + this->StackPhyiscalBottom = AllocatedStack; this->StackPhyiscalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); + this->Size = USER_STACK_SIZE; } else { this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); - this->StackPhyiscalBottom = this->StackBottom; - debug("StackBottom: %p", this->StackBottom); memset(this->StackBottom, 0, STACK_SIZE); + debug("StackBottom: %p", this->StackBottom); + this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); + + this->StackPhyiscalBottom = this->StackBottom; this->StackPhyiscalTop = this->StackTop; + this->Size = STACK_SIZE; } + trace("Allocated stack at %p", this->StackBottom); } @@ -54,7 +64,7 @@ namespace Memory if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE || FaultAddress > (uintptr_t)this->StackTop) { - return false; // It's not about the stack. + return false; /* It's not about the stack. */ } else { @@ -77,7 +87,5 @@ namespace Memory fixme("Not implemented and probably not needed"); return false; } - error("Reached end of function! How?"); - return false; } } diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index 5e031c2..904be28 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -155,6 +155,7 @@ namespace Memory error("Page %#lx not present", PML4.GetAddress()); return; } + PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.Address << 12); PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex]; if (!PDPTE.Present) @@ -162,6 +163,7 @@ namespace Memory error("Page %#lx not present", PDPTE.GetAddress()); return; } + PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12); PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex]; if (!PDE.Present) @@ -169,6 +171,7 @@ namespace Memory error("Page %#lx not present", PDE.GetAddress()); return; } + PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12); PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; if (!PTE.Present) diff --git a/Core/Video/Display.cpp b/Core/Video/Display.cpp index 595c8b1..332aa33 100644 --- a/Core/Video/Display.cpp +++ b/Core/Video/Display.cpp @@ -11,84 +11,79 @@ NewLock(PrintLock); namespace Video { - Font *Display::GetCurrentFont() - { - return CurrentFont; - } - - void Display::SetCurrentFont(Font *Font) - { - CurrentFont = Font; - } + Font *Display::GetCurrentFont() { return CurrentFont; } + void Display::SetCurrentFont(Font *Font) { CurrentFont = Font; } + uint16_t Display::GetBitsPerPixel() { return this->framebuffer.BitsPerPixel; } + uint64_t Display::GetPitch() { return this->framebuffer.Pitch; } void Display::CreateBuffer(uint32_t Width, uint32_t Height, int Index) { - if (Width == 0 && Height == 0) + if (Width == 0 || Height == 0) { Width = this->framebuffer.Width; Height = this->framebuffer.Height; - debug("No width and height specified, using %ldx%lld", Width, Height); + debug("Buffer %d created with default size (%d, %d)", Index, Width, Height); + } + + if (this->Buffers[Index].Checksum == 0xDEAD) + { + warn("Buffer %d already exists, skipping creation", Index); + return; } size_t Size = this->framebuffer.Pitch * Height; - if (this->Buffers[Index]) - { - if (this->Buffers[Index]->Checksum == 0xDEAD) - { - warn("Buffer %d already exists, skipping creation", Index); - return; - } - } - ScreenBuffer *buffer = new ScreenBuffer; - buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); - buffer->Width = Width; - buffer->Height = Height; - buffer->Size = Size; - buffer->Color = 0xFFFFFF; - buffer->CursorX = 0; - buffer->CursorY = 0; - buffer->Brightness = 100; - this->Buffers[Index] = buffer; - memset(this->Buffers[Index]->Buffer, 0, Size); - this->Buffers[Index]->Checksum = 0xDEAD; - debug("Created buffer %d, address %#lx", Index, buffer); + this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); + memset(this->Buffers[Index].Buffer, 0, Size); + + this->Buffers[Index].Width = Width; + this->Buffers[Index].Height = Height; + this->Buffers[Index].Size = Size; + this->Buffers[Index].Color = 0xFFFFFF; + this->Buffers[Index].CursorX = 0; + this->Buffers[Index].CursorY = 0; + this->Buffers[Index].Brightness = 100; + this->Buffers[Index].Checksum = 0xDEAD; + debug("Buffer %d created", Index); } void Display::SetBuffer(int Index) { - if (this->Buffers[Index]->Brightness != 100) - this->SetBrightness(this->Buffers[Index]->Brightness, Index); + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; - if (this->Buffers[Index]->Brightness == 0) /* Just clear the buffer */ - memset(this->Buffers[Index]->Buffer, 0, this->Buffers[Index]->Size); + if (this->Buffers[Index].Brightness != 100) + this->SetBrightness(this->Buffers[Index].Brightness, Index); - memcpy(this->framebuffer.BaseAddress, this->Buffers[Index]->Buffer, this->Buffers[Index]->Size); + if (this->Buffers[Index].Brightness == 0) /* Just clear the buffer */ + memset(this->Buffers[Index].Buffer, 0, this->Buffers[Index].Size); + + memcpy(this->framebuffer.BaseAddress, this->Buffers[Index].Buffer, this->Buffers[Index].Size); } - ScreenBuffer *Display::GetBuffer(int Index) - { - return this->Buffers[Index]; - } + ScreenBuffer *Display::GetBuffer(int Index) { return &this->Buffers[Index]; } void Display::ClearBuffer(int Index) { - memset(this->Buffers[Index]->Buffer, 0, this->Buffers[Index]->Size); + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + + memset(this->Buffers[Index].Buffer, 0, this->Buffers[Index].Size); } void Display::DeleteBuffer(int Index) { - if (this->Buffers[Index] == nullptr) + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) return; - KernelAllocator.FreePages(this->Buffers[Index]->Buffer, TO_PAGES(this->Buffers[Index]->Size)); - this->Buffers[Index]->Buffer = nullptr; - this->Buffers[Index]->Checksum = 0; // Making sure that the buffer is not used anymore - delete this->Buffers[Index], this->Buffers[Index] = nullptr; + + KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size)); + this->Buffers[Index].Buffer = nullptr; + this->Buffers[Index].Checksum = 0; } void Display::SetBrightness(int Value, int Index) { - if (this->Buffers[Index] == nullptr) + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) return; if (Value > 100) @@ -96,14 +91,13 @@ namespace Video else if (Value < 0) Value = 0; - ScreenBuffer *buffer = this->Buffers[Index]; - uint32_t *pixel = (uint32_t *)buffer->Buffer; + uint32_t *pixel = (uint32_t *)this->Buffers[Index].Buffer; - for (uint32_t y = 0; y < buffer->Height; y++) + for (uint32_t y = 0; y < this->Buffers[Index].Height; y++) { - for (uint32_t x = 0; x < buffer->Width; x++) + for (uint32_t x = 0; x < this->Buffers[Index].Width; x++) { - uint32_t color = pixel[y * buffer->Width + x]; + uint32_t color = pixel[y * this->Buffers[Index].Width + x]; uint8_t r = color & 0xff; uint8_t g = (color >> 8) & 0xff; @@ -113,82 +107,93 @@ namespace Video g = (g * Value) / 100; b = (b * Value) / 100; - pixel[y * buffer->Width + x] = (b << 16) | (g << 8) | r; + pixel[y * this->Buffers[Index].Width + x] = (b << 16) | (g << 8) | r; } } - buffer->Brightness = Value; + this->Buffers[Index].Brightness = Value; } void Display::SetBufferCursor(int Index, uint32_t X, uint32_t Y) { - this->Buffers[Index]->CursorX = X; - this->Buffers[Index]->CursorY = Y; + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + + this->Buffers[Index].CursorX = X; + this->Buffers[Index].CursorY = Y; } void Display::GetBufferCursor(int Index, uint32_t *X, uint32_t *Y) { - *X = this->Buffers[Index]->CursorX; - *Y = this->Buffers[Index]->CursorY; + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + + *X = this->Buffers[Index].CursorX; + *Y = this->Buffers[Index].CursorY; } void Display::SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index) { - if (unlikely(X >= this->Buffers[Index]->Width)) - X = this->Buffers[Index]->Width - 1; - if (unlikely(Y >= this->Buffers[Index]->Height)) - Y = this->Buffers[Index]->Height - 1; - uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)); + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + + if (unlikely(X >= this->Buffers[Index].Width)) + X = this->Buffers[Index].Width - 1; + + if (unlikely(Y >= this->Buffers[Index].Height)) + Y = this->Buffers[Index].Height - 1; + + uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)); *Pixel = Color; } uint32_t Display::GetPixel(uint32_t X, uint32_t Y, int Index) { - if (unlikely(X >= this->Buffers[Index]->Width || Y >= this->Buffers[Index]->Height)) + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) return 0; - uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)); + + if (unlikely(X >= this->Buffers[Index].Width || Y >= this->Buffers[Index].Height)) + return 0; + + uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)); return *Pixel; } - uint16_t Display::GetBitsPerPixel() - { - return this->framebuffer.BitsPerPixel; - } - - uint64_t Display::GetPitch() - { - return this->framebuffer.Pitch; - } - void Display::Scroll(int Index, int Lines) { + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + if (Lines == 0) return; if (Lines > 0) { - uint32_t LineSize = this->Buffers[Index]->Width * (this->framebuffer.BitsPerPixel / 8); + uint32_t LineSize = this->Buffers[Index].Width * (this->framebuffer.BitsPerPixel / 8); uint32_t BytesToMove = LineSize * Lines * this->CurrentFont->GetInfo().Height; - uint32_t BytesToClear = this->Buffers[Index]->Size - BytesToMove; - memmove(this->Buffers[Index]->Buffer, (uint8_t *)this->Buffers[Index]->Buffer + BytesToMove, BytesToClear); - memset((uint8_t *)this->Buffers[Index]->Buffer + BytesToClear, 0, BytesToMove); + uint32_t BytesToClear = this->Buffers[Index].Size - BytesToMove; + memmove(this->Buffers[Index].Buffer, (uint8_t *)this->Buffers[Index].Buffer + BytesToMove, BytesToClear); + memset((uint8_t *)this->Buffers[Index].Buffer + BytesToClear, 0, BytesToMove); } } char Display::Print(char Char, int Index, bool WriteToUART) { + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return 0; + // SmartLock(PrintLock); if (this->ColorIteration) { // RRGGBB if (Char >= '0' && Char <= '9') - this->Buffers[Index]->Color = (this->Buffers[Index]->Color << 4) | (Char - '0'); + this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - '0'); else if (Char >= 'a' && Char <= 'f') - this->Buffers[Index]->Color = (this->Buffers[Index]->Color << 4) | (Char - 'a' + 10); + this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - 'a' + 10); else if (Char >= 'A' && Char <= 'F') - this->Buffers[Index]->Color = (this->Buffers[Index]->Color << 4) | (Char - 'A' + 10); + this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - 'A' + 10); else - this->Buffers[Index]->Color = 0xFFFFFF; + this->Buffers[Index].Color = 0xFFFFFF; if (WriteToUART) UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(Char); this->ColorPickerIteration++; @@ -228,10 +233,10 @@ namespace Video uint32_t fonthdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; uint32_t fonthdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; - for (unsigned long Y = this->Buffers[Index]->CursorY; Y < this->Buffers[Index]->CursorY + fonthdrHeight; Y++) - for (unsigned long X = this->Buffers[Index]->CursorX - fonthdrWidth; X < this->Buffers[Index]->CursorX; X++) - *(uint32_t *)((uintptr_t)this->Buffers[Index]->Buffer + - (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; + for (unsigned long Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + fonthdrHeight; Y++) + for (unsigned long X = this->Buffers[Index].CursorX - fonthdrWidth; X < this->Buffers[Index].CursorX; X++) + *(uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; break; } default: @@ -239,40 +244,40 @@ namespace Video break; } - if (this->Buffers[Index]->CursorX > 0) - this->Buffers[Index]->CursorX -= this->GetCurrentFont()->GetInfo().Width; + if (this->Buffers[Index].CursorX > 0) + this->Buffers[Index].CursorX -= this->GetCurrentFont()->GetInfo().Width; return Char; } case '\t': { - this->Buffers[Index]->CursorX = (this->Buffers[Index]->CursorX + 8) & ~(8 - 1); + this->Buffers[Index].CursorX = (this->Buffers[Index].CursorX + 8) & ~(8 - 1); return Char; } case '\r': { - this->Buffers[Index]->CursorX = 0; + this->Buffers[Index].CursorX = 0; return Char; } case '\n': { - this->Buffers[Index]->CursorX = 0; - this->Buffers[Index]->CursorY += this->GetCurrentFont()->GetInfo().Height; + this->Buffers[Index].CursorX = 0; + this->Buffers[Index].CursorY += this->GetCurrentFont()->GetInfo().Height; return Char; } } uint32_t FontHeight = this->GetCurrentFont()->GetInfo().Height; - if (this->Buffers[Index]->CursorX + this->GetCurrentFont()->GetInfo().Width >= this->Buffers[Index]->Width) + if (this->Buffers[Index].CursorX + this->GetCurrentFont()->GetInfo().Width >= this->Buffers[Index].Width) { - this->Buffers[Index]->CursorX = 0; - this->Buffers[Index]->CursorY += FontHeight; + this->Buffers[Index].CursorX = 0; + this->Buffers[Index].CursorY += FontHeight; } - if (this->Buffers[Index]->CursorY + FontHeight >= this->Buffers[Index]->Height) + if (this->Buffers[Index].CursorY + FontHeight >= this->Buffers[Index].Height) { - this->Buffers[Index]->CursorY -= FontHeight; + this->Buffers[Index].CursorY -= FontHeight; this->Scroll(Index, 1); } @@ -280,16 +285,16 @@ namespace Video { case FontType::PCScreenFont1: { - uint32_t *PixelPtr = (uint32_t *)this->Buffers[Index]->Buffer; + uint32_t *PixelPtr = (uint32_t *)this->Buffers[Index].Buffer; char *FontPtr = (char *)this->CurrentFont->GetInfo().PSF1Font->GlyphBuffer + (Char * this->CurrentFont->GetInfo().PSF1Font->Header->charsize); - for (uint64_t Y = this->Buffers[Index]->CursorY; Y < this->Buffers[Index]->CursorY + 16; Y++) + for (uint64_t Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + 16; Y++) { - for (uint64_t X = this->Buffers[Index]->CursorX; X < this->Buffers[Index]->CursorX + 8; X++) - if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index]->CursorX))) > 0) - *(unsigned int *)(PixelPtr + X + (Y * this->Buffers[Index]->Width)) = this->Buffers[Index]->Color; + for (uint64_t X = this->Buffers[Index].CursorX; X < this->Buffers[Index].CursorX + 8; X++) + if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index].CursorX))) > 0) + *(unsigned int *)(PixelPtr + X + (Y * this->Buffers[Index].Width)) = this->Buffers[Index].Color; FontPtr++; } - this->Buffers[Index]->CursorX += 8; + this->Buffers[Index].CursorX += 8; break; } @@ -307,21 +312,21 @@ namespace Video uint32_t FontHdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; uint32_t FontHdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; - for (size_t Y = this->Buffers[Index]->CursorY; Y < this->Buffers[Index]->CursorY + FontHdrHeight; Y++) + for (size_t Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + FontHdrHeight; Y++) { - for (size_t X = this->Buffers[Index]->CursorX; X < this->Buffers[Index]->CursorX + FontHdrWidth; X++) + for (size_t X = this->Buffers[Index].CursorX; X < this->Buffers[Index].CursorX + FontHdrWidth; X++) { - if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index]->CursorX))) > 0) + if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index].CursorX))) > 0) { - void *FramebufferAddress = (void *)((uintptr_t)this->Buffers[Index]->Buffer + - (Y * this->Buffers[Index]->Width + X) * + void *FramebufferAddress = (void *)((uintptr_t)this->Buffers[Index].Buffer + + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)); - *(uint32_t *)FramebufferAddress = this->Buffers[Index]->Color; + *(uint32_t *)FramebufferAddress = this->Buffers[Index].Color; } } FontPtr += BytesPerLine; } - this->Buffers[Index]->CursorX += FontHdrWidth; + this->Buffers[Index].CursorX += FontHdrWidth; break; } default: @@ -333,8 +338,11 @@ namespace Video void Display::DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART) { - this->Buffers[Index]->CursorX = X; - this->Buffers[Index]->CursorY = Y; + if (unlikely(this->Buffers[Index].Checksum != 0xDEAD)) + return; + + this->Buffers[Index].CursorX = X; + this->Buffers[Index].CursorY = Y; for (int i = 0; String[i] != '\0'; i++) this->Print(String[i], Index, WriteToUART); diff --git a/Core/Video/Font.cpp b/Core/Video/Font.cpp index 2097fae..7c91b0f 100644 --- a/Core/Video/Font.cpp +++ b/Core/Video/Font.cpp @@ -10,23 +10,29 @@ namespace Video this->Info.StartAddress = Start; this->Info.EndAddress = End; this->Info.Type = Type; + size_t FontDataLength = End - Start; + if (Type == FontType::PCScreenFont2) { this->Info.PSF2Font = new PSF2_FONT; - uintptr_t FontDataLength = End - Start; PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1); - for (uintptr_t i = 0; i < FontDataLength / PAGE_SIZE + 1; i++) - Memory::Virtual().Map((void *)(font2 + (i * PAGE_SIZE)), (void *)(font2 + (i * PAGE_SIZE)), Memory::PTFlag::RW); memcpy((void *)font2, Start, FontDataLength); - this->Info.Width = font2->width; - this->Info.Height = font2->height; + for (uintptr_t i = 0; i < FontDataLength / PAGE_SIZE + 1; i++) + Memory::Virtual().Map((void *)(font2 + (i * PAGE_SIZE)), (void *)(font2 + (i * PAGE_SIZE)), Memory::PTFlag::RW); + if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3) + { error("Font2 magic mismatch."); + KernelAllocator.FreePages((void *)font2, FontDataLength / PAGE_SIZE + 1); + return; + } this->Info.PSF2Font->Header = font2; this->Info.PSF2Font->GlyphBuffer = reinterpret_cast(reinterpret_cast(Start) + sizeof(PSF2_HEADER)); + this->Info.Width = font2->width; + this->Info.Height = font2->height; } else if (Type == FontType::PCScreenFont1) { diff --git a/Kernel.cpp b/Kernel.cpp index 5dfba68..1d1a29f 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -48,11 +48,14 @@ LockClass mExtTrkLock; * - [?] Rewrite virtual file system. (it's very bad, I don't know how I wrote it this bad) * - [ ] Colors in crash screen are not following the kernel color scheme. * - [ ] Find a way to add intrinsics. + * - [ ] Rework PSF1 font loader. * * ISSUES: * - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) - * - [ ] After setting the new stack pointer, the kernel crashes with an invalid opcode. + * - [?] After setting the new stack pointer, the kernel crashes with an invalid opcode. * - [ ] Somewhere in the kernel, the memory is wrongly freed or memcpy/memset. + * - [ ] GlobalDescriptorTable::SetKernelStack() is not working properly. + * - [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock. * * CREDITS AND REFERENCES: * - General: @@ -169,12 +172,15 @@ EXTERNC void putchar(char c) { Display->Print(c, 0); } EXTERNC void KPrint(const char *Format, ...) { SmartLock(KernelLock); + Time::Clock tm = Time::ReadClock(); printf("\eCCCCCC[\e00AEFF%02d:%02d:%02d\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second); + va_list args; va_start(args, Format); vprintf(Format, args); va_end(args); + putchar('\n'); Display->SetBuffer(0); } @@ -185,6 +191,7 @@ EXTERNC NIF void Main(BootInfo *Info) bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); memcpy(bInfo, Info, sizeof(BootInfo)); debug("BootInfo structure is at %p", bInfo); + Display = new Video::Display(bInfo->Framebuffer[0]); printf("\eFFFFFF%s - %s [\e058C19%s\eFFFFFF]\n", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); /**************************************************************************************/ @@ -192,10 +199,13 @@ EXTERNC NIF void Main(BootInfo *Info) BootClock.Hour, BootClock.Minute, BootClock.Second, BootClock.Day, BootClock.Month, BootClock.Year); KPrint("CPU: \e8822AA%s \e8888FF%s (\e058C19%s\e8888FF)", CPU::Vendor(), CPU::Name(), CPU::Hypervisor()); + KPrint("Initializing GDT and IDT"); Interrupts::Initialize(0); + KPrint("Reading Kernel Parameters"); Config = ParseConfig((char *)bInfo->Kernel.CommandLine); + KPrint("Initializing CPU Features"); CPU::InitializeFeatures(0); @@ -204,10 +214,13 @@ EXTERNC NIF void Main(BootInfo *Info) KPrint("Loading Kernel Symbols"); KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase); + KPrint("Initializing Power Manager"); PowerManager = new Power::Power; + KPrint("Initializing PCI Manager"); PCIManager = new PCI::PCI; + foreach (auto Device in PCIManager->GetDevices()) { KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", @@ -217,14 +230,17 @@ EXTERNC NIF void Main(BootInfo *Info) PCI::Descriptors::GetSubclassName(Device->Class, Device->Subclass), PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF)); } + KPrint("Enabling Interrupts on Bootstrap Processor"); Interrupts::Enable(0); + #if defined(a64) PowerManager->InitDSDT(); #elif defined(a32) // FIXME: Add ACPI support for i386 #elif defined(aa64) #endif + KPrint("Initializing Timers"); #if defined(a64) TimeManager = new Time::time(PowerManager->GetACPI()); @@ -233,8 +249,10 @@ EXTERNC NIF void Main(BootInfo *Info) #elif defined(aa64) TimeManager = new Time::time(nullptr); #endif + KPrint("Initializing Bootstrap Processor Timer"); Interrupts::InitializeTimer(0); + KPrint("Initializing SMP"); SMP::Initialize(PowerManager->GetMADT()); diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index f89d68a..9b8ec10 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -287,24 +287,37 @@ static void *NativeSyscallsTable[] = { uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame) { #if defined(a64) - // debug("rax: %#llx, rbx: %#llx, rcx: %#llx, rdx: %#llx, rsi: %#llx, rdi: %#llx, rbp: %#llx, r8: %#llx, r9: %#llx, r10: %#llx, r11: %#llx, r12: %#llx, r13: %#llx, r14: %#llx, r15: %#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx, Frame->rsi, Frame->rdi, Frame->rbp, Frame->r8, Frame->r9, Frame->r10, Frame->r11, Frame->r12, Frame->r13, Frame->r14, Frame->r15); if (Frame->rax > sizeof(NativeSyscallsTable)) { - fixme("Syscall %lld not implemented", Frame->rax); + fixme("Syscall %ld not implemented", Frame->rax); return SYSCALL_NOT_IMPLEMENTED; } uintptr_t (*call)(uintptr_t, ...) = reinterpret_cast(NativeSyscallsTable[Frame->rax]); if (!call) { - error("Syscall %#llx failed.", Frame->rax); + error("Syscall %#lx failed.", Frame->rax); return SYSCALL_INTERNAL_ERROR; } - debug("[%#lx]->( %#lx %#lx %#lx %#lx %#lx %#lx )", Frame->rax, Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9); + + debug("[%#lx]->( %#lx %#lx %#lx %#lx %#lx %#lx )", + Frame->rax, + Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9); + uintptr_t ret = call((uintptr_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); Frame->rax = ret; return ret; #elif defined(a32) + if (Frame->eax > sizeof(NativeSyscallsTable)) + { + fixme("Syscall %ld not implemented", Frame->eax); + return SYSCALL_NOT_IMPLEMENTED; + } + + /* ... */ + + return SYSCALL_INTERNAL_ERROR; #elif defined(aa64) + return SYSCALL_INTERNAL_ERROR; #endif } diff --git a/include/display.hpp b/include/display.hpp index 252076c..aae8ee6 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -92,19 +92,23 @@ namespace Video private: BootInfo::FramebufferInfo framebuffer; Font *CurrentFont; - ScreenBuffer *Buffers[256]; + ScreenBuffer Buffers[256]; bool ColorIteration = false; int ColorPickerIteration = 0; public: Font *GetCurrentFont(); void SetCurrentFont(Font *Font); + uint16_t GetBitsPerPixel(); + uint64_t GetPitch(); /** * @brief Create a new buffer - * + * * This function creates a new buffer. * + * For @see Width and @see Height. Both values must be greater than 0. + * * @note Some indexes are reserved for the kernel. * 0 - Main buffer * 1 - Loading screen buffer @@ -115,7 +119,7 @@ namespace Video * 253 - Frames (crash screen) * 254 - Details (crash screen) * 255 - Main (crash screen) - * + * * @param Width The width of the buffer * @param Height The height of the buffer * @param Index The index of the buffer (0-255) @@ -130,8 +134,6 @@ namespace Video void GetBufferCursor(int Index, uint32_t *X, uint32_t *Y); void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index); uint32_t GetPixel(uint32_t X, uint32_t Y, int Index); - uint16_t GetBitsPerPixel(); - uint64_t GetPitch(); void Scroll(int Index, int Lines); char Print(char Char, int Index, bool WriteToUART = false); diff --git a/include/smp.hpp b/include/smp.hpp index 7f780ac..4ff4312 100644 --- a/include/smp.hpp +++ b/include/smp.hpp @@ -50,7 +50,7 @@ struct CPUData /** @brief Is CPU online? */ bool IsActive; -}; +} __aligned(16); CPUData *GetCurrentCPU(); CPUData *GetCPU(long ID);