QoL improvements

This commit is contained in:
Alex 2023-03-24 16:22:42 +02:00
parent 3d03f8943b
commit 9ce301907a
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
15 changed files with 378 additions and 326 deletions

View File

@ -8,72 +8,95 @@
namespace GlobalDescriptorTable namespace GlobalDescriptorTable
{ {
static GlobalDescriptorTableEntries GDTEntriesTemplate = { static GlobalDescriptorTableEntries GDTEntriesTemplate = {
// null .Null =
{.Length = 0x0, {
.BaseLow = 0x0, .Length = 0x0,
.BaseMiddle = 0x0, .BaseLow = 0x0,
.Access = {.Raw = 0x0}, .BaseMiddle = 0x0,
.Flags = {.Raw = 0x0}, .Access = {.Raw = 0x0},
.BaseHigh = 0x0}, .Flags = {.Raw = 0x0},
.BaseHigh = 0x0,
},
// kernel code .Code =
{.Length = 0x0, {
.BaseLow = 0x0, .Length = 0x0,
.BaseMiddle = 0x0, .BaseLow = 0x0,
.Access = {.A = 0, .BaseMiddle = 0x0,
.Access = {
.A = 0,
.RW = 1, .RW = 1,
.DC = 0, .DC = 0,
.E = 1, .E = 1,
.S = 1, .S = 1,
.DPL = 0, .DPL = 0,
.P = 1}, .P = 1,
.Flags = {.Unknown = 0x0, .L = 1}, },
.BaseHigh = 0x0}, .Flags = {
.Unknown = 0x0,
.L = 1,
},
.BaseHigh = 0x0,
},
// kernel data .Data = {
{.Length = 0x0, .Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = {.A = 0, .Access = {
.RW = 1, .A = 0,
.DC = 0, .RW = 1,
.E = 0, .DC = 0,
.S = 1, .E = 0,
.DPL = 0, .S = 1,
.P = 1}, .DPL = 0,
.Flags = {.Raw = 0x0}, .P = 1,
.BaseHigh = 0x0}, },
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0,
},
// user data .UserData = {
{.Length = 0x0, .Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = {.A = 0, .Access = {
.RW = 1, .A = 0,
.DC = 0, .RW = 1,
.E = 0, .DC = 0,
.S = 1, .E = 0,
.DPL = 3, .S = 1,
.P = 1}, .DPL = 3,
.Flags = {.Raw = 0x0}, .P = 1,
.BaseHigh = 0x0}, },
.Flags = {
.Raw = 0x0,
},
.BaseHigh = 0x0,
},
// user code .UserCode = {
{.Length = 0x0, .Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = {.A = 0, .Access = {
.RW = 1, .A = 0,
.DC = 0, .RW = 1,
.E = 1, .DC = 0,
.S = 1, .E = 1,
.DPL = 3, .S = 1,
.P = 1}, .DPL = 3,
.Flags = {.Unknown = 0x0, .L = 1}, .P = 1,
.BaseHigh = 0x0}, },
.Flags = {
.Unknown = 0x0,
.L = 1,
},
.BaseHigh = 0x0,
},
// tss .TaskStateSegment = {},
{}}; };
GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; GlobalDescriptorTableEntries GDTEntries[MAX_CPU];
GlobalDescriptorTableDescriptor gdt[MAX_CPU]; GlobalDescriptorTableDescriptor gdt[MAX_CPU];
@ -155,7 +178,12 @@ namespace GlobalDescriptorTable
else else
tss[CPUID].StackPointer[0] = (uint64_t)CPUStackPointer[CPUID] + STACK_SIZE; 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" asmv("mov %%rsp, %0"
: "=r"(tss[CPUID].StackPointer[0])); : "=r"(tss[CPUID].StackPointer[0]));
} }

View File

