mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-11 23:39:20 +00:00
QoL improvements
This commit is contained in:
@ -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");
|
||||
|
@ -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<uint64_t> 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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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<void *>(reinterpret_cast<uintptr_t>(Start) + sizeof(PSF2_HEADER));
|
||||
this->Info.Width = font2->width;
|
||||
this->Info.Height = font2->height;
|
||||
}
|
||||
else if (Type == FontType::PCScreenFont1)
|
||||
{
|
||||
|
Reference in New Issue
Block a user