// --- Tempory Mappings ---
tVAddr MM_MapTemp(tPAddr PAddr)
{
- Log_KernelPanic("MM", "TODO: Implement MM_MapTemp");
+ const int max_slots = (MM_TMPMAP_END - MM_TMPMAP_BASE) / PAGE_SIZE;
+ tVAddr ret = MM_TMPMAP_BASE;
+ int i;
+
+ for( i = 0; i < max_slots; i ++, ret += PAGE_SIZE )
+ {
+ tPAddr *ent;
+ if( MM_GetPageEntryPtr( ret, 0, 1, 0, &ent) < 0 ) {
+ continue ;
+ }
+
+ if( *ent & 1 )
+ continue ;
+
+ *ent = PAddr | 3;
+ return ret;
+ }
return 0;
}
void MM_FreeTemp(tVAddr VAddr)
{
- Log_KernelPanic("MM", "TODO: Implement MM_FreeTemp");
+ MM_Deallocate(VAddr);
return ;
}
{
tPAddr ret;
int i;
- tVAddr kstackbase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE + 0x1000;
+ tVAddr kstackbase;
+
+ // tThread->KernelStack is the top
+ // There is 1 guard page below the stack
+ kstackbase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE + 0x1000;
+
+ Log("MM_Clone: kstackbase = %p", kstackbase);
// #1 Create a copy of the PML4
ret = MM_AllocPhys();
TMPCR3() = ret | 3;
INVLPG_ALL();
-// Log_KernelPanic("MM", "TODO: Implement MM_Clone");
-
// #3 Set Copy-On-Write to all user pages
for( i = 0; i < 256; i ++)
{
if( i == 509 ) continue;
// 510 0xFFFFFE8.. - Temp fractal mapping
if( i == 510 ) continue;
+
+ TMPMAPLVL4(i) = PAGEMAPLVL4(i);
+ if( TMPMAPLVL4(i) & 1 )
+ MM_RefPhys( TMPMAPLVL4(i) & PADDR_MASK );
}
// #5 Set fractal mapping
TMPMAPLVL4(509) = ret | 3;
TMPMAPLVL4(510) = 0; // Temp
- // #6 Create kernel stack
+ // #6 Create kernel stack (-1 to account for the guard)
TMPMAPLVL4(320) = 0;
for( i = 0; i < KERNEL_STACK_SIZE/0x1000-1; i ++ )
{
TMPCR3() = 0;
INVLPG_ALL();
Mutex_Release(&glMM_TempFractalLock);
+ Log("MM_Clone: RETURN %P\n", ret);
return ret;
}
// === FLAGS ===
#define DEBUG_TRACE_SWITCH 0
+//#define BREAK_ON_SWITCH 1 // Break into bochs debugger on a task switch
// === CONSTANTS ===
#define SWITCH_MAGIC 0x55ECAFFF##FFFACE55 // There is no code in this area
Log("Proc_Clone: Cloning VM");
newThread->MemState.CR3 = MM_Clone();
newThread->KernelStack = cur->KernelStack;
+// MAGIC_BREAK();
} else {
Uint tmp_rbp, old_rsp = rsp;
if(rip == SWITCH_MAGIC) {
outb(0x20, 0x20); // ACK Timer and return as child
__asm__ __volatile__ ("sti");
+// MAGIC_BREAK();
return 0;
}
// Set EIP as parent
new->SavedState.RIP = rip;
// Mark as active
- new->Status = THREAD_STAT_ACTIVE;
+ new->Status = THREAD_STAT_PREINIT;
Threads_AddActive( new );
return new->TID;
thread->SavedState.UserCS = regs->CS;
thread->SavedState.UserRIP = regs->RIP;
}
-
+
+ #if BREAK_ON_SWITCH
+ {
+ tThread *oldthread = thread;
+ #endif
+
// Get next thread
thread = Threads_GetNextToRun(CPU, thread);
if(thread == NULL) {
thread = gaCPUs[CPU].IdleThread;
//Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n");
- //LogF("Zzzzz.\n");
+// LogF("Zzzzz.\n");
//return;
}
+ if(thread == NULL ) {
+ return ;
+ }
+ #if BREAK_ON_SWITCH
+ if( thread != oldthread ) {
+ MAGIC_BREAK();
+ }
+ }
+ #endif
#if DEBUG_TRACE_SWITCH
LogF("Switching to task %i, CR3 = 0x%x, RIP = %p",
// Update Kernel Stack pointer
gTSSs[CPU].RSP0 = thread->KernelStack-4;
- // Set address space
- __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3));
-
// Switch threads
__asm__ __volatile__ (
+ "mov %4, %%cr3\n\t"
"mov %1, %%rsp\n\t" // Restore RSP
"mov %2, %%rbp\n\t" // and RBP
"jmp *%3" : : // And return to where we saved state (Proc_Clone or Proc_Scheduler)
- "a"(SWITCH_MAGIC), "b"(thread->SavedState.RSP),
- "d"(thread->SavedState.RBP), "c"(thread->SavedState.RIP)
+ "a"(SWITCH_MAGIC), "r"(thread->SavedState.RSP),
+ "r"(thread->SavedState.RBP), "r"(thread->SavedState.RIP),
+ "r"(thread->MemState.CR3)
);
for(;;); // Shouldn't reach here
}
int MinArgs; // Minimum number of arguments
int MaxArgs; // Maximum number of arguments
Uint IntArgs; // Bitmap of arguments that should be treated as integers
- void *Func; // Function pointer
- Uint OptDefaults[N_MAX_ARGS]; // Default values for optional arguments
+ int Index; //
+ const char *OptDefaults[N_MAX_ARGS]; // Default values for optional arguments
} tConfigCommand;
// === IMPORTS ===
tConfigFile *System_Int_ParseFile(char *File);
// === CONSTANTS ===
+enum eConfigCommands {
+ CC_LOADMODULE,
+ CC_SPAWN,
+ CC_MOUNT,
+ CC_SYMLINK,
+ CC_MKDIR,
+ CC_OPEN,
+ CC_CLOSE,
+ CC_IOCTL
+};
const tConfigCommand caConfigCommands[] = {
- {"module", 1,2, 00, Module_LoadFile, {(Uint)"",0}}, // Load a module from a file
- {"spawn", 1,1, 00, Proc_Spawn, {0}}, // Spawn a process
+ {"module", 1,2, 00, CC_LOADMODULE, {"",NULL}}, // Load a module from a file
+ {"spawn", 1,1, 00, CC_SPAWN, {NULL}}, // Spawn a process
// --- VFS ---
- {"mount", 3,4, 00, VFS_Mount, {(Uint)"",0}}, // Mount a device
- {"symlink", 2,2, 00, VFS_Symlink, {0}}, // Create a Symbolic Link
- {"mkdir", 1,1, 00, VFS_MkDir, {0}}, // Create a Directory
- {"open", 1,2, 00, VFS_Open, {VFS_OPENFLAG_READ,0}}, // Open a file
- {"close", 1,1, 01, VFS_Close, {0}}, // Close an open file
- {"ioctl", 3,3, 03, VFS_IOCtl, {0}}, // Call an IOCtl
+ {"mount", 3,4, 00, CC_MOUNT, {"",0}}, // Mount a device
+ {"symlink", 2,2, 00, CC_SYMLINK, {0}}, // Create a Symbolic Link
+ {"mkdir", 1,1, 00, CC_MKDIR, {0}}, // Create a Directory
+ {"open", 1,2, 00, CC_OPEN, {(void*)VFS_OPENFLAG_READ,0}}, // Open a file
+ {"close", 1,1, 01, CC_CLOSE, {0}}, // Close an open file
+ {"ioctl", 3,3, 03, CC_IOCTL, {0}}, // Call an IOCtl
- {"", 0,0, 0, NULL, {0}}
+ {"", 0,0, 0, 0, {0}}
};
#define NUM_CONFIG_COMMANDS (sizeof(caConfigCommands)/sizeof(caConfigCommands[0]))
// Find the command name
for( j = 0; j < NUM_CONFIG_COMMANDS; j++ )
{
- Uint args[N_MAX_ARGS];
+ const char *args[N_MAX_ARGS];
if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0) continue;
for( k = line->nParts-1; k--; )
{
if( k < 32 && (caConfigCommands[j].IntArgs & (1 << k)) ) {
- args[k] = atoi(line->Parts[k+1]);
+ args[k] = (const char *)(Uint)atoi(line->Parts[k+1]);
}
else {
- args[k] = (Uint)line->Parts[k+1];
+ args[k] = (char *)line->Parts[k+1];
}
- Log_Debug("Config", "args[%i] = 0x%x", k, args[k]);
+ Log_Debug("Config", "args[%i] = %p", k, args[k]);
+ }
+ switch( (enum eConfigCommands) caConfigCommands[j].Index )
+ {
+ case CC_LOADMODULE:
+ result = Module_LoadFile( args[0], args[1] );
+ break;
+ case CC_SPAWN:
+ result = Proc_Spawn( args[0] );
+ break;
+ case CC_MOUNT:
+ result = VFS_Mount( args[0], args[1], args[2], args[3] );
+ break;
+ case CC_SYMLINK:
+ result = VFS_Symlink( args[0], args[1] );
+ break;
+ case CC_OPEN:
+ result = VFS_Open( args[0], (Uint)args[1] );
+ break;
+ case CC_CLOSE:
+ VFS_Close( (Uint)args[0] );
+ result = 0;
+ break;
+ case CC_MKDIR:
+ result = VFS_MkDir( args[0] );
+ break;
+ case CC_IOCTL:
+ result = VFS_IOCtl( (Uint)args[0], (Uint)args[1], (void *)args[2] );
+ break;
}
- result = CallWithArgArray(caConfigCommands[j].Func, caConfigCommands[j].MaxArgs, args);
Log_Debug("Config", "result = %i", result);
break;
}