Update kernel

This commit is contained in:
EnderIce2
2024-01-19 06:47:42 +02:00
parent fd15592608
commit 96daa43d38
282 changed files with 25486 additions and 15700 deletions

View File

@ -33,7 +33,7 @@ using namespace CPU::x64;
using namespace CPU::x86;
/*
In constructor APIC::APIC::APIC(int):
In constructor 'APIC::APIC::APIC(int)':
warning: left shift count >= width of type
| APICBaseAddress = BaseStruct.ApicBaseLo << 12u | BaseStruct.ApicBaseHi << 32u;
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
@ -55,8 +55,8 @@ namespace APIC
debug("APIC::Read(%#lx) [x2=%d]",
Register, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
assert(false);
if (unlikely(x2APICSupported))
assert(!"x2APIC is not supported");
CPU::MemBar::Barrier();
uint32_t ret = *((volatile uint32_t *)((uintptr_t)APICBaseAddress + Register));
@ -76,8 +76,8 @@ namespace APIC
debug("APIC::Write(%#lx, %#lx) [x2=%d]",
Register, Value, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
assert(false);
if (unlikely(x2APICSupported))
assert(!"x2APIC is not supported");
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)APICBaseAddress) + Register)) = Value;
@ -107,6 +107,8 @@ namespace APIC
void APIC::EOI()
{
Memory::SwapPT swap =
Memory::SwapPT(KernelPageTable, thisPageTable);
if (this->x2APICSupported)
wrmsr(MSR_X2APIC_EOI, 0);
else
@ -396,20 +398,18 @@ namespace APIC
APIC::~APIC() {}
void Timer::OnInterruptReceived(TrapFrame *Frame) { UNUSED(Frame); }
void Timer::OnInterruptReceived(CPU::TrapFrame *Frame) { UNUSED(Frame); }
void Timer::OneShot(uint32_t Vector, uint64_t Miliseconds)
{
SmartCriticalSection(APICLock);
/* FIXME: Sometimes APIC stops firing when debugging, why? */
LVTTimer timer{};
timer.VEC = uint8_t(Vector);
timer.TMM = LVTTimerMode::OneShot;
LVTTimerDivide Divider = DivideBy8;
if (unlikely(strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0))
Divider = DivideBy128;
SmartCriticalSection(APICLock);
if (this->lapic->x2APIC)
{
// wrmsr(MSR_X2APIC_DIV_CONF, Divider); <- gpf on real hardware

View File

@ -373,7 +373,7 @@ namespace APIC
private:
APIC *lapic;
uint64_t Ticks = 0;
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
void OnInterruptReceived(CPU::TrapFrame *Frame);
public:
uint64_t GetTicks() { return Ticks; }

View File

@ -122,7 +122,7 @@ namespace GlobalDescriptorTable
SafeFunction void Init(int Core)
{
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
GDTEntries[Core] = GDTEntriesTemplate;
gdt[Core] =
{
.Limit = sizeof(GlobalDescriptorTableEntries) - 1,

View File

@ -25,7 +25,7 @@
#include "gdt.hpp"
#include "../../../kernel.h"
/* conversion from uint64_t {aka long unsigned int} to unsigned char:2 may change value */
/* conversion from 'uint64_t' {aka 'long unsigned int'} to 'unsigned char:2' may change value */
#pragma GCC diagnostic ignored "-Wconversion"
extern "C" void MainInterruptHandler(void *Data);
@ -532,11 +532,11 @@ namespace InterruptDescriptorTable
}
bool EnableISRs = true;
#ifdef DEBUG
// #ifdef DEBUG
EnableISRs = !DebuggerIsAttached;
if (!EnableISRs)
KPrint("\eFFA500The debugger is attached, disabling all ISRs.");
#endif
// #endif
/* ISR */
SetEntry(0x0, InterruptHandler_0x0, IST1, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
@ -553,7 +553,7 @@ namespace InterruptDescriptorTable
SetEntry(0xb, InterruptHandler_0xb, IST1, TRAP_GATE_64BIT, RING0, (!DebuggerIsAttached), GDT_KERNEL_CODE);
SetEntry(0xc, InterruptHandler_0xc, IST3, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
SetEntry(0xd, InterruptHandler_0xd, IST3, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
SetEntry(0xe, InterruptHandler_0xe, IST3, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
SetEntry(0xe, InterruptHandler_0xe, IST3, TRAP_GATE_64BIT, RING0, EnableISRs /* FIXME: CoW? */, GDT_KERNEL_CODE);
SetEntry(0xf, InterruptHandler_0xf, IST1, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
SetEntry(0x10, InterruptHandler_0x10, IST1, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);
SetEntry(0x11, InterruptHandler_0x11, IST1, TRAP_GATE_64BIT, RING0, EnableISRs, GDT_KERNEL_CODE);

View File

@ -57,6 +57,9 @@ SafeFunction CPUData *GetCurrentCPU()
int CoreID = 0;
if (CPUEnabled.load(std::memory_order_acquire) == true)
{
Memory::SwapPT swap =
Memory::SwapPT(KernelPageTable, thisPageTable);
if (apic->x2APIC)
CoreID = int(CPU::x64::rdmsr(CPU::x64::MSR_X2APIC_APICID));
else
@ -125,7 +128,8 @@ namespace SMP
(uintptr_t)&_trampoline_start;
Memory::Virtual().Map(0x0, 0x0, Memory::PTFlag::RW);
/* We reserved the TRAMPOLINE_START address inside Physical class. */
Memory::Virtual().Map((void *)TRAMPOLINE_START, (void *)TRAMPOLINE_START,
Memory::Virtual().Map((void *)TRAMPOLINE_START,
(void *)TRAMPOLINE_START,
TrampolineLength, Memory::PTFlag::RW);
memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength);
debug("Trampoline address: %#lx-%#lx",

View File

@ -29,7 +29,7 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTE = nullptr;
PageDirectoryEntryPtr *PDE = nullptr;
@ -74,7 +74,7 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTE = nullptr;
PageDirectoryEntryPtr *PDE = nullptr;
@ -119,7 +119,7 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTE = nullptr;
PageDirectoryEntryPtr *PDE = nullptr;
@ -172,9 +172,11 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
if (PML4->Present)
return PML4;
debug("PML4 not present for %#lx", VirtualAddress);
return nullptr;
}
@ -185,14 +187,19 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
if (!PML4->Present)
{
debug("PML4 not present for %#lx", VirtualAddress);
return nullptr;
}
PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4->Address << 12);
PageDirectoryPointerTableEntry *PDPTE = &PDPTEPtr->Entries[Index.PDPTEIndex];
if (PDPTE->Present)
return PDPTE;
debug("PDPTE not present for %#lx", VirtualAddress);
return nullptr;
}
@ -203,19 +210,27 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
if (!PML4->Present)
{
debug("PML4 not present for %#lx", VirtualAddress);
return nullptr;
}
PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4->Address << 12);
PageDirectoryPointerTableEntry *PDPTE = &PDPTEPtr->Entries[Index.PDPTEIndex];
if (!PDPTE->Present)
{
debug("PDPTE not present for %#lx", VirtualAddress);
return nullptr;
}
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)(PDPTE->GetAddress() << 12);
PageDirectoryEntry *PDE = &PDEPtr->Entries[Index.PDEIndex];
if (PDE->Present)
return PDE;
debug("PDE not present for %#lx", VirtualAddress);
return nullptr;
}
@ -226,31 +241,42 @@ namespace Memory
Address &= 0xFFFFFFFFFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
if (!PML4->Present)
{
debug("PML4 not present for %#lx", VirtualAddress);
return nullptr;
}
PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4->Address << 12);
PageDirectoryPointerTableEntry *PDPTE = &PDPTEPtr->Entries[Index.PDPTEIndex];
if (!PDPTE->Present)
{
debug("PDPTE not present for %#lx", VirtualAddress);
return nullptr;
}
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)(PDPTE->GetAddress() << 12);
PageDirectoryEntry *PDE = &PDEPtr->Entries[Index.PDEIndex];
if (!PDE->Present)
{
debug("PDE not present for %#lx", VirtualAddress);
return nullptr;
}
PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)(PDE->GetAddress() << 12);
PageTableEntry *PTE = &PTEPtr->Entries[Index.PTEIndex];
if (PTE->Present)
return PTE;
debug("PTE not present for %#lx", VirtualAddress);
return nullptr;
}
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
{
SmartLock(this->MemoryLock);
if (unlikely(!this->Table))
if (unlikely(!this->pTable))
{
error("No page table");
return;
@ -262,7 +288,7 @@ namespace Memory
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
uint64_t DirectoryFlags = Flags & 0x3F;
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr;
if (!PML4->Present)
{
@ -323,7 +349,7 @@ namespace Memory
PTE->Present = true;
PTE->raw |= Flags;
PTE->SetAddress((uintptr_t)PhysicalAddress >> 12);
CPU::x32::invlpg(VirtualAddress);
CPU::x64::invlpg(VirtualAddress);
#ifdef DEBUG
/* https://stackoverflow.com/a/3208376/9352057 */
@ -346,14 +372,14 @@ namespace Memory
void Virtual::Unmap(void *VirtualAddress, MapType Type)
{
SmartLock(this->MemoryLock);
if (!this->Table)
if (!this->pTable)
{
error("No page table");
return;
}
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex];
PageMapLevel4 *PML4 = &this->pTable->Entries[Index.PMLIndex];
if (!PML4->Present)
{
warn("Page %#lx not present", PML4->GetAddress());
@ -398,6 +424,6 @@ namespace Memory
PTE.Present = false;
PTEPtr->Entries[Index.PTEIndex] = PTE;
CPU::x32::invlpg(VirtualAddress);
CPU::x64::invlpg(VirtualAddress);
}
}

View File

@ -0,0 +1,38 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
.code64
.global _sig_native_trampoline_start
_sig_native_trampoline_start:
int $0x3
.global _sig_native_trampoline_end
_sig_native_trampoline_end:
.global _sig_linux_trampoline_start
_sig_linux_trampoline_start:
movq %rsp, %rbp
movq (%rbp), %rax
call %rax
mov %rbp, %rsp
/* rt_sigreturn = 15 */
movq $15, %rax
syscall
.global _sig_linux_trampoline_end
_sig_linux_trampoline_end: