nullplan wrote:
Pretty sure those were not the inputs you were looking for.
Yeah, I don't know what I was thinking when I wrote that loop. with your code `info mem` returns just one line
Code:
0000000000000000-0000000000200000 0000000000200000 -rw
Which is correct but it's only the first page. the others are missing so something weird must be going on in the attach function.
nullplan wrote:
But beyond that, the output of your info mem also does not fit these values if paging_attach_2mb_page was working correctly, so something weird is going on there as well.
Exactly, I'm posting here the code for the new attach function with the correction you suggested before. Maybe you can spot something I missed.
Code:
#define PML_PRESENT (1ull << 0)
#define PML_READWRITE (1ull << 1)
#define PML_USER (1ull << 2)
#define PML_WRITETHROUGH (1ull << 3)
#define PML_CACHEDISABLE (1ull << 4)
#define PML_ACCESSED (1ull << 5)
#define PML_SIZE (1ull << 7)
#define PML_AVAILABLE (0b111ull << 9)
#define PML_ADDRESS (0xFFFFFFFFFFull << 12)
#define PML_EXECDISABLE (1ull << 63)
#define PML_CLEAR_AVAILABLE(entry) (entry &= ~PML_AVAILABLE)
#define PML_SET_AVAILABLE(entry, val) (entry |= (val & PML_AVAILABLE))
#define PML_UPDATE_AVAILABLE(entry, val) (PML_CLEAR_AVAILABLE(entry), PML_SET_AVAILABLE(entry, val))
#define PML_CLEAR_ADDRESS(entry) (entry &= ~PML_ADDRESS)
#define PML_SET_ADDRESS(entry, val) (entry |= (val & PML_ADDRESS))
#define PML_UPDATE_ADDRESS(entry, val) (PML_CLEAR_ADDRESS(entry), PML_SET_ADDRESS(entry, val))
void paging_attach_2mb_page(paging_data_t data, void* physical_addr, void* virtual_addr)
{
uint64_t pml4_offset = ((uint64_t)virtual_addr >> 39) & 0x01FF;
uint64_t pdp_offset = ((uint64_t)virtual_addr >> 30) & 0x01FF;
uint64_t pd_offset = ((uint64_t)virtual_addr >> 21) & 0x01FF;
uint64_t* pml4 = data;
if((pml4[pml4_offset] & PML_PRESENT) == 0)
{
uint64_t* pdp = pfa_alloc_page();
memset(pdp, 0, pfa_page_size());
pml4[pml4_offset] = (PML_PRESENT | PML_READWRITE) & ~PML_USER;
PML_UPDATE_ADDRESS(pml4[pml4_offset], (uint64_t)pdp);
}
uint64_t* pdp = (uint64_t*)((pml4[pml4_offset] & PML_ADDRESS));
if((pdp[pdp_offset] & PML_PRESENT) == 0)
{
uint64_t* pd = pfa_alloc_page();
memset(pd, 0, pfa_page_size());
pdp[pdp_offset] = (PML_PRESENT | PML_READWRITE) & ~PML_USER;
PML_UPDATE_ADDRESS(pdp[pdp_offset], (uint64_t)pd);
}
uint64_t* pd = (uint64_t*)((pdp[pdp_offset] & PML_ADDRESS));
pd[pd_offset] = (PML_PRESENT | PML_READWRITE | PML_SIZE) & ~PML_USER;
PML_UPDATE_ADDRESS(pd[pd_offset], (uint64_t)physical_addr);
}