#define DEBUG 0
#define SANITY 1
#include <acess.h>
+#include <mm_virt.h>
#include <mm_phys.h>
#include <proc.h>
#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);
// === 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;
}
/**
- * \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;
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;
//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);
+
Panic("Page Fault at 0x%x (Accessed 0x%x)", Regs->eip, 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));
}
* \fn tVAddr MM_ClearUser()
* \brief Clear user's address space
*/
-tVAddr MM_ClearUser()
+tVAddr MM_ClearUser(void)
{
Uint i, j;
}
/**
- * \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;
}
/**
- * \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;
Uint i;
// Read-Only
if( Mask & MM_PFLAG_RO )
{
- if( Flags & MM_PFLAG_RO ) *ent &= ~PF_WRITE;
- else *ent |= PF_WRITE;
+ if( Flags & MM_PFLAG_RO ) {
+ *ent &= ~PF_WRITE;
+ }
+ else {
+ gaPageDir[VAddr >> 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
*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;
}
/**
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
+
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 );