X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_virt.c;h=fdc19b148db5e8cdc7938e58241a27516f0b4c83;hb=2a05bcd81312a2885f824dac79e82c01a6e60c6c;hp=db89cc14facb922d2add9f6e2ead535d01920590;hpb=eb934b266052965b9c480d11d6866a994f30731b;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index db89cc14..fdc19b14 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -12,6 +12,7 @@ #define DEBUG 0 #define SANITY 1 #include +#include #include #include @@ -66,14 +67,15 @@ typedef Uint32 tTabEnt; #endif // === IMPORTS === +extern void _UsertextEnd, _UsertextBase; extern Uint32 gaInitPageDir[1024]; extern Uint32 gaInitPageTable[1024]; extern void Threads_SegFault(tVAddr Addr); extern void Error_Backtrace(Uint eip, Uint ebp); // === PROTOTYPES === -void MM_PreinitVirtual(); -void MM_InstallVirtual(); +void MM_PreinitVirtual(void); +void MM_InstallVirtual(void); void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs); void MM_DumpTables(tVAddr Start, tVAddr End); tPAddr MM_DuplicatePage(tVAddr VAddr); @@ -93,17 +95,17 @@ tPAddr MM_DuplicatePage(tVAddr VAddr); #define gaPAE_TmpDir ((tTabEnt*)PAE_TMP_DIR_ADDR) #define gaPAE_TmpPDPT ((tTabEnt*)PAE_TMP_PDPT_ADDR) int gbUsePAE = 0; - int gilTempMappings = 0; - int gilTempFractal = 0; +tMutex glTempMappings; +tMutex glTempFractal; Uint32 gWorkerStacks[(NUM_WORKER_STACKS+31)/32]; int giLastUsedWorker = 0; // === CODE === /** - * \fn void MM_PreinitVirtual() + * \fn void MM_PreinitVirtual(void) * \brief Maps the fractal mappings */ -void MM_PreinitVirtual() +void MM_PreinitVirtual(void) { #if USE_PAE gaInitPageDir[ ((PAGE_TABLE_ADDR >> TAB)-3*512+3)*2 ] = ((tTabEnt)&gaInitPageDir - KERNEL_BASE) | 3; @@ -114,10 +116,10 @@ void MM_PreinitVirtual() } /** - * \fn void MM_InstallVirtual() + * \fn void MM_InstallVirtual(void) * \brief Sets up the constant page mappings */ -void MM_InstallVirtual() +void MM_InstallVirtual(void) { int i; @@ -153,12 +155,17 @@ void MM_InstallVirtual() memset( &gaPageTable[i*1024], 0, 0x1000 ); } #endif + + // Unset kernel on the User Text pages + for( i = ((tVAddr)&_UsertextEnd-(tVAddr)&_UsertextBase+0xFFF)/4096; i--; ) { + MM_SetFlags( (tVAddr)&_UsertextBase + i*4096, 0, MM_PFLAG_KERNEL ); + } } /** * \brief Cleans up the SMP required mappings */ -void MM_FinishVirtualInit() +void MM_FinishVirtualInit(void) { #if USE_PAE gaInitPDPT[ 0 ] = 0; @@ -239,6 +246,19 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) //MM_DumpTables(0, -1); + // Register Dump + Log("EAX %08x ECX %08x EDX %08x EBX %08x", Regs->eax, Regs->ecx, Regs->edx, Regs->ebx); + Log("ESP %08x EBP %08x ESI %08x EDI %08x", Regs->esp, Regs->ebp, Regs->esi, Regs->edi); + //Log("SS:ESP %04x:%08x", Regs->ss, Regs->esp); + Log("CS:EIP %04x:%08x", Regs->cs, Regs->eip); + Log("DS %04x ES %04x FS %04x GS %04x", Regs->ds, Regs->es, Regs->fs, Regs->gs); + { + Uint dr0, dr1; + __ASM__ ("mov %%dr0, %0":"=r"(dr0):); + __ASM__ ("mov %%dr1, %0":"=r"(dr1):); + Log("DR0 %08x DR1 %08x", dr0, dr1); + } + Panic("Page Fault at 0x%x (Accessed 0x%x)", Regs->eip, Addr); } @@ -405,27 +425,11 @@ tPAddr MM_GetPhysAddr(tVAddr Addr) return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF); } - /** - * \fn int MM_IsUser(tVAddr VAddr) - * \brief Checks if a page is user accessable - */ -int MM_IsUser(tVAddr VAddr) -{ - if( !(gaPageDir[VAddr >> 22] & 1) ) - return 0; - if( !(gaPageTable[VAddr >> 12] & 1) ) - return 0; - if( !(gaPageTable[VAddr >> 12] & PF_USER) ) - return 0; - return 1; -} - -/** - * \fn void MM_SetCR3(tPAddr CR3) + * \fn void MM_SetCR3(Uint CR3) * \brief Sets the current process space */ -void MM_SetCR3(tPAddr CR3) +void MM_SetCR3(Uint CR3) { __asm__ __volatile__ ("mov %0, %%cr3"::"r"(CR3)); } @@ -487,7 +491,7 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr) * \fn tVAddr MM_ClearUser() * \brief Clear user's address space */ -tVAddr MM_ClearUser() +tVAddr MM_ClearUser(void) { Uint i, j; @@ -518,10 +522,10 @@ tVAddr MM_ClearUser() } /** - * \fn tPAddr MM_Clone() + * \fn tPAddr MM_Clone(void) * \brief Clone the current address space */ -tPAddr MM_Clone() +tPAddr MM_Clone(void) { Uint i, j; tVAddr ret; @@ -529,7 +533,7 @@ tPAddr MM_Clone() tVAddr kStackBase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE; void *tmp; - LOCK( &gilTempFractal ); + Mutex_Acquire( &glTempFractal ); // Create Directory Table *gpTmpCR3 = MM_AllocPhys() | 3; @@ -637,26 +641,27 @@ tPAddr MM_Clone() } ret = *gpTmpCR3 & ~0xFFF; - RELEASE( &gilTempFractal ); + Mutex_Release( &glTempFractal ); //LEAVE('x', ret); return ret; } /** - * \fn tVAddr MM_NewKStack() + * \fn tVAddr MM_NewKStack(void) * \brief Create a new kernel stack */ -tVAddr MM_NewKStack() +tVAddr MM_NewKStack(void) { - tVAddr base = KERNEL_STACKS; + tVAddr base; Uint i; - for(;base> 22] |= PF_WRITE; + *ent |= PF_WRITE; + } } // Kernel if( Mask & MM_PFLAG_KERNEL ) { - if( Flags & MM_PFLAG_KERNEL ) *ent &= ~PF_USER; - else *ent |= PF_USER; + if( Flags & MM_PFLAG_KERNEL ) { + *ent &= ~PF_USER; + } + else { + gaPageDir[VAddr >> 22] |= PF_USER; + *ent |= PF_USER; + } } // Copy-On-Write @@ -804,6 +819,33 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) *ent |= PF_WRITE; } } + + //Log("MM_SetFlags: *ent = 0x%08x, gaPageDir[%i] = 0x%08x", + // *ent, VAddr >> 22, gaPageDir[VAddr >> 22]); +} + +/** + * \brief Get the flags on a page + */ +Uint MM_GetFlags(tVAddr VAddr) +{ + tTabEnt *ent; + Uint ret = 0; + + // Validity Check + if( !(gaPageDir[VAddr >> 22] & 1) ) return 0; + if( !(gaPageTable[VAddr >> 12] & 1) ) return 0; + + ent = &gaPageTable[VAddr >> 12]; + + // Read-Only + if( !(*ent & PF_WRITE) ) ret |= MM_PFLAG_RO; + // Kernel + if( !(*ent & PF_USER) ) ret |= MM_PFLAG_KERNEL; + // Copy-On-Write + if( *ent & PF_COW ) ret |= MM_PFLAG_COW; + + return ret; } /** @@ -859,11 +901,11 @@ tVAddr MM_MapTemp(tPAddr PAddr) PAddr &= ~0xFFF; - //LOG("gilTempMappings = %i", gilTempMappings); + //LOG("glTempMappings = %i", glTempMappings); for(;;) { - LOCK( &gilTempMappings ); + Mutex_Acquire( &glTempMappings ); for( i = 0; i < NUM_TEMP_PAGES; i ++ ) { @@ -873,11 +915,11 @@ tVAddr MM_MapTemp(tPAddr PAddr) gaPageTable[ (TEMP_MAP_ADDR >> 12) + i ] = PAddr | 3; INVLPG( TEMP_MAP_ADDR + (i << 12) ); //LEAVE('p', TEMP_MAP_ADDR + (i << 12)); - RELEASE( &gilTempMappings ); + Mutex_Release( &glTempMappings ); return TEMP_MAP_ADDR + (i << 12); } - RELEASE( &gilTempMappings ); - Threads_Yield(); + Mutex_Release( &glTempMappings ); + Threads_Yield(); // TODO: Less expensive } } @@ -1004,20 +1046,23 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) void MM_UnmapHWPages(tVAddr VAddr, Uint Number) { int i, j; + + //Log_Debug("VirtMem", "MM_UnmapHWPages: (VAddr=0x%08x, Number=%i)", VAddr, Number); + // Sanity Check - if(VAddr < HW_MAP_ADDR || VAddr-Number*0x1000 > HW_MAP_MAX) return; + if(VAddr < HW_MAP_ADDR || VAddr+Number*0x1000 > HW_MAP_MAX) return; i = VAddr >> 12; - LOCK( &gilTempMappings ); // Temp and HW share a directory, so they share a lock + Mutex_Acquire( &glTempMappings ); // Temp and HW share a directory, so they share a lock for( j = 0; j < Number; j++ ) { - MM_DerefPhys( gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] ); - gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] = 0; + MM_DerefPhys( gaPageTable[ i + j ] & ~0xFFF ); + gaPageTable[ i + j ] = 0; } - RELEASE( &gilTempMappings ); + Mutex_Release( &glTempMappings ); } // --- EXPORTS ---