feat: add support for shutdown/reboot via UEFI Runtime Services
This commit is contained in:
@@ -267,4 +267,34 @@ namespace Memory::VMM {
|
||||
std::uint64_t Paging::GetPhysAddr(std::uint64_t virtualAddress) {
|
||||
return GetPhysAddr((std::uint64_t)PML4, virtualAddress, false);
|
||||
}
|
||||
|
||||
void Paging::MapEfiRuntime(limine_efi_memmap_response* efiMemmap) {
|
||||
if (!efiMemmap) return;
|
||||
|
||||
auto* base = (uint8_t*)efiMemmap->memmap;
|
||||
uint64_t descSize = efiMemmap->desc_size;
|
||||
uint64_t count = efiMemmap->memmap_size / descSize;
|
||||
|
||||
struct EfiMemDesc {
|
||||
uint32_t Type;
|
||||
uint64_t PhysicalStart;
|
||||
uint64_t VirtualStart;
|
||||
uint64_t NumberOfPages;
|
||||
uint64_t Attribute;
|
||||
};
|
||||
|
||||
static constexpr uint64_t EFI_MEMORY_RUNTIME = 0x8000000000000000ULL;
|
||||
|
||||
for (uint64_t i = 0; i < count; i++) {
|
||||
auto* desc = (EfiMemDesc*)(base + i * descSize);
|
||||
if (desc->Attribute & EFI_MEMORY_RUNTIME) {
|
||||
for (uint64_t p = 0; p < desc->NumberOfPages; p++) {
|
||||
uint64_t addr = desc->PhysicalStart + p * 0x1000;
|
||||
Map(addr, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlushTLB();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -108,10 +108,18 @@ public:
|
||||
|
||||
// Map a page into an arbitrary PML4 with User + Write-Combining attributes.
|
||||
static void MapUserInWC(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress);
|
||||
|
||||
// Identity-map EFI runtime service regions so firmware code can
|
||||
// reference its own data at physical addresses.
|
||||
void MapEfiRuntime(limine_efi_memmap_response* efiMemmap);
|
||||
};
|
||||
|
||||
extern Paging* g_paging;
|
||||
|
||||
extern "C" uint64_t GetCR3();
|
||||
extern "C" void LoadCR3(PageTable* PML4);
|
||||
|
||||
inline void FlushTLB() {
|
||||
asm volatile("mov %%cr3, %%rax; mov %%rax, %%cr3" ::: "rax", "memory");
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user