X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.c;h=8efe2a81bfe5937dbee10b94b38c82dd6b2d419c;hb=dcebc16c576aa98eb6a33047f4c4b2b69b30a1bc;hp=3c298fcee2aa65e56896dbc414f9838f3a0d7655;hpb=dc42c3998b01e66a609fed5d503a81a972e636d6;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 3c298fce..8efe2a81 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -45,7 +45,7 @@ extern void APStartup(void); // 16-bit AP startup code extern Uint GetEIP(void); // start.asm extern Uint GetEIP_Sched(void); // proc.asm extern void NewTaskHeader(tThread *Thread, void *Fcn, int nArgs, ...); // Actually takes cdecl args -extern Uint Proc_CloneInt(Uint *ESP, Uint *CR3); +extern Uint Proc_CloneInt(Uint *ESP, Uint32 *CR3); extern Uint32 gaInitPageDir[1024]; // start.asm extern char Kernel_Stack_Top[]; extern tShortSpinlock glThreadListLock; @@ -54,12 +54,15 @@ extern int giNextTID; extern tThread gThreadZero; extern void Isr8(void); // Double Fault extern void Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack); -extern void scheduler_return; // Return address in SchedulerBase -extern void IRQCommon; // Common IRQ handler code -extern void IRQCommon_handled; // IRQCommon call return location -extern void GetEIP_Sched_ret; // GetEIP call return location +extern char scheduler_return[]; // Return address in SchedulerBase +extern char IRQCommon[]; // Common IRQ handler code +extern char IRQCommon_handled[]; // IRQCommon call return location +extern char GetEIP_Sched_ret[]; // GetEIP call return location extern void Threads_AddToDelete(tThread *Thread); extern void SwitchTasks(Uint NewSP, Uint *OldSP, Uint NewIP, Uint *OldIO, Uint CR3); +extern void Proc_InitialiseSSE(void); +extern void Proc_SaveSSE(Uint DestPtr); +extern void Proc_DisableSSE(void); // === PROTOTYPES === //void ArchThreads_Init(void); @@ -71,11 +74,11 @@ void Proc_IdleThread(void *Ptr); //void Proc_Start(void); //tThread *Proc_GetCurThread(void); void Proc_ChangeStack(void); - int Proc_NewKThread(void (*Fcn)(void*), void *Data); +// int Proc_NewKThread(void (*Fcn)(void*), void *Data); // 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); +void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NORETURN; int Proc_Demote(Uint *Err, int Dest, tRegs *Regs); //void Proc_CallFaultHandler(tThread *Thread); //void Proc_DumpThreadCPUState(tThread *Thread); @@ -371,6 +374,9 @@ void ArchThreads_Init(void) { Panic("OOM - No space for initial Per-Process Config"); } + + // Initialise SSE support + Proc_InitialiseSSE(); // Change Stacks Proc_ChangeStack(); @@ -579,6 +585,7 @@ int Proc_NewKThread(void (*Fcn)(void*), void *Data) newThread->SavedState.ESP = esp; newThread->SavedState.EIP = (Uint)&NewTaskHeader; + newThread->SavedState.SSE = NULL; Log("New (KThread) %p, esp = %p\n", newThread->SavedState.EIP, newThread->SavedState.ESP); // MAGIC_BREAK(); @@ -616,6 +623,8 @@ int Proc_Clone(Uint Flags) return 0; } newThread->SavedState.EIP = eip; + newThread->SavedState.SSE = NULL; + newThread->SavedState.bSSEModified = 0; // Check for errors if( newThread->MemState.CR3 == 0 ) { @@ -656,8 +665,9 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data) // Save core machine state new->SavedState.ESP = new->KernelStack - sizeof(stack_contents); - new->SavedState.EBP = 0; new->SavedState.EIP = (Uint)NewTaskHeader; + new->SavedState.SSE = NULL; + new->SavedState.bSSEModified = 0; // Mark as active new->Status = THREAD_STAT_PREINIT; @@ -695,52 +705,37 @@ Uint Proc_MakeUserStack(void) return base + USER_STACK_SZ; } -/** - * \fn void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) - * \brief Starts a user task - */ -void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) +void Proc_StartUser(Uint Entrypoint, Uint Base, int ArgC, char **ArgV, int DataSize) { - Uint *stack = (void*)Proc_MakeUserStack(); + Uint *stack; int i; - Uint delta; + char **envp = NULL; Uint16 ss, cs; - //Log("stack = %p", stack); - - // Copy Arguments + // Copy data to the user stack and free original buffer + stack = (void*)Proc_MakeUserStack(); stack -= DataSize/sizeof(*stack); memcpy( stack, ArgV, DataSize ); + free(ArgV); - //Log("stack = %p", stack); - + // Adjust Arguments and environment if( DataSize ) { - // Adjust Arguments and environment - delta = (Uint)stack - (Uint)ArgV; + Uint delta = (Uint)stack - (Uint)ArgV; ArgV = (char**)stack; - for( i = 0; ArgV[i]; i++ ) - ArgV[i] += delta; - i ++; - - // Do we care about EnvP? - if( EnvP ) { - EnvP = &ArgV[i]; - for( i = 0; EnvP[i]; i++ ) - EnvP[i] += delta; - } + for( i = 0; ArgV[i]; i++ ) ArgV[i] += delta; + envp = &ArgV[i+1]; + for( i = 0; envp[i]; i++ ) envp[i] += delta; } // User Mode Segments ss = 0x23; cs = 0x1B; // Arguments - *--stack = (Uint)EnvP; + *--stack = (Uint)envp; *--stack = (Uint)ArgV; *--stack = (Uint)ArgC; - while(*Bases) - *--stack = *Bases++; - *--stack = 0; // Return Address + *--stack = Base; Proc_StartProcess(ss, (Uint)stack, 0x202, cs, Entrypoint); } @@ -864,7 +859,6 @@ void Proc_DumpThreadCPUState(tThread *Thread) return ; } - #if 1 tVAddr diffFromScheduler = Thread->SavedState.EIP - (tVAddr)SwitchTasks; tVAddr diffFromClone = Thread->SavedState.EIP - (tVAddr)Proc_CloneInt; tVAddr diffFromSpawn = Thread->SavedState.EIP - (tVAddr)NewTaskHeader; @@ -882,24 +876,6 @@ void Proc_DumpThreadCPUState(tThread *Thread) } if( diffFromScheduler > 0 && diffFromScheduler < 128 ) // When I last checked, GetEIP was at .+0x30 - #else - Uint32 data[3]; - MM_ReadFromAddrSpace(Thread->MemState.CR3, Thread->SavedState.EBP, data, 12); - if( data[1] == (Uint32)&IRQCommon + 25 ) - { - tRegs *regs = (void *) data[2]; - Log(" oldebp = 0x%08x, ret = 0x%08x, regs = 0x%x", - data[0], data[1], data[2] - ); - // [EBP] = old EBP - // [EBP+0x04] = Return Addr - // [EBP+0x08] = Arg 1 (CPU Number) - // [EBP+0x0C] = Arg 2 (Thread) - // [EBP+0x10] = GS (start of tRegs) - Log(" IRQ%i from %02x:%08x", regs->int_num regs->cs, regs->eip); - } - if( stack[1] == (Uint32)&scheduler_return ) - #endif { // Scheduled out Log(" At %04x:%08x", Thread->SavedState.UserCS, Thread->SavedState.UserEIP); @@ -914,7 +890,7 @@ void Proc_Reschedule(void) tThread *nextthread, *curthread; int cpu = GetCPUNum(); - // TODO: Wait for it? + // TODO: Wait for the lock? if(IS_LOCKED(&glThreadListLock)) return; curthread = Proc_GetCurThread(); @@ -940,11 +916,20 @@ void Proc_Reschedule(void) gTSSs[cpu].ESP0 = nextthread->KernelStack-4; __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) ); + // Save FPU/MMX/XMM/SSE state + if( curthread->SavedState.SSE ) + { + Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF ); + curthread->SavedState.bSSEModified = 0; + Proc_DisableSSE(); + } + SwitchTasks( nextthread->SavedState.ESP, &curthread->SavedState.ESP, nextthread->SavedState.EIP, &curthread->SavedState.EIP, nextthread->MemState.CR3 ); + return ; }