X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FKernel%2Farch%2Fx86%2Fmm_virt.c;h=b81698c30f4066fb15b15527220bf14b3805b983;hb=e7a76b0d8a0cc6aa77966509780973a6f8216ef7;hp=0eb60a18c1b03998d03075024ad66a07bef92d20;hpb=819ea8133d95cd688c47b4f688c2503db9a9bccd;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/mm_virt.c b/KernelLand/Kernel/arch/x86/mm_virt.c index 0eb60a18..b81698c3 100644 --- a/KernelLand/Kernel/arch/x86/mm_virt.c +++ b/KernelLand/Kernel/arch/x86/mm_virt.c @@ -17,6 +17,7 @@ #include #include #include +#include #define TAB 22 @@ -97,6 +98,7 @@ tPAddr MM_DuplicatePage(tVAddr VAddr); #define gaPAE_TmpPDPT ((tTabEnt*)PAE_TMP_PDPT_ADDR) int gbUsePAE = 0; tMutex glTempMappings; +tSemaphore gTempMappingsSem; tMutex glTempFractal; Uint32 gWorkerStacks[(NUM_WORKER_STACKS+31)/32]; int giLastUsedWorker = 0; @@ -117,6 +119,8 @@ void MM_PreinitVirtual(void) { gaInitPageDir[ PAGE_TABLE_ADDR >> 22 ] = ((tTabEnt)&gaInitPageDir - KERNEL_BASE) | 3; INVLPG( PAGE_TABLE_ADDR ); + + Semaphore_Init(&gTempMappingsSem, NUM_TEMP_PAGES, NUM_TEMP_PAGES, "MMVirt", "Temp Mappings"); } /** @@ -980,32 +984,29 @@ tPAddr MM_DuplicatePage(tVAddr VAddr) */ void * MM_MapTemp(tPAddr PAddr) { - int i; - //ENTER("XPAddr", PAddr); PAddr &= ~0xFFF; //LOG("glTempMappings = %i", glTempMappings); - for(;;) + if( Semaphore_Wait(&gTempMappingsSem, 1) != 1 ) + return NULL; + Mutex_Acquire( &glTempMappings ); + for( int i = 0; i < NUM_TEMP_PAGES; i ++ ) { - Mutex_Acquire( &glTempMappings ); - - for( i = 0; i < NUM_TEMP_PAGES; i ++ ) - { - // Check if page used - if(gaPageTable[ (TEMP_MAP_ADDR >> 12) + i ] & 1) continue; - // Mark as used - gaPageTable[ (TEMP_MAP_ADDR >> 12) + i ] = PAddr | 3; - INVLPG( TEMP_MAP_ADDR + (i << 12) ); - //LEAVE('p', TEMP_MAP_ADDR + (i << 12)); - Mutex_Release( &glTempMappings ); - return (void*)( TEMP_MAP_ADDR + (i << 12) ); - } + // Check if page used + if(gaPageTable[ (TEMP_MAP_ADDR >> 12) + i ] & 1) continue; + // Mark as used + gaPageTable[ (TEMP_MAP_ADDR >> 12) + i ] = PAddr | 3; + INVLPG( TEMP_MAP_ADDR + (i << 12) ); + //LEAVE('p', TEMP_MAP_ADDR + (i << 12)); Mutex_Release( &glTempMappings ); - Threads_Yield(); // TODO: Use a sleep queue here instead + return (void*)( TEMP_MAP_ADDR + (i << 12) ); } + Mutex_Release( &glTempMappings ); + Log_KernelPanic("MMVirt", "Semaphore suplied a mapping, but none are avaliable"); + return NULL; } /** @@ -1017,8 +1018,10 @@ void MM_FreeTemp(void *VAddr) int i = (tVAddr)VAddr >> 12; //ENTER("xVAddr", VAddr); - if(i >= (TEMP_MAP_ADDR >> 12)) + if(i >= (TEMP_MAP_ADDR >> 12)) { gaPageTable[ i ] = 0; + Semaphore_Signal(&gTempMappingsSem, 1); + } //LEAVE('-'); } @@ -1029,12 +1032,17 @@ void MM_FreeTemp(void *VAddr) */ 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 ) @@ -1137,7 +1145,11 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number) 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;