* \fn tPAddr MM_GetPhysAddr(tVAddr Addr)
* \brief Checks if the passed address is accesable
*/
-tPAddr MM_GetPhysAddr(tVAddr Addr)
+tPAddr MM_GetPhysAddr(volatile const void *Addr)
{
- if( !(gaPageDir[Addr >> 22] & 1) )
+ tVAddr addr = (tVAddr)Addr;
+ if( !(gaPageDir[addr >> 22] & 1) )
return 0;
- if( !(gaPageTable[Addr >> 12] & 1) )
+ if( !(gaPageTable[addr >> 12] & 1) )
return 0;
- return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF);
+ return (gaPageTable[addr >> 12] & ~0xFFF) | (addr & 0xFFF);
}
/**
MM_RefPhys( gaTmpTable[i*1024+j] & ~0xFFF );
- tmp = (void *) MM_MapTemp( gaTmpTable[i*1024+j] & ~0xFFF );
+ tmp = MM_MapTemp( gaTmpTable[i*1024+j] & ~0xFFF );
memcpy( tmp, (void *)( (i*1024+j)*0x1000 ), 0x1000 );
- MM_FreeTemp( (Uint)tmp );
+ MM_FreeTemp( tmp );
}
}
for(base = MM_KERNEL_STACKS; base < MM_KERNEL_STACKS_END; base += MM_KERNEL_STACK_SIZE)
{
// Check if space is free
- if(MM_GetPhysAddr(base) != 0) continue;
+ if(MM_GetPhysAddr( (void*) base) != 0)
+ continue;
// Allocate
//for(i = MM_KERNEL_STACK_SIZE; i -= 0x1000 ; )
for(i = 0; i < MM_KERNEL_STACK_SIZE; i += 0x1000 )
// NOTE: Max of 1 page
// `page` is the last allocated page from the previious for loop
- tmpPage = MM_MapTemp( page );
+ tmpPage = (tVAddr)MM_MapTemp( page );
memcpy( (void*)( tmpPage + (0x1000 - ContentsSize) ), StackContents, ContentsSize);
- MM_FreeTemp(tmpPage);
+ MM_FreeTemp( (void*)tmpPage );
//Log("MM_NewWorkerStack: RETURN 0x%x", base);
return base + WORKER_STACK_SIZE;
tPAddr MM_DuplicatePage(tVAddr VAddr)
{
tPAddr ret;
- Uint temp;
+ void *temp;
int wasRO = 0;
//ENTER("xVAddr", VAddr);
// Copy Data
temp = MM_MapTemp(ret);
- memcpy( (void*)temp, (void*)VAddr, 0x1000 );
+ memcpy( temp, (void*)VAddr, 0x1000 );
MM_FreeTemp(temp);
// Restore Writeable status
* \brief Create a temporary memory mapping
* \todo Show Luigi Barone (C Lecturer) and see what he thinks
*/
-tVAddr MM_MapTemp(tPAddr PAddr)
+void * MM_MapTemp(tPAddr PAddr)
{
int i;
INVLPG( TEMP_MAP_ADDR + (i << 12) );
//LEAVE('p', TEMP_MAP_ADDR + (i << 12));
Mutex_Release( &glTempMappings );
- return TEMP_MAP_ADDR + (i << 12);
+ return (void*)( TEMP_MAP_ADDR + (i << 12) );
}
Mutex_Release( &glTempMappings );
Threads_Yield(); // TODO: Use a sleep queue here instead
* \fn void MM_FreeTemp(tVAddr PAddr)
* \brief Free's a temp mapping
*/
-void MM_FreeTemp(tVAddr VAddr)
+void MM_FreeTemp(void *VAddr)
{
- int i = VAddr >> 12;
+ int i = (tVAddr)VAddr >> 12;
//ENTER("xVAddr", VAddr);
if(i >= (TEMP_MAP_ADDR >> 12))
* \fn tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
* \brief Allocates a contigous number of pages
*/
-tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
+void *MM_MapHWPages(tPAddr PAddr, Uint Number)
{
- int i, j;
+ int j;
PAddr &= ~0xFFF;
-
+
+ if( PAddr < 1024*1024 && (1024*1024-PAddr) >= Number * PAGE_SIZE )
+ {
+ return (void*)(KERNEL_BASE + PAddr);
+ }
+
// Scan List
- for( i = 0; i < NUM_HW_PAGES; i ++ )
+ for( int i = 0; i < NUM_HW_PAGES; i ++ )
{
// Check if addr used
if( gaPageTable[ (HW_MAP_ADDR >> 12) + i ] & 1 )
MM_RefPhys( PAddr + (j<<12) );
gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] = (PAddr + (j<<12)) | 3;
}
- return HW_MAP_ADDR + (i<<12);
+ return (void*)(HW_MAP_ADDR + (i<<12));
}
}
// If we don't find any, return NULL
* \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 maxCheck = (1 << MaxBits);
tPAddr phys;
- tVAddr ret;
+ void *ret;
ENTER("iPages iMaxBits pPhysAddr", Pages, MaxBits, PhysAddr);
MaxBits = PHYS_BITS;
// Sanity Check
- if(MaxBits < 12 || !PhysAddr) {
+ if(MaxBits < 12) {
LEAVE('i', 0);
return 0;
}
- // Bound
- if(MaxBits >= PHYS_BITS) maxCheck = -1;
-
// Fast Allocate
if(Pages == 1 && MaxBits >= PHYS_BITS)
{
phys = MM_AllocPhys();
+ if( PhysAddr )
+ *PhysAddr = phys;
if( !phys ) {
- *PhysAddr = 0;
LEAVE_RET('i', 0);
}
- *PhysAddr = phys;
ret = MM_MapHWPages(phys, 1);
if(ret == 0) {
MM_DerefPhys(phys);
return 0;
}
LEAVE('x', ret);
- return ret;
+ return (void*)ret;
}
// Slow Allocate
return 0;
}
- *PhysAddr = phys;
+ if( PhysAddr )
+ *PhysAddr = phys;
LEAVE('x', ret);
- return ret;
+ return (void*)ret;
}
/**
int i, j;
//Log_Debug("VirtMem", "MM_UnmapHWPages: (VAddr=0x%08x, Number=%i)", VAddr, Number);
-
+
+ //
+ if( KERNEL_BASE <= VAddr && VAddr < KERNEL_BASE + 1024*1024 )
+ return ;
+
// Sanity Check
if(VAddr < HW_MAP_ADDR || VAddr+Number*0x1000 > HW_MAP_MAX) return;
{
MM_DerefPhys( gaPageTable[ i + j ] & ~0xFFF );
gaPageTable[ i + j ] = 0;
+ INVLPG( (tVAddr)(i+j) << 12 );
}
Mutex_Release( &glTempMappings );