ASSERT(paddr != curpage);
- tmp = (void*)MM_MapTemp(paddr);
+ tmp = MM_MapTemp(paddr);
memcpy( tmp, NextLevel, 0x1000 );
- MM_FreeTemp( (tVAddr)tmp );
+ MM_FreeTemp( tmp );
#if TRACE_COW
Log_Debug("MMVirt", "COW ent at %p (%p) from %P to %P", Ent, NextLevel, curpage, paddr);
#define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
LogF("%016llx => ", CANOICAL(RangeStart));
// LogF("%6llx %6llx %6llx %016llx => ",
-// MM_GetPhysAddr( (tVAddr)&PAGEDIRPTR(RangeStart>>30) ),
-// MM_GetPhysAddr( (tVAddr)&PAGEDIR(RangeStart>>21) ),
-// MM_GetPhysAddr( (tVAddr)&PAGETABLE(RangeStart>>12) ),
+// MM_GetPhysAddr( &PAGEDIRPTR(RangeStart>>30) ),
+// MM_GetPhysAddr( &PAGEDIR(RangeStart>>21) ),
+// MM_GetPhysAddr( &PAGETABLE(RangeStart>>12) ),
// CANOICAL(RangeStart)
// );
if( gMM_ZeroPage && (PAGETABLE(RangeStart>>12) & PADDR_MASK) == gMM_ZeroPage )
expected |= expected_pml4 & PF_NX;
expected |= expected_pdp & PF_NX;
expected |= expected_pd & PF_NX;
- Log("expected (pml4 = %x, pdp = %x, pd = %x)",
- expected_pml4, expected_pdp, expected_pd);
+// Log("expected (pml4 = %x, pdp = %x, pd = %x)",
+// expected_pml4, expected_pdp, expected_pd);
// Dump
MM_int_DumpTablesEnt( rangeStart, curPos - rangeStart, expected );
expected = CHANGEABLE_BITS;
{
tPAddr phys;
- phys = MM_GetPhysAddr(VAddr);
+ phys = MM_GetPhysAddr( (void*)VAddr );
if(!phys) return ;
MM_Unmap(VAddr);
/**
* \brief Get the physical address of a virtual location
*/
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(volatile const void *Ptr)
{
+ tVAddr Addr = (tVAddr)Ptr;
tPAddr *ptr;
int ret;
Size += Addr & (PAGE_SIZE-1);
Addr &= ~(PAGE_SIZE-1);
- Addr &= ((1UL << 48)-1); // Clap to address space
+ // NC addr
+ if( ((Addr >> 47) & 1) != ((Addr>>48) == 0xFFFF))
+ return 0;
+ Addr &= ((1UL << 48)-1); // Clamp to address space
pml4 = Addr >> 39;
pdp = Addr >> 30;
dir = Addr >> 21;
tab = Addr >> 12;
- if( !(PAGEMAPLVL4(pml4) & 1) ) return 0;
- if( !(PAGEDIRPTR(pdp) & 1) ) return 0;
- if( !(PAGEDIR(dir) & 1) ) return 0;
- if( !(PAGETABLE(tab) & 1) ) return 0;
+ if( !(PAGEMAPLVL4(pml4) & 1) ) {
+ Log_Debug("MMVirt", "PML4E %i NP", pml4);
+ return 0;
+ }
+ if( !(PAGEDIRPTR(pdp) & 1) ) {
+ Log_Debug("MMVirt", "PDPE %i NP", pdp);
+ return 0;
+ }
+ if( !(PAGEDIR(dir) & 1) ) {
+ Log_Debug("MMVirt", "PDE %i NP", dir);
+ return 0;
+ }
+ if( !(PAGETABLE(tab) & 1) ) {
+ Log_Debug("MMVirt", "PTE %i NP", tab);
+ return 0;
+ }
bIsUser = !!(PAGETABLE(tab) & PF_USER);
while( Size >= PAGE_SIZE )
{
+ tab ++;
+ Size -= PAGE_SIZE;
+
if( (tab & 511) == 0 )
{
dir ++;
- if( ((dir >> 9) & 511) == 0 )
+ if( (dir & 511) == 0 )
{
pdp ++;
- if( ((pdp >> 18) & 511) == 0 )
+ if( (pdp & 511) == 0 )
{
pml4 ++;
- if( !(PAGEMAPLVL4(pml4) & 1) ) return 0;
+ if( !(PAGEMAPLVL4(pml4) & 1) ) {
+ Log_Debug("MMVirt", "IsValidBuffer - PML4E %x NP, Size=%x", pml4, Size);
+ return 0;
+ }
+ }
+ if( !(PAGEDIRPTR(pdp) & 1) ) {
+ Log_Debug("MMVirt", "IsValidBuffer - PDPE %x NP", pdp);
+ return 0;
}
- if( !(PAGEDIRPTR(pdp) & 1) ) return 0;
}
- if( !(PAGEDIR(dir) & 1) ) return 0;
+ if( !(PAGEDIR(dir) & 1) ) {
+ Log_Debug("MMVirt", "IsValidBuffer - PDE %x NP", dir);
+ return 0;
+ }
}
- if( !(PAGETABLE(tab) & 1) ) return 0;
- if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) return 0;
-
- tab ++;
- Size -= PAGE_SIZE;
+ if( !(PAGETABLE(tab) & 1) ) {
+ Log_Debug("MMVirt", "IsValidBuffer - PTE %x NP", tab);
+ return 0;
+ }
+ if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) {
+ Log_Debug("MMVirt", "IsValidBuffer - PTE %x Not user", tab);
+ return 0;
+ }
}
return 1;
}
/**
* \brief Map a range of hardware pages
*/
-tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
+void *MM_MapHWPages(tPAddr PAddr, Uint Number)
{
tVAddr ret;
int num;
{
for( num = Number; num -- && ret < MM_HWMAP_TOP; ret += 0x1000 )
{
- if( MM_GetPhysAddr(ret) != 0 ) break;
+ if( MM_GetPhysAddr( (void*)ret ) != 0 )
+ break;
}
if( num >= 0 ) continue;
MM_RefPhys(PAddr);
}
- return ret;
+ return (void*)ret;
}
Log_Error("MM", "MM_MapHWPages - No space for %i pages", Number);
// Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
while( Number -- )
{
- MM_DerefPhys( MM_GetPhysAddr(VAddr) );
+ MM_DerefPhys( MM_GetPhysAddr((void*)VAddr) );
MM_Unmap(VAddr);
VAddr += 0x1000;
}
* \param PhysAddr Pointer to the location to place the physical address allocated
* \return Virtual address allocate
*/
-tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
+void *MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr)
{
tPAddr phys;
- tVAddr ret;
+ void *ret;
// Sanity Check
if(MaxBits < 12 || !PhysAddr) return 0;
// Allocated successfully, now map
ret = MM_MapHWPages(phys, Pages);
+ *PhysAddr = phys;
// MapHWPages references the pages, so deref them back down to 1
for(;Pages--;phys+=0x1000)
MM_DerefPhys(phys);
return 0;
}
- *PhysAddr = phys;
return ret;
}
// --- Tempory Mappings ---
-tVAddr MM_MapTemp(tPAddr PAddr)
+void *MM_MapTemp(tPAddr PAddr)
{
const int max_slots = (MM_TMPMAP_END - MM_TMPMAP_BASE) / PAGE_SIZE;
tVAddr ret = MM_TMPMAP_BASE;
*ent = PAddr | 3;
MM_RefPhys(PAddr);
INVLPG(ret);
- return ret;
+ return (void*)ret;
}
return 0;
}
-void MM_FreeTemp(tVAddr VAddr)
+void MM_FreeTemp(void *Ptr)
{
- MM_Deallocate(VAddr);
+ MM_Deallocate((tVAddr)Ptr);
return ;
}
// --- Address Space Clone --
-tPAddr MM_Clone(void)
+tPAddr MM_Clone(int bNoUserCopy)
{
tPAddr ret;
int i;
INVLPG_ALL();
// #3 Set Copy-On-Write to all user pages
- if( Threads_GetPID() != 0 )
+ if( Threads_GetPID() != 0 && !bNoUserCopy )
{
for( i = 0; i < 256; i ++)
{
for( i = 1; i < KERNEL_STACK_SIZE/0x1000; i ++ )
{
tPAddr phys = MM_AllocPhys();
- tVAddr tmpmapping;
+ void *tmpmapping;
MM_MapEx(kstackbase+i*0x1000, phys, 1, 0);
tmpmapping = MM_MapTemp(phys);
- if( MM_GetPhysAddr( kstackbase+i*0x1000 ) )
- memcpy((void*)tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000);
+ if( MM_GetPhysAddr( (void*)(kstackbase+i*0x1000) ) )
+ memcpy(tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000);
else
- memset((void*)tmpmapping, 0, 0x1000);
+ memset(tmpmapping, 0, 0x1000);
// if( i == 0xF )
// Debug_HexDump("MM_Clone: *tmpmapping = ", (void*)tmpmapping, 0x1000);
MM_FreeTemp(tmpmapping);
Log_Error("MM", "MM_NewWorkerStack: StackSize(0x%x) > 0x1000, cbf handling", StackSize);
}
else {
- tVAddr tmp_addr, dest;
+ void *tmp_addr, *dest;
tmp_addr = MM_MapTemp(phys);
- dest = tmp_addr + (0x1000 - StackSize);
- memcpy( (void*)dest, StackData, StackSize );
- Log_Debug("MM", "MM_NewWorkerStack: %p->%p %i bytes (i=%i)", StackData, dest, StackSize, i);
- Log_Debug("MM", "MM_NewWorkerStack: ret = %p", ret);
+ dest = (char*)tmp_addr + (0x1000 - StackSize);
+ memcpy( dest, StackData, StackSize );
MM_FreeTemp(tmp_addr);
}
Uint i;
for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE )
{
- if(MM_GetPhysAddr(base+KERNEL_STACK_SIZE-0x1000) != 0)
+ if(MM_GetPhysAddr( (void*)(base+KERNEL_STACK_SIZE-0x1000) ) != 0)
continue;
//Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);