The Pedigree Project
0.1
|
#include <VirtualAddressSpace.h>
Public Member Functions | |
virtual bool | isAddressValid (void *virtualAddress) |
virtual bool | isMapped (void *virtualAddress) |
virtual bool | map (physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags) |
virtual void | getMapping (void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags) |
virtual void | setFlags (void *virtualAddress, size_t newFlags) |
virtual void | unmap (void *virtualAddress) |
virtual void * | allocateStack () |
virtual void | freeStack (void *pStack) |
uintptr_t | getPageTableChunk (uintptr_t chunkIdx) |
Public Member Functions inherited from VirtualAddressSpace | |
virtual void * | expandHeap (ssize_t incr, size_t flags) |
virtual bool | mapHuge (physical_uintptr_t physAddress, void *virtualAddress, size_t count, size_t flags) |
virtual Stack * | allocateStack (size_t stackSz) |
virtual void | freeStack (Stack *pStack)=0 |
virtual VirtualAddressSpace * | clone (bool copyOnWrite=true)=0 |
virtual void | revertToKernelAddressSpace ()=0 |
virtual | ~VirtualAddressSpace () |
void | setHeap (void *heap, void *heapEnd) |
virtual bool | memIsInKernelHeap (void *pMem)=0 |
virtual bool | memIsInHeap (void *pMem)=0 |
virtual void * | getEndOfHeap ()=0 |
virtual uintptr_t | getKernelStart () const =0 |
virtual uintptr_t | getUserStart () const =0 |
virtual uintptr_t | getUserReservedStart () const =0 |
virtual uintptr_t | getDynamicLinkerAddress () const =0 |
virtual uintptr_t | getKernelHeapStart () const =0 |
virtual uintptr_t | getKernelHeapEnd () const =0 |
virtual uintptr_t | getKernelCacheStart () const =0 |
virtual uintptr_t | getKernelCacheEnd () const =0 |
virtual uintptr_t | getKernelEventBlockStart () const =0 |
virtual uintptr_t | getKernelModulesStart () const =0 |
virtual uintptr_t | getKernelModulesEnd () const =0 |
virtual uintptr_t | getDynamicStart () const |
virtual uintptr_t | getDynamicEnd () const |
virtual uintptr_t | getGlobalInfoBlock () const |
Protected Member Functions | |
virtual | ~MIPS32VirtualAddressSpace () |
Protected Member Functions inherited from VirtualAddressSpace | |
VirtualAddressSpace (void *Heap) | |
Private Member Functions | |
MIPS32VirtualAddressSpace () | |
MIPS32VirtualAddressSpace (const MIPS32VirtualAddressSpace &) | |
MIPS32VirtualAddressSpace & | operator= (const MIPS32VirtualAddressSpace &) |
void | setPageTableChunk (uintptr_t chunkIdx, uintptr_t chunkAddr) |
uintptr_t | generateNullChunk () |
Private Attributes | |
uintptr_t | m_pKusegDirectory [1024] |
Static Private Attributes | |
static uintptr_t | m_pKseg2Directory [512] |
static MIPS32VirtualAddressSpace | m_KernelSpace |
Friends | |
class | Processor |
VirtualAddressSpace & | VirtualAddressSpace::getKernelAddressSpace () |
Additional Inherited Members | |
Static Public Member Functions inherited from VirtualAddressSpace | |
static EXPORTED_PUBLIC VirtualAddressSpace & | getKernelAddressSpace () |
static VirtualAddressSpace * | create () |
Public Attributes inherited from VirtualAddressSpace | |
void * | m_Heap |
void * | m_HeapEnd |
Static Public Attributes inherited from VirtualAddressSpace | |
static const size_t | KernelMode = 0x01 |
static const size_t | Write = 0x02 |
static const size_t | Execute = 0x04 |
static const size_t | WriteThrough = 0x08 |
static const size_t | CacheDisable = 0x10 |
static const size_t | CopyOnWrite = 0x20 |
static const size_t | Swapped = 0x40 |
static const size_t | MemoryCoherent = 0x80 |
static const size_t | Guarded = 0x100 |
static const size_t | Shared = 0x200 |
static const size_t | WriteCombine = 0x400 |
static const size_t | Accessed = 0x800 |
static const size_t | Dirty = 0x1000 |
static const size_t | ClearDirty = 0x2000 |
static physical_uintptr_t | m_ZeroPage = 0 |
The X86VirtualAddressSpace implements the VirtualAddressSpace class for the mip32 processor, which means it encompasses paging (KUSEG) and KSEG0, KSEG1, KSEG2.
Virtual addressing on MIPS is a little complex. There are two paged areas - KUSEG and KSEG2. The former is intended for user applications and is located in the lower 2GB of the address space. The latter is intended for kernel use and is located in the highest 1GB of the address space. It is normal practice to store the current page table in KSEG2, so that a full 2MB of physical RAM doesn't have to be assigned per address space. However, this causes problems, as the MIPS TLB is rather small and it is possible that an entry for the page table doesn't exist, so a TLB refill will fault.
In this case, the CPU will double fault and enter our 'normal' exception entry point. The exception handler must fix up the TLB so that the piece of page table being accessed by the TLB refill handler is present. The CPU will then return to its original faulting instruction, fault again, but this time the TLB refill handler will be able to take care of the miss.
We consider the page table as a set of 4KB chunks. It is important to note that because the R4000 is in essence a 64-bit CPU, the design of the 'standard' page table is that each entry is 64 bits long. This gives us more bits to play with (in the 32-bit version), but doubles the size of the page table.
So the page table covers 4GB / 4KB = 1M pages, each entry being 2 words in size (64-bits) = 2M words.
But to map the page table into KSEG2, we split the page table down again into 4KB chunks, which means we have 2M / 1K (1K being 4KB / 4bytes per word) = 2048 words.
Here however, we have a problem. VirtualAddressSpace objects are part of Process objects, which are stored on the kernel heap (which is in KSEG2). So in order to fix up the page table which maps KSEG2, we need to do a lookup... in KSEG2!
Obviously this wouldn't work, so we set the page table entr(ies) containing this VirtualAddressSpace as a permanent (or 'wired') TLB entry. That way we can be certain that it will always be present.
One further optimisation is that while the KUSEG mappings will be different through each address space, the KSEG2 mappings will all be the same - we want the kernel heap to look the same from every address space! Thus, we can split our page table 'directory' into two chunks - the KUSEG chunk and the KSEG2 chunk (which will be static across all VirtualAddressSpace objects). This has the added advantage that we can get rid of mappings for the 1GB of KSEG0 and KSEG1 mappings in between KUSEG and KSEG2, as these areas aren't paged.
So that's 1024 words to map KUSEG, and 512 words to map KSEG2.
Definition at line 96 of file kernel/core/processor/mips32/VirtualAddressSpace.h.
|
protectedvirtual |
The destructor does nothing
Definition at line 61 of file mips32/VirtualAddressSpace.cc.
References PhysicalMemoryManager::freePage(), PhysicalMemoryManager::instance(), and m_pKusegDirectory.
|
private |
The constructor for already present paging structures
Definition at line 45 of file mips32/VirtualAddressSpace.cc.
References m_pKseg2Directory, and m_pKusegDirectory.
|
private |
The copy-constructor
|
virtual |
Allocates a single stack for a thread. Will use the default kernel thread size.
Implements VirtualAddressSpace.
Definition at line 300 of file mips32/VirtualAddressSpace.cc.
References Dec, ERROR, Hex, m_pKseg2Directory, m_pKusegDirectory, and NOTICE.
|
private |
Obtains a new physical frame and generates 'null' entries throughout.
Definition at line 328 of file mips32/VirtualAddressSpace.cc.
References PhysicalMemoryManager::allocatePage(), PhysicalMemoryManager::instance(), PAGE_SIZE, and panic().
Referenced by map().
|
virtual |
Get the physical address and the flags associated with the specific virtual address.
[in] | virtualAddress | the address in the virtual address space |
[out] | flags | the flags |
[out] | physicalAddress | the physical address |
Implements VirtualAddressSpace.
Definition at line 220 of file mips32/VirtualAddressSpace.cc.
References getPageTableChunk(), and panic().
uintptr_t MIPS32VirtualAddressSpace::getPageTableChunk | ( | uintptr_t | chunkIdx | ) |
Intended to be called solely by MIPS32TlbManager. Returns the physical address of the chunkIdx'th 4KB chunk of the page table.
Definition at line 283 of file mips32/VirtualAddressSpace.cc.
References Dec, ERROR, m_pKseg2Directory, and m_pKusegDirectory.
Referenced by getMapping(), MIPS32TlbManager::interrupt(), isMapped(), and map().
|
virtual |
Is a particular virtual address valid?
[in] | virtualAddress | the virtual address to check |
Implements VirtualAddressSpace.
Definition at line 73 of file mips32/VirtualAddressSpace.cc.
|
virtual |
Checks whether a mapping the the specific virtual address exists. Pages marked as swapped out are not considered mapped.
[in] | virtualAddress | the virtual address |
Implements VirtualAddressSpace.
Definition at line 79 of file mips32/VirtualAddressSpace.cc.
References getPageTableChunk(), and panic().
|
virtual |
Map a specific physical page (of size PhysicalMemoryManager::getPageSize()) at a specific location into the virtual address space.
[in] | physicalAddress | the address of the physical page that should be mapped into the virtual address space. |
[in] | virtualAddress | the virtual address at which the page apears within the virtual address space. |
[in] | flags | flags that describe which accesses should be allowed on the page. |
Implements VirtualAddressSpace.
Definition at line 120 of file mips32/VirtualAddressSpace.cc.
References VirtualAddressSpace::CacheDisable, generateNullChunk(), getPageTableChunk(), Hex, panic(), physicalAddress(), WARNING, and VirtualAddressSpace::Write.
|
private |
The copy-constructor
|
virtual |
Set the flags of the page at a specific virtual address.
[in] | virtualAddress | the virtual address |
[in] | newFlags | the flags |
Implements VirtualAddressSpace.
Definition at line 275 of file mips32/VirtualAddressSpace.cc.
|
virtual |
Remove the page at the specific virtual address from the virtual address space.
[in] | virtualAddress | the virtual address |
Implements VirtualAddressSpace.
Definition at line 279 of file mips32/VirtualAddressSpace.cc.
|
friend |
Processor::switchAddressSpace() needs access to m_PhysicalPageDirectory
Definition at line 100 of file kernel/core/processor/mips32/VirtualAddressSpace.h.
|
staticprivate |
The kernel virtual address space
Definition at line 150 of file kernel/core/processor/mips32/VirtualAddressSpace.h.
|
staticprivate |
Our 'directory' for KSEG2. Shared across all address spaces.
Definition at line 147 of file kernel/core/processor/mips32/VirtualAddressSpace.h.
Referenced by allocateStack(), getPageTableChunk(), and MIPS32VirtualAddressSpace().
|
private |
Our 'directory' - contains the physical address of each page table 'chunk' for KUSEG.
Definition at line 145 of file kernel/core/processor/mips32/VirtualAddressSpace.h.
Referenced by allocateStack(), getPageTableChunk(), MIPS32VirtualAddressSpace(), and ~MIPS32VirtualAddressSpace().