diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-08 14:00:04 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-08 14:00:04 +0200 |
| commit | 6dfe91e2f6d91011c57e0dd0858a7907f35bb71b (patch) | |
| tree | 41fe2cfb13c3c1e451212321eabbd723671dc6a4 | |
| parent | 2ac97283d813414973f83d177280aafa7fbaa66f (diff) | |
dev: Urgent patches regarding memory management.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
| -rw-r--r-- | dev/boot/src/HEL/AMD64/BootEFI.cc | 3 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 205 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 50 |
3 files changed, 72 insertions, 186 deletions
diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 4102d3b4..b7cda085 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -334,9 +334,6 @@ EFI_EXTERN_C EFI_API Int32 ModuleMain(EfiHandlePtr image_handle, Boot::ExitBootServices(map_key, image_handle); - handover_hdr->f_BitMapStart = (VoidPtr)((UIntPtr)reader_kernel.Blob() + (UIntPtr)handover_hdr->f_BitMapStart + reader_kernel.Size()); - handover_hdr->f_BitMapSize -= reader_kernel.Size(); - if (kernel_thread->Start(handover_hdr, YES) != kEfiOk) { // ------------------------------------------ // diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc index 6a9a89b7..c4898dfc 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc @@ -12,86 +12,47 @@ namespace Kernel::HAL { - typedef UInt32 PageTableIndex; + /// @brief Go over the Page structure and find the address of *virtual_address* - /***********************************************************************************/ - /// \brief Page store type. - /***********************************************************************************/ - struct PageStore final + UIntPtr hal_get_phys_address(VoidPtr virt) { - struct - { - PDE* fPde{nullptr}; - PTE* fPte{nullptr}; - VoidPtr fPAddr{nullptr}; - } fInternalStore; - - Bool fStoreOp{No}; // Store operation is in progress. - - bool IsValidPage(PTE* pte) - { - return pte && pte->Present; - } - - bool IsWRPage(PTE* pte) + const UInt64 vaddr = (UInt64)virt; + const UInt64 kMask9Bits = 0x1FFULL; + const UInt64 kPageOffsetMask = 0xFFFULL; + + UInt64 cr3 = (UInt64)hal_read_cr3() & ~kPageOffsetMask; + + // Level 4 + auto pml4 = reinterpret_cast<UInt64*>(cr3); + UInt64 pml4e = pml4[(vaddr >> 39) & kMask9Bits]; + if (!(pml4e & 1)) + return 0; + + // Level 3 + auto pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageOffsetMask); + UInt64 pdpte = pdpt[(vaddr >> 30) & kMask9Bits]; + if (!(pdpte & 1)) + return 0; + + // Level 2 + auto pd = reinterpret_cast<UInt64*>(pdpte & ~kPageOffsetMask); + UInt64 pde = pd[(vaddr >> 21) & kMask9Bits]; + if (!(pde & 1)) + return 0; + + // 1 GiB page support + if (pde & (1 << 7)) { - return pte && pte->Wr; + return (pde & ~((1ULL << 30) - 1)) | (vaddr & ((1ULL << 30) - 1)); } - bool IsUserPage(PTE* pte) - { - return pte && pte->User; - } - - static PageStore& The() - { - static PageStore the; - return the; - } - }; - - /// @brief Go over the Page structure and find the address of *virtual_address* - - UIntPtr hal_get_phys_address(VoidPtr virtual_address) - { - // Constants for table index bits - const UInt64 kPmlIndexMask = 0x1FFULL; // Mask for PML4, PDPT, PD, PT index (9 bits) - const UInt64 kPtIndexMask = 0xFFFULL; // Mask for page table index (12 bits) - - UInt64 cr3 = (UInt64)hal_read_cr3(); - - PageStore& page_store = PageStore::The(); - - // Extract the indices from the virtual address - UInt64 pml4_index = ((UIntPtr)virtual_address >> 39) & kPmlIndexMask; - UInt64 pdpt_index = ((UIntPtr)virtual_address >> 30) & kPmlIndexMask; - UInt64 pd_index = ((UIntPtr)virtual_address >> 21) & kPmlIndexMask; - UInt64 pt_index = ((UIntPtr)virtual_address >> 12) & kPmlIndexMask; - - page_store.fStoreOp = Yes; - - const auto kPmlEntrySize = 8; - - // Read the PML4 entry from memory - UInt64 pml4_base = cr3 & ~kPtIndexMask; // CR3 points to the PML4 table base, mask off lower bits - UInt64 pml4_entry = (pml4_base + pml4_index * kPmlEntrySize); // Each entry is 8 bytes - - // Read the PDPT entry - UInt64 pdpt_base = pml4_entry & ~kPtIndexMask; // Get the PDPT base physical address - UInt64 pdpt_entry = (pdpt_base + pdpt_index * kPmlEntrySize); - - // Read the PD entry - UInt64 pd_base = pdpt_entry & ~kPtIndexMask; // Get the Page Directory base physical address - UInt64 pd_entry = (pd_base + pd_index * kPmlEntrySize); - - // Read the PT entry - UInt64 pt_base = pd_entry & ~kPtIndexMask; // Get the Page Table base physical address - UInt64 pt_entry = (pt_base + pt_index * kPmlEntrySize); + // Level 1 + auto pt = reinterpret_cast<UInt64*>(pde & ~kPageOffsetMask); + UInt64 pte = pt[(vaddr >> 12) & kMask9Bits]; + if (!(pte & 1)) + return 0; - // Lastly, grab the pte entry. - NE_PDE* pde_struct = reinterpret_cast<NE_PDE*>(pt_base); - - return pde_struct->fEntries[pt_entry]->PhysicalAddress; + return (pte & ~kPageOffsetMask) | (vaddr & kPageOffsetMask); } /***********************************************************************************/ @@ -117,88 +78,40 @@ namespace Kernel::HAL /***********************************************************************************/ EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { - // Constants for table index bits - const UInt64 kPmlIndexMask = 0x1FFULL; // Mask for PML4, PDPT, PD, PT index (9 bits) - const UInt64 kPtIndexMask = 0xFFFULL; // Mask for page table index (12 bits) - - UInt64 cr3 = (UInt64)hal_read_cr3(); - - PageStore& page_store = PageStore::The(); - - // Extract the indices from the virtual address - UInt64 pml4_index = ((UIntPtr)virtual_address >> 39) & kPmlIndexMask; - UInt64 pdpt_index = ((UIntPtr)virtual_address >> 30) & kPmlIndexMask; - UInt64 pd_index = ((UIntPtr)virtual_address >> 21) & kPmlIndexMask; - UInt64 pt_index = ((UIntPtr)virtual_address >> 12) & kPmlIndexMask; - - page_store.fStoreOp = Yes; - - const auto kPmlEntrySize = 8; - - // Read the PML4 entry from memory - UInt64 pml4_base = cr3 & ~kPtIndexMask; // CR3 points to the PML4 table base, mask off lower bits - UInt64 pml4_entry = (pml4_base + pml4_index * kPmlEntrySize); // Each entry is 8 bytes + const UInt64 vaddr = (UInt64)virtual_address; + constexpr UInt64 kMask9 = 0x1FF; + constexpr UInt64 kPageMask = 0xFFF; - // Read the PDPT entry - UInt64 pdpt_base = pml4_entry & ~kPtIndexMask; // Get the PDPT base physical address - UInt64 pdpt_entry = (pdpt_base + pdpt_index * kPmlEntrySize); + UInt64 cr3 = (UIntPtr)hal_read_cr3() & ~kPageMask; - // Read the PD entry - UInt64 pd_base = pdpt_entry & ~kPtIndexMask; // Get the Page Directory base physical address - UInt64 pd_entry = (pd_base + pd_index * kPmlEntrySize); - - // Read the PT entry - UInt64 pt_base = pd_entry & ~kPtIndexMask; // Get the Page Table base physical address - UInt64 pt_entry = (pt_base + pt_index * kPmlEntrySize); - - // Lastly, grab the pte entry. - NE_PDE* pde_struct = reinterpret_cast<NE_PDE*>(pt_base); + auto pml4 = reinterpret_cast<UInt64*>(cr3); + UInt64 pml4e = pml4[(vaddr >> 39) & kMask9]; + if (!(pml4e & 1)) + return 1; - return mmi_map_page_table_entry(reinterpret_cast<UIntPtr>(virtual_address), (UInt32)(UInt64)physical_address, flags, pde_struct->fEntries[pt_entry], pde_struct); - } + auto pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageMask); + UInt64 pdpte = pdpt[(vaddr >> 30) & kMask9]; + if (!(pdpte & 1)) + return 1; - /***********************************************************************************/ - /// @brief Maps flags for a specific pte. - /// @internal Internal function. - /***********************************************************************************/ - STATIC Int32 mmi_map_page_table_entry(UIntPtr virtual_address, UInt32 physical_address, UInt32 flags, NE_PTE* pt_entry, NE_PDE* pd_entry) - { - if (!pt_entry) + auto pd = reinterpret_cast<UInt64*>(pdpte & ~kPageMask); + UInt64 pde = pd[(vaddr >> 21) & kMask9]; + if (!(pde & 1)) return 1; - pt_entry->Present = true; + auto pt = reinterpret_cast<UInt64*>(pde & ~kPageMask); + UInt64& pte = pt[(vaddr >> 12) & kMask9]; + // Set the new PTE + pte = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFULL) | 0x01ULL; // Present if (flags & kMMFlagsWr) - pt_entry->Wr = true; - else if (flags & ~kMMFlagsWr) - pt_entry->Wr = false; - - if (flags & kMMFlagsNX) - pt_entry->ExecDisable = true; - else if (flags & ~kMMFlagsNX) - pt_entry->ExecDisable = false; - + pte |= 1 << 1; // Writable if (flags & kMMFlagsUser) - pt_entry->User = true; - else if (flags & ~kMMFlagsUser) - pt_entry->User = false; - - pt_entry->PhysicalAddress = physical_address; - - hal_invl_tlb(reinterpret_cast<VoidPtr>(virtual_address)); - - mmi_page_status(pt_entry); - - PageStore& page_store = PageStore::The(); - - // Update Internal store. - - page_store.fInternalStore.fPde = pd_entry; - page_store.fInternalStore.fPte = pt_entry; - page_store.fInternalStore.fPAddr = (VoidPtr)(UIntPtr)physical_address; - - page_store.fStoreOp = No; + pte |= 1 << 2; // User + if (flags & kMMFlagsNX) + pte |= 1ULL << 63; // NX + hal_invl_tlb(virtual_address); return 0; } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 68a5b051..41aabca2 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -147,6 +147,10 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz return; } + if (size_buffer > mib_cast(4) || + sector_sz > kAHCISectorSize) + return; + if (!Write) { // Zero-memory the buffer field. @@ -167,9 +171,10 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz command_header->Cfl = sizeof(FisRegH2D) / sizeof(UInt32); command_header->Write = Write; - command_header->Prdtl = (UInt16)((size_buffer + kMaxPRDSize - 1) / kMaxPRDSize); + command_header->Prdtl = 1; - volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((VoidPtr)((UInt64)command_header->Ctba)); + auto ctba_phys = ((UInt64)command_header->Ctbau << 32) | command_header->Ctba; + auto command_table = reinterpret_cast<volatile HbaCmdTbl*>(ctba_phys); rt_set_memory((HbaCmdTbl*)command_table, 0, sizeof(HbaCmdTbl) + (command_header->Prdtl - 1) * sizeof(HbaPrdtEntry)); @@ -177,23 +182,11 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz UIntPtr buffer_phys = HAL::hal_get_phys_address(buffer); SizeT bytes_remaining = size_buffer; - SizeT prdt_count = command_header->Prdtl; - - for (UInt16 i = 0; i < prdt_count; ++i) - { - UInt32 chunk = bytes_remaining / prdt_count; - - if (chunk == 0) - break; - - command_table->Prdt[i].Dba = (UInt32)(buffer_phys & 0xFFFFFFFF); - command_table->Prdt[i].Dbau = (UInt32)(buffer_phys >> 32); - command_table->Prdt[i].Dbc = chunk - 1; - command_table->Prdt[i].Ie = 1; - buffer_phys += chunk; - bytes_remaining -= chunk; - } + command_table->Prdt[0].Dba = (UInt32)(buffer_phys & 0xFFFFFFFF); + command_table->Prdt[0].Dbau = (UInt32)(buffer_phys >> 32); + command_table->Prdt[0].Dbc = bytes_remaining - 1; + command_table->Prdt[0].Ie = 1; volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)(&command_table->Cfis[0]); @@ -214,29 +207,12 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz h2d_fis->CountLow = (size_buffer)&0xFF; h2d_fis->CountHigh = (size_buffer >> 8) & 0xFF; - while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) - { - ; - } - kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); - while (YES) + for (Int32 i = 0; i < 1000000; ++i) { if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break; - - if (kSATAHba->Is & kHBAErrTaskFile) - { - err_global_get() = kErrorDiskIsCorrupted; - return; - } - } - - /// we should wait again, just in case. - while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) - { - ; } if (kSATAHba->Is & kHBAErrTaskFile) @@ -454,7 +430,7 @@ namespace Kernel UInt16 sk_init_ahci_device(BOOL atapi) { UInt16 pi = 0; - + if (drv_std_init_ahci(pi, atapi)) kSATAPortsImplemented = pi; |
