* Implemented X86VMTranslationMapPAE and X86PagingStructuresPAE destruction.
* Implemented X86VMTranslationMapPAE::QueryInterrupt(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37100 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
99f806cc7f
commit
68b53104ba
@ -6,34 +6,46 @@
|
||||
|
||||
#include "paging/pae/X86PagingStructuresPAE.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <int.h>
|
||||
|
||||
#include "paging/pae/X86PagingMethodPAE.h"
|
||||
|
||||
|
||||
#if B_HAIKU_PHYSICAL_BITS == 64
|
||||
|
||||
|
||||
X86PagingStructuresPAE::X86PagingStructuresPAE()
|
||||
{
|
||||
fVirtualPageDirs[0] = NULL;
|
||||
}
|
||||
|
||||
|
||||
X86PagingStructuresPAE::~X86PagingStructuresPAE()
|
||||
{
|
||||
// TODO: Implement!
|
||||
panic("X86PagingStructuresPAE::~X86PagingStructuresPAE(): not implemented");
|
||||
// free the user page dirs
|
||||
free(fVirtualPageDirs[0]);
|
||||
|
||||
// free the PDPT page
|
||||
X86PagingMethodPAE::Method()->Free32BitPage(fPageDirPointerTable,
|
||||
pgdir_phys, fPageDirPointerTableHandle);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
X86PagingStructuresPAE::Init(
|
||||
pae_page_directory_pointer_table_entry* virtualPDPT,
|
||||
phys_addr_t physicalPDPT, pae_page_directory_entry* const* virtualPageDirs,
|
||||
phys_addr_t physicalPDPT, void* pdptHandle,
|
||||
pae_page_directory_entry* const* virtualPageDirs,
|
||||
const phys_addr_t* physicalPageDirs)
|
||||
{
|
||||
fPageDirPointerTable = virtualPDPT;
|
||||
pgdir_phys = physicalPDPT;
|
||||
fPageDirPointerTableHandle = pdptHandle;
|
||||
memcpy(fVirtualPageDirs, virtualPageDirs, sizeof(fVirtualPageDirs));
|
||||
memcpy(fPhysicalPageDirs, physicalPageDirs, sizeof(fPhysicalPageDirs));
|
||||
}
|
||||
@ -42,8 +54,10 @@ X86PagingStructuresPAE::Init(
|
||||
void
|
||||
X86PagingStructuresPAE::Delete()
|
||||
{
|
||||
// TODO: Implement!
|
||||
panic("X86PagingStructuresPAE::Delete(): not implemented");
|
||||
if (are_interrupts_enabled())
|
||||
delete this;
|
||||
else
|
||||
deferred_delete(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ struct X86PagingStructuresPAE : X86PagingStructures {
|
||||
|
||||
void Init(pae_page_directory_pointer_table_entry*
|
||||
virtualPDPT,
|
||||
phys_addr_t physicalPDPT,
|
||||
phys_addr_t physicalPDPT, void* pdptHandle,
|
||||
pae_page_directory_entry* const*
|
||||
virtualPageDirs,
|
||||
const phys_addr_t* physicalPageDirs);
|
||||
@ -31,6 +31,7 @@ struct X86PagingStructuresPAE : X86PagingStructures {
|
||||
|
||||
private:
|
||||
pae_page_directory_pointer_table_entry* fPageDirPointerTable;
|
||||
void* fPageDirPointerTableHandle;
|
||||
pae_page_directory_entry* fVirtualPageDirs[4];
|
||||
phys_addr_t fPhysicalPageDirs[4];
|
||||
};
|
||||
|
@ -43,7 +43,40 @@ X86VMTranslationMapPAE::X86VMTranslationMapPAE()
|
||||
|
||||
X86VMTranslationMapPAE::~X86VMTranslationMapPAE()
|
||||
{
|
||||
// TODO: Implement!
|
||||
if (fPagingStructures == NULL)
|
||||
return;
|
||||
|
||||
if (fPageMapper != NULL)
|
||||
fPageMapper->Delete();
|
||||
|
||||
// cycle through and free all of the user space page tables
|
||||
|
||||
STATIC_ASSERT(KERNEL_BASE == 0x80000000 && KERNEL_SIZE == 0x80000000);
|
||||
// assuming 1-1 split of the address space
|
||||
|
||||
for (uint32 k = 0; k < 2; k++) {
|
||||
pae_page_directory_entry* pageDir
|
||||
= fPagingStructures->VirtualPageDirs()[k];
|
||||
if (pageDir == NULL)
|
||||
continue;
|
||||
|
||||
for (uint32 i = 0; i < kPAEPageDirEntryCount; i++) {
|
||||
if ((pageDir[i] & X86_PAE_PDE_PRESENT) != 0) {
|
||||
phys_addr_t address = pageDir[i] & X86_PAE_PDE_ADDRESS_MASK;
|
||||
vm_page* page = vm_lookup_page(address / B_PAGE_SIZE);
|
||||
if (page == NULL)
|
||||
panic("X86VMTranslationMapPAE::~X86VMTranslationMapPAE: "
|
||||
"didn't find page table page: page address: %#"
|
||||
B_PRIxPHYSADDR ", virtual base: %#" B_PRIxADDR "\n",
|
||||
address,
|
||||
(k * kPAEPageDirEntryCount + i) * kPAEPageTableRange);
|
||||
DEBUG_PAGE_ACCESS_START(page);
|
||||
vm_page_set_state(page, PAGE_STATE_FREE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fPagingStructures->RemoveReference();
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +100,7 @@ X86VMTranslationMapPAE::Init(bool kernel)
|
||||
|
||||
// we already know the kernel pgdir mapping
|
||||
fPagingStructures->Init(method->KernelVirtualPageDirPointerTable(),
|
||||
method->KernelPhysicalPageDirPointerTable(),
|
||||
method->KernelPhysicalPageDirPointerTable(), NULL,
|
||||
method->KernelVirtualPageDirs(), method->KernelPhysicalPageDirs());
|
||||
} else {
|
||||
// user
|
||||
@ -124,7 +157,7 @@ X86VMTranslationMapPAE::Init(bool kernel)
|
||||
}
|
||||
|
||||
// init the paging structures
|
||||
fPagingStructures->Init(pdpt, physicalPDPT, virtualPageDirs,
|
||||
fPagingStructures->Init(pdpt, physicalPDPT, pdptHandle, virtualPageDirs,
|
||||
physicalPageDirs);
|
||||
}
|
||||
|
||||
@ -455,12 +488,48 @@ X86VMTranslationMapPAE::Query(addr_t virtualAddress,
|
||||
|
||||
|
||||
status_t
|
||||
X86VMTranslationMapPAE::QueryInterrupt(addr_t va, phys_addr_t *_physical,
|
||||
uint32 *_flags)
|
||||
X86VMTranslationMapPAE::QueryInterrupt(addr_t virtualAddress,
|
||||
phys_addr_t* _physicalAddress, uint32* _flags)
|
||||
{
|
||||
// TODO: Implement!
|
||||
panic("X86VMTranslationMapPAE::QueryInterrupt(): not implemented");
|
||||
return B_UNSUPPORTED;
|
||||
// default the flags to not present
|
||||
*_flags = 0;
|
||||
*_physicalAddress = 0;
|
||||
|
||||
// get the page directory entry
|
||||
pae_page_directory_entry* pageDirEntry
|
||||
= X86PagingMethodPAE::PageDirEntryForAddress(
|
||||
fPagingStructures->VirtualPageDirs(), virtualAddress);
|
||||
if ((*pageDirEntry & X86_PAE_PDE_PRESENT) == 0) {
|
||||
// no pagetable here
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// get the page table entry
|
||||
pae_page_table_entry* pageTable
|
||||
= (pae_page_table_entry*)X86PagingMethodPAE::Method()
|
||||
->PhysicalPageMapper()->InterruptGetPageTableAt(
|
||||
*pageDirEntry & X86_PAE_PDE_ADDRESS_MASK);
|
||||
pae_page_table_entry entry
|
||||
= pageTable[virtualAddress / B_PAGE_SIZE % kPAEPageTableEntryCount];
|
||||
|
||||
*_physicalAddress = entry & X86_PAE_PTE_ADDRESS_MASK;
|
||||
|
||||
// translate the page state flags
|
||||
if ((entry & X86_PAE_PTE_USER) != 0) {
|
||||
*_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_WRITE_AREA : 0)
|
||||
| B_READ_AREA;
|
||||
}
|
||||
|
||||
*_flags |= ((entry & X86_PAE_PTE_WRITABLE) != 0 ? B_KERNEL_WRITE_AREA : 0)
|
||||
| B_KERNEL_READ_AREA
|
||||
| ((entry & X86_PAE_PTE_DIRTY) != 0 ? PAGE_MODIFIED : 0)
|
||||
| ((entry & X86_PAE_PTE_ACCESSED) != 0 ? PAGE_ACCESSED : 0)
|
||||
| ((entry & X86_PAE_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0);
|
||||
|
||||
TRACE("X86VMTranslationMapPAE::Query(%#" B_PRIxADDR ") -> %#"
|
||||
B_PRIxPHYSADDR ":\n", *_physicalAddress, virtualAddress);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user