summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-04-08 14:00:04 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-04-08 14:00:04 +0200
commit6dfe91e2f6d91011c57e0dd0858a7907f35bb71b (patch)
tree41fe2cfb13c3c1e451212321eabbd723671dc6a4 /dev/kernel
parent2ac97283d813414973f83d177280aafa7fbaa66f (diff)
dev: Urgent patches regarding memory management.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel')
-rw-r--r--dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc205
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc50
2 files changed, 72 insertions, 183 deletions
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;