X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Kernel%2Farch%2Fx86%2Fproc.c;h=a204b49cc98c94ebcfe8ee1037c5ece3e874d92e;hb=8a8a744341df513d00d2e60adf5e88636856e65b;hp=e9b4a681fb1317abb433893f4164cb8ec02c6313;hpb=2d83a99f3202f0e4688b58405f67604a24420861;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index e9b4a681..a204b49c 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -14,6 +14,7 @@ // === FLAGS === #define DEBUG_TRACE_SWITCH 0 +#define DEBUG_DISABLE_DOUBLEFAULT 1 // === CONSTANTS === #define SWITCH_MAGIC 0xFF5317C8 // FF SWITCH - There is no code in this area @@ -42,13 +43,12 @@ extern Uint GetEIP(void); // start.asm extern int GetCPUNum(void); // start.asm extern Uint32 gaInitPageDir[1024]; // start.asm extern char Kernel_Stack_Top[]; -extern tSpinlock glThreadListLock; +extern tShortSpinlock glThreadListLock; 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(void); +extern void Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack); // === PROTOTYPES === void ArchThreads_Init(void); @@ -56,11 +56,14 @@ void ArchThreads_Init(void); 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); @@ -286,7 +289,7 @@ void ArchThreads_Init(void) MM_FinishVirtualInit(); #endif - #if 0 + #if !DEBUG_DISABLE_DOUBLEFAULT // Initialise Double Fault TSS gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF; gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16; @@ -367,7 +370,10 @@ void ArchThreads_Init(void) #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(); @@ -444,8 +450,8 @@ void Proc_Start(void) for(;;) HALT(); // Just yeilds } gaCPUs[i].IdleThread = Threads_GetThread(tid); - gaCPUs[i].IdleThread->ThreadName = "Idle Thread"; - Threads_SetTickets( gaCPUs[i].IdleThread, 0 ); // Never called randomly + gaCPUs[i].IdleThread->ThreadName = (char*)"Idle Thread"; + Threads_SetPriority( gaCPUs[i].IdleThread, -1 ); // Never called randomly gaCPUs[i].IdleThread->Quantum = 1; // 1 slice quantum @@ -467,8 +473,8 @@ void Proc_Start(void) if(Proc_Clone(0, 0) == 0) { gpIdleThread = Proc_GetCurThread(); - gpIdleThread->ThreadName = "Idle Thread"; - gpIdleThread->NumTickets = 0; // Never called randomly + gpIdleThread->ThreadName = strdup("Idle Thread"); + Threads_SetPriority( gpIdleThread, -1 ); // Never called randomly gpIdleThread->Quantum = 1; // 1 slice quantum for(;;) HALT(); // Just yeilds } @@ -565,18 +571,27 @@ int Proc_Clone(Uint *Err, Uint Flags) // 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; // Set CR3 + #if USE_PAE + # warning "PAE Unimplemented" + #else newThread->MemState.CR3 = cur->MemState.CR3; + #endif // Create new KStack newThread->KernelStack = MM_NewKStack(); // Check for errors if(newThread->KernelStack == 0) { - free(newThread); + Threads_Kill(newThread, -2); return -1; } @@ -606,7 +621,7 @@ int Proc_Clone(Uint *Err, Uint Flags) __asm__ __volatile__ ("mov %0, %%db0" : : "r" (newThread) ); #if USE_MP // ACK the interrupt - if(GetCPUNum()) + if( GetCPUNum() ) gpMP_LocalAPIC->EOI.Val = 0; else #endif @@ -636,14 +651,11 @@ int Proc_SpawnWorker(void) 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(); @@ -674,7 +686,6 @@ int Proc_SpawnWorker(void) // Set EIP as parent new->SavedState.EIP = eip; // Mark as active - new->Status = THREAD_STAT_ACTIVE; Threads_AddActive( new ); return new->TID; @@ -698,7 +709,13 @@ Uint Proc_MakeUserStack(void) // 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; } @@ -829,7 +846,7 @@ void Proc_CallFaultHandler(tThread *Thread) { // Rewinds the stack and calls the user function // Never returns - __asm__ __volatile__ ("mov %0, %%ebp;\n\tcall Proc_ReturnToUser" :: "r"(Thread->FaultHandler)); + Proc_ReturnToUser( Thread->FaultHandler, Thread->CurFaultNum, Thread->KernelStack ); for(;;); } @@ -907,13 +924,6 @@ void Proc_Scheduler(int CPU) // 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) { @@ -921,14 +931,20 @@ void Proc_Scheduler(int CPU) } #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 }