X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.c;h=0708540ed48f4bace9e1927d8c32d0f1094ad3bb;hb=83612bb37fbd8e84d90ecb9e6a7157aadd1e2175;hp=c9035e1bb6a90614f19da395106e5a04b733c8ab;hpb=ccd6cf2af99fdc050888c70eb4d59f078a15a2da;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index c9035e1b..0708540e 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -17,6 +17,7 @@ // === CONSTANTS === #define SWITCH_MAGIC 0xFFFACE55 // There is no code in this area // Base is 1193182 +#define TIMER_BASE 1193182 #define TIMER_DIVISOR 11931 //~100Hz // === TYPES === @@ -73,9 +74,11 @@ void Proc_Scheduler(int CPU); #if USE_MP volatile int giNumInitingCPUs = 0; tMPInfo *gMPFloatPtr = NULL; +volatile Uint32 giMP_TimerCount; // Start Count for Local APIC Timer tAPIC *gpMP_LocalAPIC = NULL; Uint8 gaAPIC_to_CPU[256] = {0}; tCPU gaCPUs[MAX_CPUS]; +tTSS gaTSSs[MAX_CPUS]; // TSS Array int giProc_BootProcessorID = 0; #else tThread *gCurrentThread = NULL; @@ -83,16 +86,16 @@ tThread *gCurrentThread = NULL; #if USE_PAE Uint32 *gPML4s[4] = NULL; #endif -tTSS *gTSSs = NULL; +tTSS *gTSSs = NULL; // Pointer to TSS array tTSS gTSS0 = {0}; // --- Error Recovery --- -char gaDoubleFaultStack[1024]; +char gaDoubleFaultStack[1024] __attribute__ ((section(".padata"))); tTSS gDoubleFault_TSS = { - .ESP0 = (Uint)&gaDoubleFaultStack[1023], + .ESP0 = (Uint)&gaDoubleFaultStack[1024], .SS0 = 0x10, .CR3 = (Uint)gaInitPageDir - KERNEL_BASE, .EIP = (Uint)Isr8, - .ESP = (Uint)&gaDoubleFaultStack[1023], + .ESP = (Uint)&gaDoubleFaultStack[1024], .CS = 0x08, .SS = 0x10, .DS = 0x10, .ES = 0x10, .FS = 0x10, .GS = 0x10, @@ -226,6 +229,8 @@ void ArchThreads_Init(void) } break; + + #if DUMP_MP_TABLES case 1: // Bus entSize = 8; Log("%i: Bus", i); @@ -263,6 +268,7 @@ void ArchThreads_Init(void) default: Log("%i: Unknown (%i)", i, ents->Type); break; + #endif } ents = (void*)( (Uint)ents + entSize ); } @@ -271,6 +277,7 @@ void ArchThreads_Init(void) Warning("Too many CPUs detected (%i), only using %i of them", giNumCPUs, MAX_CPUS); giNumCPUs = MAX_CPUS; } + gTSSs = gaTSSs; } else { Log("No MP Table was found, assuming uniprocessor\n"); @@ -283,6 +290,7 @@ void ArchThreads_Init(void) MM_FinishVirtualInit(); #endif + #if 0 // Initialise Double Fault TSS gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF; gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16; @@ -293,8 +301,34 @@ void ArchThreads_Init(void) gIDT[8].CS = 5<<3; gIDT[8].Flags = 0x8500; gIDT[8].OffsetHi = 0; + #endif + + // Set timer frequency + outb(0x43, 0x34); // Set Channel 0, Low/High, Rate Generator + outb(0x40, TIMER_DIVISOR&0xFF); // Low Byte of Divisor + outb(0x40, (TIMER_DIVISOR>>8)&0xFF); // High Byte #if USE_MP + // Get the count setting for APIC timer + Log("Determining APIC Count"); + __asm__ __volatile__ ("sti"); + while( giMP_TimerCount == 0 ) __asm__ __volatile__ ("hlt"); + __asm__ __volatile__ ("cli"); + Log("APIC Count %i", giMP_TimerCount); + { + Uint64 freq = giMP_TimerCount; + freq /= TIMER_DIVISOR; + freq *= TIMER_BASE; + if( (freq /= 1000) < 2*1000) + Log("Bus Frequency %i KHz", freq); + else if( (freq /= 1000) < 2*1000) + Log("Bus Frequency %i MHz", freq); + else if( (freq /= 1000) < 2*1000) + Log("Bus Frequency %i GHz", freq); + else + Log("Bus Frequency %i THz", freq); + } + // Initialise Normal TSS(s) for(pos=0;pos>8)&0xFF); // High Byte - // Create Per-Process Data Block MM_Allocate(MM_PPD_CFG); @@ -368,6 +399,8 @@ void MP_StartAP(int CPU) // Delay inb(0x80); inb(0x80); inb(0x80); inb(0x80); + // TODO: Use a better address, preferably registered with the MM + // - MM_AllocDMA mabye? // Create a far jump *(Uint8*)(KERNEL_BASE|0x11000) = 0xEA; // Far JMP *(Uint16*)(KERNEL_BASE|0x11001) = (Uint)&APStartup - (KERNEL_BASE|0xFFFF0); // IP @@ -387,18 +420,16 @@ void MP_StartAP(int CPU) */ void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode) { - Uint32 addr = (Uint)gpMP_LocalAPIC + 0x300; Uint32 val; // Hi val = (Uint)APICID << 24; - Log("*%p = 0x%08x", addr+0x10, val); - *(Uint32*)(addr+0x10) = val; - + Log("*%p = 0x%08x", &gpMP_LocalAPIC->ICR[1], val); + gpMP_LocalAPIC->ICR[1].Val = val; // Low (and send) val = ((DeliveryMode & 7) << 8) | (Vector & 0xFF); - Log("*%p = 0x%08x", addr, val); - *(Uint32*)addr = val; + Log("*%p = 0x%08x", &gpMP_LocalAPIC->ICR[0], val); + gpMP_LocalAPIC->ICR[0].Val = val; } #endif @@ -825,6 +856,8 @@ void Proc_Scheduler(int CPU) gCurrentThread = thread; #endif + //Log("CPU = %i", CPU); + // Update Kernel Stack pointer gTSSs[CPU].ESP0 = thread->KernelStack-4;