@ -14,8 +14,10 @@ namespace InterruptDescriptorTable
{ {
static InterruptDescriptorTableEntry Entries[0x100]; static InterruptDescriptorTableEntry Entries[0x100];
InterruptDescriptorTableDescriptor idtd = {.Length = sizeof(Entries) - 1, InterruptDescriptorTableDescriptor idtd = {
.Entries = Entries}; .Length = sizeof(Entries) - 1,
.Entries = Entries,
};
void SetEntry(uint8_t Index, void SetEntry(uint8_t Index,
void (*Base)(), void (*Base)(),
@ -36,19 +38,10 @@ namespace InterruptDescriptorTable
Entries[Index].Present = 1; Entries[Index].Present = 1;
} }
extern "C" __attribute__((naked, used, no_stack_protector)) void ExceptionHandlerStub() extern "C" __naked __used __no_stack_protector void ExceptionHandlerStub()
{ {
asm( asm("cld\n"
// "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"
"cld\n" // clear direction flag
// push all registers
"pushq %rax\n" "pushq %rax\n"
"pushq %rbx\n" "pushq %rbx\n"
"pushq %rcx\n" "pushq %rcx\n"
@ -68,7 +61,6 @@ namespace InterruptDescriptorTable
"movq %rsp, %rdi\n" "movq %rsp, %rdi\n"
"call ExceptionHandler\n" "call ExceptionHandler\n"
// pop all registers
"popq %r15\n" "popq %r15\n"
"popq %r14\n" "popq %r14\n"
"popq %r13\n" "popq %r13\n"
@ -87,44 +79,13 @@ namespace InterruptDescriptorTable
"addq $16, %rsp\n" "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 "iretq"); // pop CS RIP RFLAGS SS RSP
} }
extern "C" void WarnSwapgs() { warn("swapgs"); } extern "C" __naked __used __no_stack_protector void InterruptHandlerStub()
// void *OriginalCR3;
extern "C" __attribute__((naked, used, no_stack_protector)) void InterruptHandlerStub()
{ {
// // Store cr3 to OriginalCR3 asm("cld\n"
// asmv("mov %%cr3, %0"
// : "=q"(OriginalCR3)
// :
// : "memory");
// // Set cr3 to KPT (Kernel Page Table)
// asmv("mov %0, %%cr3"
// :
// : "q"(KPT)
// : "memory");
// 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 %rax\n"
"pushq %rbx\n" "pushq %rbx\n"
"pushq %rcx\n" "pushq %rcx\n"
@ -142,28 +103,9 @@ namespace InterruptDescriptorTable
"pushq %r15\n" "pushq %r15\n"
"movq %rsp, %rdi\n" "movq %rsp, %rdi\n"
"call MainInterruptHandler\n"); "call MainInterruptHandler\n"
// // Check if the current cr3 is the same as the KPT "popq %r15\n"
// // 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 %r14\n" "popq %r14\n"
"popq %r13\n" "popq %r13\n"
"popq %r12\n" "popq %r12\n"
@ -181,38 +123,30 @@ namespace InterruptDescriptorTable
"addq $16, %rsp\n" "addq $16, %rsp\n"
// "cmp $0x1000, %rsp\n" "iretq"); // pop CS RIP RFLAGS SS RSP
// "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");
} }
#pragma region Exceptions #pragma region Exceptions
#define EXCEPTION_HANDLER(num) \ #define EXCEPTION_HANDLER(num) \
__attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ __naked __used __no_stack_protector static void InterruptHandler_##num() \
{ \ { \
asm("pushq $0\npushq $" #num "\n" \ asm("pushq $0\npushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \ "jmp ExceptionHandlerStub"); \
} }
#define EXCEPTION_ERROR_HANDLER(num) \ #define EXCEPTION_ERROR_HANDLER(num) \
__attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ __naked __used __no_stack_protector static void InterruptHandler_##num() \
{ \ { \
asm("pushq $" #num "\n" \ asm("pushq $" #num "\n" \
"jmp ExceptionHandlerStub"); \ "jmp ExceptionHandlerStub"); \
} }
#define INTERRUPT_HANDLER(num) \ #define INTERRUPT_HANDLER(num) \
__attribute__((naked, used, no_stack_protector)) void InterruptHandler_##num() \ __naked __used __no_stack_protector void InterruptHandler_##num() \
{ \ { \
asm("pushq $0\npushq $" #num "\n" \ asm("pushq $0\npushq $" #num "\n" \
"jmp InterruptHandlerStub\n"); \ "jmp InterruptHandlerStub\n"); \
} }
/* ISR */ /* ISR */
@ -487,9 +421,7 @@ namespace InterruptDescriptorTable
void Init(int Core) void Init(int Core)
{ {
UNUSED(Core); if (Core == 0) /* Disable PIC using BSP */
static int once = 0;
if (!once++)
{ {
// PIC // PIC
outb(0x20, 0x10 | 0x1); outb(0x20, 0x10 | 0x1);

View File

@ -25,7 +25,7 @@ enum SMPTrampolineAddress
volatile bool CPUEnabled = false; volatile bool CPUEnabled = false;
#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #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]; } SafeFunction CPUData *GetCPU(long id) { return &CPUs[id]; }
@ -33,6 +33,7 @@ SafeFunction CPUData *GetCurrentCPU()
{ {
if (unlikely(!Interrupts::apic[0])) if (unlikely(!Interrupts::apic[0]))
return &CPUs[0]; /* No APIC means we are on the BSP. */ return &CPUs[0]; /* No APIC means we are on the BSP. */
int CoreID = ((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24; int CoreID = ((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24;
if (unlikely((&CPUs[CoreID])->IsActive != true)) if (unlikely((&CPUs[CoreID])->IsActive != true))

View File

@ -58,7 +58,8 @@ namespace Interrupts
CPU::Stop(); CPU::Stop();
} }
debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE); 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(); InitializeSystemCalls();
#elif defined(a32) #elif defined(a32)
warn("i386 is not supported yet"); warn("i386 is not supported yet");

View File

@ -50,33 +50,38 @@ int LockClass::Lock(const char *FunctionName)
{ {
LockData.AttemptingToGet = FunctionName; LockData.AttemptingToGet = FunctionName;
LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0); LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0);
Retry: Retry:
unsigned int i = 0; int i = 0;
while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000)) while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000))
CPU::Pause(); CPU::Pause();
if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000)) if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000))
{ {
DeadLock(LockData); DeadLock(LockData);
goto Retry; goto Retry;
} }
LockData.Count++; LockData.Count++;
LockData.CurrentHolder = FunctionName; LockData.CurrentHolder = FunctionName;
LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0); LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0);
CPUData *CoreData = GetCurrentCPU(); CPUData *CoreData = GetCurrentCPU();
if (CoreData != nullptr) if (CoreData != nullptr)
LockData.Core = CoreData->ID; LockData.Core = CoreData->ID;
LocksCount++;
__sync;
LocksCount++;
__sync;
return 0; return 0;
} }
int LockClass::Unlock() int LockClass::Unlock()
{ {
__sync; __sync;
IsLocked.Store(false, MemoryOrder::Release); IsLocked.Store(false, MemoryOrder::Release);
LockData.Count--; LockData.Count--;
IsLocked = false;
LocksCount--; LocksCount--;
return 0; return 0;
@ -86,6 +91,7 @@ void LockClass::TimeoutDeadLock(SpinLockData Lock, uint64_t Timeout)
{ {
CPUData *CoreData = GetCurrentCPU(); CPUData *CoreData = GetCurrentCPU();
long CCore = 0xdead; long CCore = 0xdead;
if (CoreData != nullptr) if (CoreData != nullptr)
CCore = CoreData->ID; CCore = CoreData->ID;
@ -111,13 +117,16 @@ int LockClass::TimeoutLock(const char *FunctionName, uint64_t Timeout)
{ {
if (!TimeManager) if (!TimeManager)
return Lock(FunctionName); return Lock(FunctionName);
LockData.AttemptingToGet = FunctionName; LockData.AttemptingToGet = FunctionName;
LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0); LockData.StackPointerAttempt = (uintptr_t)__builtin_frame_address(0);
Atomic<uint64_t> Target = 0; Atomic<uint64_t> Target = 0;
Retry: Retry:
unsigned int i = 0; int i = 0;
while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000)) while (IsLocked.Exchange(true, MemoryOrder::Acquire) && ++i < (DebuggerIsAttached ? 0x100000 : 0x10000000))
CPU::Pause(); CPU::Pause();
if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000)) if (i >= (DebuggerIsAttached ? 0x100000 : 0x10000000))
{ {
if (Target.Load() == 0) if (Target.Load() == 0)
@ -125,14 +134,17 @@ Retry:
TimeoutDeadLock(LockData, Target.Load()); TimeoutDeadLock(LockData, Target.Load());
goto Retry; goto Retry;
} }
LockData.Count++; LockData.Count++;
LockData.CurrentHolder = FunctionName; LockData.CurrentHolder = FunctionName;
LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0); LockData.StackPointerHolder = (uintptr_t)__builtin_frame_address(0);
CPUData *CoreData = GetCurrentCPU(); CPUData *CoreData = GetCurrentCPU();
if (CoreData != nullptr) if (CoreData != nullptr)
LockData.Core = CoreData->ID; LockData.Core = CoreData->ID;
LocksCount++;
__sync;
LocksCount++;
__sync;
return 0; return 0;
} }

