X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.c;h=62980674215919ebd538b0ee2ce2f0403e2c1795;hb=e617614d9e5ca900649d584524eacef768b1f1b9;hp=98ba7e0cf225c9b7e0ea74af50658020251909dc;hpb=d52a53f035af92941c0cafe5f81888fed16d2462;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 98ba7e0c..62980674 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #if USE_MP @@ -15,10 +16,12 @@ // === CONSTANTS === #define SWITCH_MAGIC 0xFFFACE55 // There is no code in this area +// Base is 1193182 #define TIMER_DIVISOR 11931 //~100Hz // === IMPORTS === extern tGDT gGDT[]; +extern tIDT gIDT[]; extern void APStartup(); // 16-bit AP startup code extern Uint GetEIP(); // start.asm extern Uint32 gaInitPageDir[1024]; // start.asm @@ -35,7 +38,7 @@ extern tThread *gDeleteThreads; extern tThread *Threads_GetNextToRun(int CPU); extern void Threads_Dump(); extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags); -extern void Isr7(); +extern void Isr8(); // Double Fault // === PROTOTYPES === void ArchThreads_Init(); @@ -47,13 +50,15 @@ void Proc_Start(); tThread *Proc_GetCurThread(); void Proc_ChangeStack(); int Proc_Clone(Uint *Err, Uint Flags); +void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP); void Proc_Scheduler(); // === GLOBALS === // --- Multiprocessing --- #if USE_MP +volatile int giNumInitingCPUs = 0; tMPInfo *gMPFloatPtr = NULL; -tIOAPIC *gpMP_LocalAPIC = NULL; +tAPIC *gpMP_LocalAPIC = NULL; Uint8 gaAPIC_to_CPU[256] = {0}; tCPU gaCPUs[MAX_CPUS]; #else @@ -69,7 +74,12 @@ char gaDoubleFaultStack[1024]; tTSS gDoubleFault_TSS = { .ESP0 = (Uint)&gaDoubleFaultStack[1023], .SS0 = 0x10, - .EIP = (Uint)Isr7 + .CR3 = (Uint)gaInitPageDir - KERNEL_BASE, + .EIP = (Uint)Isr8, + .ESP = (Uint)&gaDoubleFaultStack[1023], + .CS = 0x08, .SS = 0x10, + .DS = 0x10, .ES = 0x10, + .FS = 0x10, .GS = 0x10, }; // === CODE === @@ -176,6 +186,12 @@ void ArchThreads_Init() Log("\t.CPUSignature = 0x%08x", ents->Proc.CPUSignature); Log("\t.FeatureFlags = 0x%08x", ents->Proc.FeatureFlags); + + if( !(ents->Proc.CPUFlags & 1) ) { + Log("DISABLED"); + break; + } + // Check if there is too many processors if(giNumCPUs >= MAX_CPUS) { giNumCPUs ++; // If `giNumCPUs` > MAX_CPUS later, it will be clipped @@ -189,7 +205,10 @@ void ArchThreads_Init() giNumCPUs ++; // Send IPI - MP_StartAP( giNumCPUs-1 ); + if( !(ents->Proc.CPUFlags & 2) ) + { + MP_StartAP( giNumCPUs-1 ); + } break; case 1: // Bus @@ -235,7 +254,11 @@ void ArchThreads_Init() if( giNumCPUs > MAX_CPUS ) { Warning("Too many CPUs detected (%i), only using %i of them", giNumCPUs, MAX_CPUS); + giNumCPUs = MAX_CPUS; } + + while( giNumInitingCPUs ) + MM_FinishVirtualInit(); Panic("Uh oh... MP Table Parsing is unimplemented\n"); } @@ -247,6 +270,7 @@ void ArchThreads_Init() #else giNumCPUs = 1; gTSSs = &gTSS0; + MM_FinishVirtualInit(); #endif // Initialise Double Fault TSS @@ -260,6 +284,17 @@ void ArchThreads_Init() gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16; gGDT[5].BaseHi = (Uint)&gDoubleFault_TSS >> 24; + Log_Debug("Proc", "gIDT[8] = {OffsetLo:%04x, CS:%04x, Flags:%04x, OffsetHi:%04x}", + gIDT[8].OffsetLo, gIDT[8].CS, gIDT[8].Flags, gIDT[8].OffsetHi); + gIDT[8].OffsetLo = 0; + gIDT[8].CS = 5<<3; + gIDT[8].Flags = 0x8500; + gIDT[8].OffsetHi = 0; + Log_Debug("Proc", "gIDT[8] = {OffsetLo:%04x, CS:%04x, Flags:%04x, OffsetHi:%04x}", + gIDT[8].OffsetLo, gIDT[8].CS, gIDT[8].Flags, gIDT[8].OffsetHi); + + //__asm__ __volatile__ ("xchg %bx, %bx"); + #if USE_MP // Initialise Normal TSS(s) for(pos=0;posAddr = 0; - return gaCPUs[ gaAPIC_to_CPU[gpMP_LocalAPIC->Value.Byte] ].Current; + return gaCPUs[ gaAPIC_to_CPU[gpMP_LocalAPIC->ID.Val&0xFF] ].Current; #else return gCurrentThread; #endif @@ -578,13 +621,18 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char ** while(*Bases) *--stack = *Bases++; *--stack = 0; // Return Address - delta = (Uint)stack; // Reuse delta to save SP - *--stack = ss; //Stack Segment - *--stack = delta; //Stack Pointer - *--stack = 0x0202; //EFLAGS (Resvd (0x2) and IF (0x20)) - *--stack = cs; //Code Segment - *--stack = Entrypoint; //EIP + Proc_StartProcess(ss, (Uint)stack, 0x202, cs, Entrypoint); +} + +void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) +{ + Uint *stack = (void*)Stack; + *--stack = SS; //Stack Segment + *--stack = Stack; //Stack Pointer + *--stack = Flags; //EFLAGS (Resvd (0x2) and IF (0x20)) + *--stack = CS; //Code Segment + *--stack = IP; //EIP //PUSHAD *--stack = 0xAAAAAAAA; // eax *--stack = 0xCCCCCCCC; // ecx @@ -595,10 +643,10 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char ** *--stack = 0x51515151; // esi *--stack = 0xB4B4B4B4; // ebp //Individual PUSHs - *--stack = ss; // ds - *--stack = ss; // es - *--stack = ss; // fs - *--stack = ss; // gs + *--stack = SS; // ds + *--stack = SS; // es + *--stack = SS; // fs + *--stack = SS; // gs __asm__ __volatile__ ( "mov %%eax,%%esp;\n\t" // Set stack pointer @@ -679,7 +727,7 @@ void Proc_Scheduler(int CPU) #if USE_MP thread = gaCPUs[CPU].Current; #else - curThread = gCurrentThread; + thread = gCurrentThread; #endif // Reduce remaining quantum and continue timeslice if non-zero @@ -723,7 +771,7 @@ void Proc_Scheduler(int CPU) #endif // Update Kernel Stack pointer - gTSSs[CPU].ESP0 = thread->KernelStack; + gTSSs[CPU].ESP0 = thread->KernelStack-4; // Set address space #if USE_PAE @@ -731,6 +779,14 @@ void Proc_Scheduler(int CPU) #else __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3)); #endif + + #if 0 + if(thread->SavedState.ESP > 0xC0000000 + && thread->SavedState.ESP < thread->KernelStack-0x2000) { + Log_Warning("Proc", "Possible bad ESP %p (PID %i)", thread->SavedState.ESP); + } + #endif + // Switch threads __asm__ __volatile__ ( "mov %1, %%esp\n\t" // Restore ESP