extern int giNumCPUs;
extern int giNextTID;
extern tThread gThreadZero;
-extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
extern void Isr8(void); // Double Fault
extern void Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack);
void MP_StartAP(int CPU);
void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode);
#endif
-void Proc_Start(void);
-tThread *Proc_GetCurThread(void);
+//void Proc_Start(void);
+//tThread *Proc_GetCurThread(void);
void Proc_ChangeStack(void);
- int Proc_Clone(Uint *Err, Uint Flags);
+// int Proc_Clone(Uint *Err, Uint Flags);
+Uint Proc_MakeUserStack(void);
+void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize);
void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP);
+ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs);
void Proc_CallFaultHandler(tThread *Thread);
void Proc_Scheduler(int CPU);
#endif
// Create Per-Process Data Block
- MM_Allocate(MM_PPD_CFG);
+ if( !MM_Allocate(MM_PPD_CFG) )
+ {
+ Panic("OOM - No space for initiali Per-Process Config");
+ }
// Change Stacks
Proc_ChangeStack();
for(;;) HALT(); // Just yeilds
}
gaCPUs[i].IdleThread = Threads_GetThread(tid);
- gaCPUs[i].IdleThread->ThreadName = "Idle Thread";
+ gaCPUs[i].IdleThread->ThreadName = (char*)"Idle Thread";
Threads_SetPriority( gaCPUs[i].IdleThread, -1 ); // Never called randomly
gaCPUs[i].IdleThread->Quantum = 1; // 1 slice quantum
if(Proc_Clone(0, 0) == 0)
{
gpIdleThread = Proc_GetCurThread();
- gpIdleThread->ThreadName = "Idle Thread";
+ gpIdleThread->ThreadName = strdup("Idle Thread");
Threads_SetPriority( gpIdleThread, -1 ); // Never called randomly
gpIdleThread->Quantum = 1; // 1 slice quantum
for(;;) HALT(); // Just yeilds
// Initialise Memory Space (New Addr space or kernel stack)
if(Flags & CLONE_VM) {
newThread->MemState.CR3 = MM_Clone();
+ // Check for errors
+ if(newThread->MemState.CR3 == 0) {
+ Threads_Kill(newThread, -2);
+ return -1;
+ }
newThread->KernelStack = cur->KernelStack;
} else {
Uint tmpEbp, oldEsp = esp;
newThread->KernelStack = MM_NewKStack();
// Check for errors
if(newThread->KernelStack == 0) {
- free(newThread);
+ Threads_Kill(newThread, -2);
return -1;
}
cur = Proc_GetCurThread();
// Create new thread
- new = malloc( sizeof(tThread) );
+ new = Threads_CloneThreadZero();
if(!new) {
Warning("Proc_SpawnWorker - Out of heap space!\n");
return -1;
}
- memcpy(new, &gThreadZero, sizeof(tThread));
- // Set Thread ID
- new->TID = giNextTID++;
// Create a new worker stack (in PID0's address space)
// - The stack is relocated by this function
new->KernelStack = MM_NewWorkerStack();
// Allocate Stack - Allocate incrementally to clean up MM_Dump output
for( i = 0; i < USER_STACK_SZ/0x1000; i++ )
- MM_Allocate( base + (i<<12) );
+ {
+ if( !MM_Allocate( base + (i<<12) ) )
+ {
+ Warning("OOM: Proc_MakeUserStack");
+ return 0;
+ }
+ }
return base + USER_STACK_SZ;
}
// Update Kernel Stack pointer
gTSSs[CPU].ESP0 = thread->KernelStack-4;
- // Set address space
- #if USE_PAE
- # error "Todo: Implement PAE Address space switching"
- #else
- __asm__ __volatile__ ("mov %0, %%cr3" : : "a" (thread->MemState.CR3));
- #endif
-
#if 0
if(thread->SavedState.ESP > 0xC0000000
&& thread->SavedState.ESP < thread->KernelStack-0x2000) {
}
#endif
+ #if USE_PAE
+ # error "Todo: Implement PAE Address space switching"
+ #else
// Switch threads
__asm__ __volatile__ (
+ "mov %4, %%cr3\n\t" // Set address space
"mov %1, %%esp\n\t" // Restore ESP
"mov %2, %%ebp\n\t" // and EBP
"jmp *%3" : : // And return to where we saved state (Proc_Clone or Proc_Scheduler)
"a"(SWITCH_MAGIC), "b"(thread->SavedState.ESP),
- "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP)
+ "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP),
+ "r"(thread->MemState.CR3)
);
+ #endif
for(;;); // Shouldn't reach here
}