View File

@ -107,6 +107,7 @@ namespace Memory
int Flags = Memory::PTFlag::RW; int Flags = Memory::PTFlag::RW;
if (User) if (User)
Flags |= Memory::PTFlag::US; Flags |= Memory::PTFlag::US;
Memory::Virtual(this->PageTable).Remap((void *)((uintptr_t)Address + (i * PAGE_SIZE)), (void *)((uint64_t)Address + (i * PAGE_SIZE)), Flags); 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}); AllocatedPagesList.push_back({Address, Count});
/* For security reasons, we clear the memory /* For security reasons, we clear the allocated page
if the page is user accessible. */ if it's a user page. */
if (User) if (User)
memset(Address, 0, Count * PAGE_SIZE); memset(Address, 0, Count * PAGE_SIZE);
return Address; return Address;
} }
void MemMgr::FreePages(void *Address, size_t Count) void MemMgr::FreePages(void *Address, size_t Count)
{ {
for (size_t i = 0; i < AllocatedPagesList.size(); i++) for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{
if (AllocatedPagesList[i].Address == Address) if (AllocatedPagesList[i].Address == Address)
{ {
/** TODO: Advanced checks. Allow if the page count is less than the requested one. /** TODO: Advanced checks. Allow if the page count is less than the requested one.
@ -150,9 +153,12 @@ namespace Memory
} }
KernelAllocator.FreePages(Address, Count); KernelAllocator.FreePages(Address, Count);
for (size_t i = 0; i < Count; i++) 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).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) if (this->Directory)
{ {
@ -166,11 +172,13 @@ namespace Memory
AllocatedPagesList.remove(i); AllocatedPagesList.remove(i);
return; return;
} }
}
} }
void MemMgr::DetachAddress(void *Address) void MemMgr::DetachAddress(void *Address)
{ {
for (size_t i = 0; i < AllocatedPagesList.size(); i++) for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{
if (AllocatedPagesList[i].Address == Address) if (AllocatedPagesList[i].Address == Address)
{ {
if (this->Directory) if (this->Directory)
@ -185,6 +193,7 @@ namespace Memory
AllocatedPagesList.remove(i); AllocatedPagesList.remove(i);
return; return;
} }
}
} }
MemMgr::MemMgr(PageTable4 *PageTable, VirtualFileSystem::Node *Directory) MemMgr::MemMgr(PageTable4 *PageTable, VirtualFileSystem::Node *Directory)
@ -192,11 +201,13 @@ namespace Memory
if (PageTable) if (PageTable)
this->PageTable = PageTable; this->PageTable = PageTable;
else else
{
#if defined(a64) #if defined(a64)
this->PageTable = (PageTable4 *)CPU::x64::readcr3().raw; this->PageTable = (PageTable4 *)CPU::x64::readcr3().raw;
#elif defined(a32) #elif defined(a32)
this->PageTable = (PageTable4 *)CPU::x32::readcr3().raw; this->PageTable = (PageTable4 *)CPU::x32::readcr3().raw;
#endif #endif
}
this->Directory = Directory; this->Directory = Directory;
debug("+ %#lx", this); debug("+ %#lx", this);
@ -212,8 +223,10 @@ namespace Memory
} }
if (this->Directory) if (this->Directory)
{
foreach (auto Child in this->Directory->Children) foreach (auto Child in this->Directory->Children)
vfs->Delete(Child, true); vfs->Delete(Child, true);
}
debug("- %#lx", this); debug("- %#lx", this);
} }

View File

@ -42,8 +42,10 @@ namespace Memory
bool Physical::SwapPages(void *Address, size_t PageCount) bool Physical::SwapPages(void *Address, size_t PageCount)
{ {
for (size_t i = 0; i < PageCount; i++) for (size_t i = 0; i < PageCount; i++)
{
if (!this->SwapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE)))) if (!this->SwapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))))
return false; return false;
}
return false; return false;
} }
@ -56,20 +58,23 @@ namespace Memory
bool Physical::UnswapPages(void *Address, size_t PageCount) bool Physical::UnswapPages(void *Address, size_t PageCount)
{ {
for (size_t i = 0; i < PageCount; i++) for (size_t i = 0; i < PageCount; i++)
{
if (!this->UnswapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE)))) if (!this->UnswapPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))))
return false; return false;
}
return false; return false;
} }
void *Physical::RequestPage() void *Physical::RequestPage()
{ {
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{ {
if (PageBitmap[PageBitmapIndex] == true) if (PageBitmap[PageBitmapIndex] == true)
continue; continue;
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE));
#ifdef DEBUG #ifdef DEBUG
if (EnableExternalMemoryTracer) if (EnableExternalMemoryTracer)
{ {
@ -106,6 +111,7 @@ namespace Memory
void *Physical::RequestPages(size_t Count) void *Physical::RequestPages(size_t Count)
{ {
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++)
{ {
if (PageBitmap[PageBitmapIndex] == true) if (PageBitmap[PageBitmapIndex] == true)
@ -117,8 +123,10 @@ namespace Memory
continue; continue;
for (size_t i = 0; i < Count; i++) for (size_t i = 0; i < Count; i++)
{
if (PageBitmap[Index + i] == true) if (PageBitmap[Index + i] == true)
goto NextPage; goto NextPage;
}
this->LockPages((void *)(Index * PAGE_SIZE), Count); this->LockPages((void *)(Index * PAGE_SIZE), Count);
#ifdef DEBUG #ifdef DEBUG
@ -152,26 +160,6 @@ namespace Memory
if (this->SwapPages((void *)(PageBitmapIndex * PAGE_SIZE), Count)) if (this->SwapPages((void *)(PageBitmapIndex * PAGE_SIZE), Count))
{ {
this->LockPages((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); return (void *)(PageBitmapIndex * PAGE_SIZE);
} }
@ -183,12 +171,15 @@ namespace Memory
void Physical::FreePage(void *Address) void Physical::FreePage(void *Address)
{ {
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
if (unlikely(Address == nullptr)) if (unlikely(Address == nullptr))
{ {
warn("Null pointer passed to FreePage."); warn("Null pointer passed to FreePage.");
return; return;
} }
size_t Index = (size_t)Address / PAGE_SIZE; size_t Index = (size_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == false)) if (unlikely(PageBitmap[Index] == false))
{ {
warn("Tried to free an already free page. (%p)", Address); warn("Tried to free an already free page. (%p)", Address);
@ -262,8 +253,10 @@ namespace Memory
warn("Trying to lock null address."); warn("Trying to lock null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == true)) if (unlikely(PageBitmap[Index] == true))
return; return;
if (PageBitmap.Set(Index, true)) if (PageBitmap.Set(Index, true))
{ {
FreeMemory -= PAGE_SIZE; FreeMemory -= PAGE_SIZE;
@ -286,6 +279,7 @@ namespace Memory
warn("Trying to reserve null address."); warn("Trying to reserve null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == true)) if (unlikely(PageBitmap[Index] == true))
return; return;
@ -311,6 +305,7 @@ namespace Memory
warn("Trying to unreserve null address."); warn("Trying to unreserve null address.");
uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; uintptr_t Index = (uintptr_t)Address / PAGE_SIZE;
if (unlikely(PageBitmap[Index] == false)) if (unlikely(PageBitmap[Index] == false))
return; return;
@ -335,25 +330,33 @@ namespace Memory
void Physical::Init(BootInfo *Info) void Physical::Init(BootInfo *Info)
{ {
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
uint64_t MemorySize = Info->Memory.Size;
TotalMemory = MemorySize;
FreeMemory = MemorySize;
void *LargestFreeMemorySegment = nullptr; void *LargestFreeMemorySegment = nullptr;
uint64_t LargestFreeMemorySegmentSize = 0; uint64_t LargestFreeMemorySegmentSize = 0;
uint64_t MemorySize = Info->Memory.Size;
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)
{
if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize) if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize)
{ {
// We don't want to use 0 as a memory address. /* We don't want to use 0 as a memory address. */
if (Info->Memory.Entry[i].BaseAddress == nullptr) if (Info->Memory.Entry[i].BaseAddress == 0x0)
continue; continue;
LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
debug("Largest free memory segment: %llp (%lldMB)", debug("Largest free memory segment: %llp (%lldMB)",
(void *)Info->Memory.Entry[i].BaseAddress, (void *)Info->Memory.Entry[i].BaseAddress,
TO_MB(Info->Memory.Entry[i].Length)); TO_MB(Info->Memory.Entry[i].Length));
} }
TotalMemory = MemorySize; }
FreeMemory = MemorySize; }
if (LargestFreeMemorySegment == nullptr) if (LargestFreeMemorySegment == nullptr)
{ {
@ -366,6 +369,7 @@ namespace Memory
LargestFreeMemorySegment, LargestFreeMemorySegment,
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize), (void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
BitmapSize); BitmapSize);
PageBitmap.Size = BitmapSize; PageBitmap.Size = BitmapSize;
PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment; PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegment;
for (size_t i = 0; i < BitmapSize; i++) for (size_t i = 0; i < BitmapSize; i++)
@ -373,8 +377,11 @@ namespace Memory
trace("Reserving pages..."); trace("Reserving 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->ReservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1); this->ReservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);
}
trace("Locking bitmap pages..."); trace("Locking bitmap pages...");
this->ReservePages(0, 0x100); this->ReservePages(0, 0x100);
this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1); this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1);

View File

@ -8,35 +8,45 @@ namespace Memory
{ {
this->UserMode = User; this->UserMode = User;
this->Table = Table; this->Table = Table;
if (this->UserMode) if (this->UserMode)
{ {
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE)); void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
debug("AllocatedStack: %p", AllocatedStack);
memset(AllocatedStack, 0, USER_STACK_SIZE); memset(AllocatedStack, 0, USER_STACK_SIZE);
debug("AllocatedStack: %p", AllocatedStack);
for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++) for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
{ {
Virtual(Table).Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)), Virtual(Table).Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)),
(void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)),
PTFlag::RW | PTFlag::US); PTFlag::RW | PTFlag::US);
debug("Mapped %p to %p", (void *)(USER_STACK_BASE + (i * PAGE_SIZE)), debug("Mapped %p to %p", (void *)(USER_STACK_BASE + (i * PAGE_SIZE)),
(void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE))); (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)));
} }
this->StackBottom = (void *)USER_STACK_BASE; this->StackBottom = (void *)USER_STACK_BASE;
this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE); this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE);
this->StackPhyiscalBottom = AllocatedStack; this->StackPhyiscalBottom = AllocatedStack;
this->StackPhyiscalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE); this->StackPhyiscalTop = (void *)((uintptr_t)AllocatedStack + USER_STACK_SIZE);
this->Size = USER_STACK_SIZE; this->Size = USER_STACK_SIZE;
} }
else else
{ {
this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));
this->StackPhyiscalBottom = this->StackBottom;
debug("StackBottom: %p", this->StackBottom);
memset(this->StackBottom, 0, STACK_SIZE); memset(this->StackBottom, 0, STACK_SIZE);
debug("StackBottom: %p", this->StackBottom);
this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE); this->StackTop = (void *)((uintptr_t)this->StackBottom + STACK_SIZE);
this->StackPhyiscalBottom = this->StackBottom;
this->StackPhyiscalTop = this->StackTop; this->StackPhyiscalTop = this->StackTop;
this->Size = STACK_SIZE; this->Size = STACK_SIZE;
} }
trace("Allocated stack at %p", this->StackBottom); trace("Allocated stack at %p", this->StackBottom);
} }
@ -54,7 +64,7 @@ namespace Memory
if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE || if (FaultAddress < (uintptr_t)this->StackBottom - USER_STACK_SIZE ||
FaultAddress > (uintptr_t)this->StackTop) FaultAddress > (uintptr_t)this->StackTop)
{ {
return false; // It's not about the stack. return false; /* It's not about the stack. */
} }
else else
{ {
@ -77,7 +87,5 @@ namespace Memory
fixme("Not implemented and probably not needed"); fixme("Not implemented and probably not needed");
return false; return false;
} }
error("Reached end of function! How?");
return false;
} }
} }

View File

@ -155,6 +155,7 @@ namespace Memory
error("Page %#lx not present", PML4.GetAddress()); error("Page %#lx not present", PML4.GetAddress());
return; return;
} }
PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.Address << 12); PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.Address << 12);
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex]; PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
if (!PDPTE.Present) if (!PDPTE.Present)
@ -162,6 +163,7 @@ namespace Memory
error("Page %#lx not present", PDPTE.GetAddress()); error("Page %#lx not present", PDPTE.GetAddress());
return; return;
} }
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12); PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12);
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex]; PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
if (!PDE.Present) if (!PDE.Present)
@ -169,6 +171,7 @@ namespace Memory
error("Page %#lx not present", PDE.GetAddress()); error("Page %#lx not present", PDE.GetAddress());
return; return;
} }
PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12); PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12);
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
if (!PTE.Present) if (!PTE.Present)

View File

@ -11,84 +11,79 @@ NewLock(PrintLock);
namespace Video namespace Video
{ {
Font *Display::GetCurrentFont() Font *Display::GetCurrentFont() { return CurrentFont; }
{ void Display::SetCurrentFont(Font *Font) { CurrentFont = Font; }
return CurrentFont; uint16_t Display::GetBitsPerPixel() { return this->framebuffer.BitsPerPixel; }
} uint64_t Display::GetPitch() { return this->framebuffer.Pitch; }
void Display::SetCurrentFont(Font *Font)
{
CurrentFont = Font;
}
void Display::CreateBuffer(uint32_t Width, uint32_t Height, int Index) 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; Width = this->framebuffer.Width;
Height = this->framebuffer.Height; 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; 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; this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); memset(this->Buffers[Index].Buffer, 0, Size);
buffer->Width = Width;
buffer->Height = Height; this->Buffers[Index].Width = Width;
buffer->Size = Size; this->Buffers[Index].Height = Height;
buffer->Color = 0xFFFFFF; this->Buffers[Index].Size = Size;
buffer->CursorX = 0; this->Buffers[Index].Color = 0xFFFFFF;
buffer->CursorY = 0; this->Buffers[Index].CursorX = 0;
buffer->Brightness = 100; this->Buffers[Index].CursorY = 0;
this->Buffers[Index] = buffer; this->Buffers[Index].Brightness = 100;
memset(this->Buffers[Index]->Buffer, 0, Size); this->Buffers[Index].Checksum = 0xDEAD;
this->Buffers[Index]->Checksum = 0xDEAD; debug("Buffer %d created", Index);
debug("Created buffer %d, address %#lx", Index, buffer);
} }
void Display::SetBuffer(int Index) void Display::SetBuffer(int Index)
{ {
if (this->Buffers[Index]->Brightness != 100) if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
this->SetBrightness(this->Buffers[Index]->Brightness, Index); return;
if (this->Buffers[Index]->Brightness == 0) /* Just clear the buffer */ if (this->Buffers[Index].Brightness != 100)
memset(this->Buffers[Index]->Buffer, 0, this->Buffers[Index]->Size); 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) ScreenBuffer *Display::GetBuffer(int Index) { return &this->Buffers[Index]; }
{
return this->Buffers[Index];
}
void Display::ClearBuffer(int 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) void Display::DeleteBuffer(int Index)
{ {
if (this->Buffers[Index] == nullptr) if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
return; return;
KernelAllocator.FreePages(this->Buffers[Index]->Buffer, TO_PAGES(this->Buffers[Index]->Size));
this->Buffers[Index]->Buffer = nullptr; KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size));
this->Buffers[Index]->Checksum = 0; // Making sure that the buffer is not used anymore this->Buffers[Index].Buffer = nullptr;
delete this->Buffers[Index], this->Buffers[Index] = nullptr; this->Buffers[Index].Checksum = 0;
} }
void Display::SetBrightness(int Value, int Index) void Display::SetBrightness(int Value, int Index)
{ {
if (this->Buffers[Index] == nullptr) if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
return; return;
if (Value > 100) if (Value > 100)
@ -96,14 +91,13 @@ namespace Video
else if (Value < 0) else if (Value < 0)
Value = 0; Value = 0;
ScreenBuffer *buffer = this->Buffers[Index]; uint32_t *pixel = (uint32_t *)this->Buffers[Index].Buffer;
uint32_t *pixel = (uint32_t *)buffer->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 r = color & 0xff;
uint8_t g = (color >> 8) & 0xff; uint8_t g = (color >> 8) & 0xff;
@ -113,82 +107,93 @@ namespace Video
g = (g * Value) / 100; g = (g * Value) / 100;
b = (b * 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) void Display::SetBufferCursor(int Index, uint32_t X, uint32_t Y)
{ {
this->Buffers[Index]->CursorX = X; if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
this->Buffers[Index]->CursorY = Y; return;
this->Buffers[Index].CursorX = X;
this->Buffers[Index].CursorY = Y;
} }
void Display::GetBufferCursor(int Index, uint32_t *X, uint32_t *Y) void Display::GetBufferCursor(int Index, uint32_t *X, uint32_t *Y)
{ {
*X = this->Buffers[Index]->CursorX; if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
*Y = this->Buffers[Index]->CursorY; 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) void Display::SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index)
{ {
if (unlikely(X >= this->Buffers[Index]->Width)) if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
X = this->Buffers[Index]->Width - 1; return;
if (unlikely(Y >= this->Buffers[Index]->Height))
Y = this->Buffers[Index]->Height - 1; if (unlikely(X >= this->Buffers[Index].Width))
uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index]->Buffer + (Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)); 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; *Pixel = Color;
} }
uint32_t Display::GetPixel(uint32_t X, uint32_t Y, int Index) 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; 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; 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) void Display::Scroll(int Index, int Lines)
{ {
if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
return;
if (Lines == 0) if (Lines == 0)
return; return;
if (Lines > 0) 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 BytesToMove = LineSize * Lines * this->CurrentFont->GetInfo().Height;
uint32_t BytesToClear = this->Buffers[Index]->Size - BytesToMove; uint32_t BytesToClear = this->Buffers[Index].Size - BytesToMove;
memmove(this->Buffers[Index]->Buffer, (uint8_t *)this->Buffers[Index]->Buffer + BytesToMove, BytesToClear); memmove(this->Buffers[Index].Buffer, (uint8_t *)this->Buffers[Index].Buffer + BytesToMove, BytesToClear);
memset((uint8_t *)this->Buffers[Index]->Buffer + BytesToClear, 0, BytesToMove); memset((uint8_t *)this->Buffers[Index].Buffer + BytesToClear, 0, BytesToMove);
} }
} }
char Display::Print(char Char, int Index, bool WriteToUART) char Display::Print(char Char, int Index, bool WriteToUART)
{ {
if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
return 0;
// SmartLock(PrintLock); // SmartLock(PrintLock);
if (this->ColorIteration) if (this->ColorIteration)
{ {
// RRGGBB // RRGGBB
if (Char >= '0' && Char <= '9') 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') 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') 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 else
this->Buffers[Index]->Color = 0xFFFFFF; this->Buffers[Index].Color = 0xFFFFFF;
if (WriteToUART) if (WriteToUART)
UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(Char); UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(Char);
this->ColorPickerIteration++; this->ColorPickerIteration++;
@ -228,10 +233,10 @@ namespace Video
uint32_t fonthdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; uint32_t fonthdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width;
uint32_t fonthdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; 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 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++) for (unsigned long X = this->Buffers[Index].CursorX - fonthdrWidth; X < this->Buffers[Index].CursorX; X++)
*(uint32_t *)((uintptr_t)this->Buffers[Index]->Buffer + *(uint32_t *)((uintptr_t)this->Buffers[Index].Buffer +
(Y * this->Buffers[Index]->Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0;
break; break;
} }
default: default:
@ -239,40 +244,40 @@ namespace Video
break; break;
} }
if (this->Buffers[Index]->CursorX > 0) if (this->Buffers[Index].CursorX > 0)
this->Buffers[Index]->CursorX -= this->GetCurrentFont()->GetInfo().Width; this->Buffers[Index].CursorX -= this->GetCurrentFont()->GetInfo().Width;
return Char; return Char;
} }
case '\t': 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; return Char;
} }
case '\r': case '\r':
{ {
this->Buffers[Index]->CursorX = 0; this->Buffers[Index].CursorX = 0;
return Char; return Char;
} }
case '\n': case '\n':
{ {
this->Buffers[Index]->CursorX = 0; this->Buffers[Index].CursorX = 0;
this->Buffers[Index]->CursorY += this->GetCurrentFont()->GetInfo().Height; this->Buffers[Index].CursorY += this->GetCurrentFont()->GetInfo().Height;
return Char; return Char;
} }
} }
uint32_t FontHeight = this->GetCurrentFont()->GetInfo().Height; 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].CursorX = 0;
this->Buffers[Index]->CursorY += FontHeight; 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); this->Scroll(Index, 1);
} }
@ -280,16 +285,16 @@ namespace Video
{ {
case FontType::PCScreenFont1: 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); 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++) for (uint64_t X = this->Buffers[Index].CursorX; X < this->Buffers[Index].CursorX + 8; X++)
if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index]->CursorX))) > 0) if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index].CursorX))) > 0)
*(unsigned int *)(PixelPtr + X + (Y * this->Buffers[Index]->Width)) = this->Buffers[Index]->Color; *(unsigned int *)(PixelPtr + X + (Y * this->Buffers[Index].Width)) = this->Buffers[Index].Color;
FontPtr++; FontPtr++;
} }
this->Buffers[Index]->CursorX += 8; this->Buffers[Index].CursorX += 8;
break; break;
} }
@ -307,21 +312,21 @@ namespace Video
uint32_t FontHdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; uint32_t FontHdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width;
uint32_t FontHdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; 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 + void *FramebufferAddress = (void *)((uintptr_t)this->Buffers[Index].Buffer +
(Y * this->Buffers[Index]->Width + X) * (Y * this->Buffers[Index].Width + X) *
(this->framebuffer.BitsPerPixel / 8)); (this->framebuffer.BitsPerPixel / 8));
*(uint32_t *)FramebufferAddress = this->Buffers[Index]->Color; *(uint32_t *)FramebufferAddress = this->Buffers[Index].Color;
} }
} }
FontPtr += BytesPerLine; FontPtr += BytesPerLine;
} }
this->Buffers[Index]->CursorX += FontHdrWidth; this->Buffers[Index].CursorX += FontHdrWidth;
break; break;
} }
default: default:
@ -333,8 +338,11 @@ namespace Video
void Display::DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART) void Display::DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART)
{ {
this->Buffers[Index]->CursorX = X; if (unlikely(this->Buffers[Index].Checksum != 0xDEAD))
this->Buffers[Index]->CursorY = Y; return;
this->Buffers[Index].CursorX = X;
this->Buffers[Index].CursorY = Y;
for (int i = 0; String[i] != '\0'; i++) for (int i = 0; String[i] != '\0'; i++)
this->Print(String[i], Index, WriteToUART); this->Print(String[i], Index, WriteToUART);

View File

@ -10,23 +10,29 @@ namespace Video
this->Info.StartAddress = Start; this->Info.StartAddress = Start;
this->Info.EndAddress = End; this->Info.EndAddress = End;
this->Info.Type = Type; this->Info.Type = Type;
size_t FontDataLength = End - Start;
if (Type == FontType::PCScreenFont2) if (Type == FontType::PCScreenFont2)
{ {
this->Info.PSF2Font = new PSF2_FONT; this->Info.PSF2Font = new PSF2_FONT;
uintptr_t FontDataLength = End - Start;
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1); 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); memcpy((void *)font2, Start, FontDataLength);
this->Info.Width = font2->width; for (uintptr_t i = 0; i < FontDataLength / PAGE_SIZE + 1; i++)
this->Info.Height = font2->height; 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) 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."); error("Font2 magic mismatch.");
KernelAllocator.FreePages((void *)font2, FontDataLength / PAGE_SIZE + 1);
return;
}
this->Info.PSF2Font->Header = font2; this->Info.PSF2Font->Header = font2;
this->Info.PSF2Font->GlyphBuffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(Start) + sizeof(PSF2_HEADER)); 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) else if (Type == FontType::PCScreenFont1)
{ {

View File

@ -48,11 +48,14 @@ LockClass mExtTrkLock;
* - [?] Rewrite virtual file system. (it's very bad, I don't know how I wrote it this bad) * - [?] 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. * - [ ] Colors in crash screen are not following the kernel color scheme.
* - [ ] Find a way to add intrinsics. * - [ ] Find a way to add intrinsics.
* - [ ] Rework PSF1 font loader.
* *
* ISSUES: * ISSUES:
* - [ ] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) * - [ ] 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. * - [ ] 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: * CREDITS AND REFERENCES:
* - General: * - General:
@ -169,12 +172,15 @@ EXTERNC void putchar(char c) { Display->Print(c, 0); }
EXTERNC void KPrint(const char *Format, ...) EXTERNC void KPrint(const char *Format, ...)
{ {
SmartLock(KernelLock); SmartLock(KernelLock);
Time::Clock tm = Time::ReadClock(); Time::Clock tm = Time::ReadClock();
printf("\eCCCCCC[\e00AEFF%02d:%02d:%02d\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second); printf("\eCCCCCC[\e00AEFF%02d:%02d:%02d\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second);
va_list args; va_list args;
va_start(args, Format); va_start(args, Format);
vprintf(Format, args); vprintf(Format, args);
va_end(args); va_end(args);
putchar('\n'); putchar('\n');
Display->SetBuffer(0); Display->SetBuffer(0);
} }
@ -185,6 +191,7 @@ EXTERNC NIF void Main(BootInfo *Info)
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));
debug("BootInfo structure is at %p", bInfo); debug("BootInfo structure is at %p", bInfo);
Display = new Video::Display(bInfo->Framebuffer[0]); Display = new Video::Display(bInfo->Framebuffer[0]);
printf("\eFFFFFF%s - %s [\e058C19%s\eFFFFFF]\n", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); 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.Hour, BootClock.Minute, BootClock.Second,
BootClock.Day, BootClock.Month, BootClock.Year); BootClock.Day, BootClock.Month, BootClock.Year);
KPrint("CPU: \e8822AA%s \e8888FF%s (\e058C19%s\e8888FF)", CPU::Vendor(), CPU::Name(), CPU::Hypervisor()); KPrint("CPU: \e8822AA%s \e8888FF%s (\e058C19%s\e8888FF)", CPU::Vendor(), CPU::Name(), CPU::Hypervisor());
KPrint("Initializing GDT and IDT"); KPrint("Initializing GDT and IDT");
Interrupts::Initialize(0); Interrupts::Initialize(0);
KPrint("Reading Kernel Parameters"); KPrint("Reading Kernel Parameters");
Config = ParseConfig((char *)bInfo->Kernel.CommandLine); Config = ParseConfig((char *)bInfo->Kernel.CommandLine);
KPrint("Initializing CPU Features"); KPrint("Initializing CPU Features");
CPU::InitializeFeatures(0); CPU::InitializeFeatures(0);
@ -204,10 +214,13 @@ EXTERNC NIF void Main(BootInfo *Info)
KPrint("Loading Kernel Symbols"); KPrint("Loading Kernel Symbols");
KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase); KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase);
KPrint("Initializing Power Manager"); KPrint("Initializing Power Manager");
PowerManager = new Power::Power; PowerManager = new Power::Power;
KPrint("Initializing PCI Manager"); KPrint("Initializing PCI Manager");
PCIManager = new PCI::PCI; PCIManager = new PCI::PCI;
foreach (auto Device in PCIManager->GetDevices()) foreach (auto Device in PCIManager->GetDevices())
{ {
KPrint("PCI: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s", 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::GetSubclassName(Device->Class, Device->Subclass),
PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF)); PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF));
} }
KPrint("Enabling Interrupts on Bootstrap Processor"); KPrint("Enabling Interrupts on Bootstrap Processor");
Interrupts::Enable(0); Interrupts::Enable(0);
#if defined(a64) #if defined(a64)
PowerManager->InitDSDT(); PowerManager->InitDSDT();
#elif defined(a32) #elif defined(a32)
// FIXME: Add ACPI support for i386 // FIXME: Add ACPI support for i386
#elif defined(aa64) #elif defined(aa64)
#endif #endif
KPrint("Initializing Timers"); KPrint("Initializing Timers");
#if defined(a64) #if defined(a64)
TimeManager = new Time::time(PowerManager->GetACPI()); TimeManager = new Time::time(PowerManager->GetACPI());
@ -233,8 +249,10 @@ EXTERNC NIF void Main(BootInfo *Info)
#elif defined(aa64) #elif defined(aa64)
TimeManager = new Time::time(nullptr); TimeManager = new Time::time(nullptr);
#endif #endif
KPrint("Initializing Bootstrap Processor Timer"); KPrint("Initializing Bootstrap Processor Timer");
Interrupts::InitializeTimer(0); Interrupts::InitializeTimer(0);
KPrint("Initializing SMP"); KPrint("Initializing SMP");
SMP::Initialize(PowerManager->GetMADT()); SMP::Initialize(PowerManager->GetMADT());

View File

@ -287,24 +287,37 @@ static void *NativeSyscallsTable[] = {
uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame) uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame)
{ {
#if defined(a64) #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)) if (Frame->rax > sizeof(NativeSyscallsTable))
{ {
fixme("Syscall %lld not implemented", Frame->rax); fixme("Syscall %ld not implemented", Frame->rax);
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
uintptr_t (*call)(uintptr_t, ...) = reinterpret_cast<uintptr_t (*)(uintptr_t, ...)>(NativeSyscallsTable[Frame->rax]); uintptr_t (*call)(uintptr_t, ...) = reinterpret_cast<uintptr_t (*)(uintptr_t, ...)>(NativeSyscallsTable[Frame->rax]);
if (!call) if (!call)
{ {
error("Syscall %#llx failed.", Frame->rax); error("Syscall %#lx failed.", Frame->rax);
return SYSCALL_INTERNAL_ERROR; 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); uintptr_t ret = call((uintptr_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9);
Frame->rax = ret; Frame->rax = ret;
return ret; return ret;
#elif defined(a32) #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) #elif defined(aa64)
return SYSCALL_INTERNAL_ERROR;
#endif #endif
} }

View File

@ -92,19 +92,23 @@ namespace Video
private: private:
BootInfo::FramebufferInfo framebuffer; BootInfo::FramebufferInfo framebuffer;
Font *CurrentFont; Font *CurrentFont;
ScreenBuffer *Buffers[256]; ScreenBuffer Buffers[256];
bool ColorIteration = false; bool ColorIteration = false;
int ColorPickerIteration = 0; int ColorPickerIteration = 0;
public: public:
Font *GetCurrentFont(); Font *GetCurrentFont();
void SetCurrentFont(Font *Font); void SetCurrentFont(Font *Font);
uint16_t GetBitsPerPixel();
uint64_t GetPitch();
/** /**
* @brief Create a new buffer * @brief Create a new buffer
* *
* This function creates 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. * @note Some indexes are reserved for the kernel.
* 0 - Main buffer * 0 - Main buffer
* 1 - Loading screen buffer * 1 - Loading screen buffer
@ -115,7 +119,7 @@ namespace Video
* 253 - Frames (crash screen) * 253 - Frames (crash screen)
* 254 - Details (crash screen) * 254 - Details (crash screen)
* 255 - Main (crash screen) * 255 - Main (crash screen)
* *
* @param Width The width of the buffer * @param Width The width of the buffer
* @param Height The height of the buffer * @param Height The height of the buffer
* @param Index The index of the buffer (0-255) * @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 GetBufferCursor(int Index, uint32_t *X, uint32_t *Y);
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);
uint32_t GetPixel(uint32_t X, uint32_t Y, 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); void Scroll(int Index, int Lines);
char Print(char Char, int Index, bool WriteToUART = false); char Print(char Char, int Index, bool WriteToUART = false);

View File

@ -50,7 +50,7 @@ struct CPUData
/** @brief Is CPU online? */ /** @brief Is CPU online? */
bool IsActive; bool IsActive;
}; } __aligned(16);
CPUData *GetCurrentCPU(); CPUData *GetCurrentCPU();
CPUData *GetCPU(long ID); CPUData *GetCPU(long ID);