From 1303ed4cedc2e01316d2d033f3dd0b50b190ef81 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 31 Dec 2009 11:14:38 +0800 Subject: [PATCH] Working on Multiprocessing support - Cleaned up SysFS debug - Fixed ByteSum() (now returns a byte) - Added character array functionality to %c (%Nc will print N chacters from the passed array) --- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/include/arch.h | 4 ++ Kernel/arch/x86/include/mp.h | 36 ++++++++++- Kernel/arch/x86/proc.c | 112 ++++++++++++++++++++++++--------- Kernel/debug.c | 13 +++- Kernel/drv/proc.c | 4 +- Kernel/lib.c | 6 +- Makefile.cfg | 2 +- 8 files changed, 138 insertions(+), 41 deletions(-) diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index e6ab2162..83042ca8 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 11 +BUILD_NUM = 18 diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 0afc51d0..ccd1875f 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -30,6 +30,10 @@ // Uses no advanced features # define USE_MP 0 # define USE_PAE 0 +#elif ARCH == i486 +// MP Only +# define USE_MP 1 +# define USE_PAE 0 #elif ARCH == i586 // All Enabled # define USE_MP 1 diff --git a/Kernel/arch/x86/include/mp.h b/Kernel/arch/x86/include/mp.h index f64cd0bf..c2e910d7 100644 --- a/Kernel/arch/x86/include/mp.h +++ b/Kernel/arch/x86/include/mp.h @@ -3,15 +3,45 @@ #ifndef _MP_H #define _MP_H -#define MPTABLE_IDENT ('_'|('M'<<8)|('P'<<16)|('_'<<24)) +#define MPPTR_IDENT ('_'|('M'<<8)|('P'<<16)|('_'<<24)) +#define MPTABLE_IDENT ('P'|('C'<<8)|('M'<<16)|('P'<<24)) typedef struct sMPInfo { - Uint Sig; // '_MP_' - Uint MPConfig; + Uint32 Sig; // '_MP_' + Uint32 MPConfig; Uint8 Length; Uint8 Version; Uint8 Checksum; Uint8 Features[5]; // 2-4 are unused } tMPInfo; +typedef struct sMPTable { + Uint32 Sig; + Uint16 BaseTableLength; + Uint8 SpecRev; + Uint8 Checksum; + + char OemID[8]; + char ProductID[12]; + + Uint32 OEMTablePtr; + Uint16 OEMTableSize; + Uint16 EntryCount; + + Uint32 LocalAPICMemMap; //!< Address used to access the local APIC + Uint16 ExtendedTableLen; + Uint8 ExtendedTableChecksum; + Uint8 Reserved; +} tMPTable; + +typedef struct sMPTable_Proc { + Uint8 Type; // 0x00 + Uint8 APICID; + Uint8 APICVer; + Uint8 CPUFlags; // bit 0: Disabled, bit 1: Boot Processor + Uint32 CPUSignature; // Stepping, Model, Family + Uint32 FeatureFlags; + Uint32 Reserved[2]; +} tMPTable_Proc; + #endif diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 2395c684..018b5632 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -52,15 +52,13 @@ tThread *gCurrentThread = NULL; #endif // --- Multiprocessing --- #if USE_MP -tMPInfo *gMPTable = NULL; +tMPInfo *gMPFloatPtr = NULL; #endif #if USE_PAE Uint32 *gPML4s[4] = NULL; #endif tTSS *gTSSs = NULL; -#if !USE_MP tTSS gTSS0 = {0}; -#endif // --- Error Recovery --- char gaDoubleFaultStack[1024]; tTSS gDoubleFault_TSS = { @@ -77,42 +75,82 @@ tTSS gDoubleFault_TSS = { void ArchThreads_Init() { Uint pos = 0; + #if USE_MP + tMPTable *mptable; + // -- Initialise Multiprocessing // Find MP Floating Table - // - EBDA - for(pos = KERNEL_BASE|0x9FC00; pos < (KERNEL_BASE|0xA0000); pos += 16) { - if( *(Uint*)(pos) == MPTABLE_IDENT ) { - if(ByteSum( (void*)pos, sizeof(tMPInfo) ) != 0) continue; - gMPTable = (void*)pos; + // - EBDA/Last 1Kib (640KiB) + for(pos = KERNEL_BASE|0x9F000; pos < (KERNEL_BASE|0xA0000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; break; } } - // - Last KiB - if(!gMPTable) { - + // - Last KiB (512KiB base mem) + if(!gMPFloatPtr) { + for(pos = KERNEL_BASE|0x7F000; pos < (KERNEL_BASE|0x80000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; + break; + } + } } // - BIOS ROM - if(!gMPTable) { - for(pos = KERNEL_BASE|0xF0000; pos < (KERNEL_BASE|0x100000); pos += 16) { - if( *(Uint*)(pos) == MPTABLE_IDENT ) { - if(ByteSum( (void*)pos, sizeof(tMPInfo) ) != 0) continue; - gMPTable = (void*)pos; + if(!gMPFloatPtr) { + for(pos = KERNEL_BASE|0xE0000; pos < (KERNEL_BASE|0x100000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; break; } } } // If the MP Table Exists, parse it - if(gMPTable) + if(gMPFloatPtr) { + Log("gMPFloatPtr = %p", gMPFloatPtr); + Log("*gMPFloatPtr = {"); + Log("\t.Sig = 0x%08x", gMPFloatPtr->Sig); + Log("\t.MPConfig = 0x%08x", gMPFloatPtr->MPConfig); + Log("\t.Length = 0x%02x", gMPFloatPtr->Length); + Log("\t.Version = 0x%02x", gMPFloatPtr->Version); + Log("\t.Checksum = 0x%02x", gMPFloatPtr->Checksum); + Log("\t.Features = [0x%02x,0x%02x,0x%02x,0x%02x,0x%02x]", + gMPFloatPtr->Features[0], gMPFloatPtr->Features[1], + gMPFloatPtr->Features[2], gMPFloatPtr->Features[3], + gMPFloatPtr->Features[4] + ); + Log("}"); + + mptable = (void*)( KERNEL_BASE|gMPFloatPtr->MPConfig ); + Log("mptable = %p", mptable); + Log("*mptable = {"); + Log("\t.Sig = 0x%08x", mptable->Sig); + Log("\t.BaseTableLength = 0x%04x", mptable->BaseTableLength); + Log("\t.SpecRev = 0x%02x", mptable->SpecRev); + Log("\t.Checksum = 0x%02x", mptable->Checksum); + Log("\t.OEMID = '%8c'", mptable->OemID); + Log("\t.ProductID = '%8c'", mptable->ProductID); + Log("}"); + Panic("Uh oh... MP Table Parsing is unimplemented\n"); - } else { - #endif + } + else { + Log("No MP Table was found, assuming uniprocessor\n"); giNumCPUs = 1; gTSSs = &gTSS0; - #if USE_MP } + #else + giNumCPUs = 1; + gTSSs = &gTSS0; #endif // Initialise Double Fault TSS @@ -247,7 +285,7 @@ void Proc_ChangeStack() *(Uint*)tmpEbp += newBase - curBase; } - gCurrentThread->KernelStack = newBase; + Proc_GetCurThread()->KernelStack = newBase; __asm__ __volatile__ ("mov %0, %%esp"::"r"(esp)); __asm__ __volatile__ ("mov %0, %%ebp"::"r"(ebp)); @@ -527,10 +565,17 @@ void Proc_Scheduler(int CPU) return; } + // Get current thread + #if USE_MP + thread = gCurrentThread[CPU]; + #else + curThread = gCurrentThread; + #endif + // Reduce remaining quantum and continue timeslice if non-zero - if(gCurrentThread->Remaining--) return; + if(thread->Remaining--) return; // Reset quantum for next call - gCurrentThread->Remaining = gCurrentThread->Quantum; + thread->Remaining = thread->Quantum; // Get machine state __asm__ __volatile__ ("mov %%esp, %0":"=r"(esp)); @@ -539,9 +584,9 @@ void Proc_Scheduler(int CPU) if(eip == SWITCH_MAGIC) return; // Check if a switch happened // Save machine state - gCurrentThread->SavedState.ESP = esp; - gCurrentThread->SavedState.EBP = ebp; - gCurrentThread->SavedState.EIP = eip; + thread->SavedState.ESP = esp; + thread->SavedState.EBP = ebp; + thread->SavedState.EIP = eip; // Get next thread thread = Threads_GetNextToRun(CPU); @@ -561,21 +606,28 @@ void Proc_Scheduler(int CPU) #endif // Set current thread + #if USE_MP + gCurrentThread[CPU] = thread; + #else gCurrentThread = thread; + #endif // Update Kernel Stack pointer gTSSs[CPU].ESP0 = thread->KernelStack; // Set address space - if( gCurrentThread->MemState.CR3 != 0 ) - __asm__ __volatile__ ("mov %0, %%cr3"::"a"(gCurrentThread->MemState.CR3)); + #if USE_PAE + # error "Todo: Implement PAE Address space switching" + #else + __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3)); + #endif // Switch threads __asm__ __volatile__ ( "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"(gCurrentThread->SavedState.ESP), - "d"(gCurrentThread->SavedState.EBP), "c"(gCurrentThread->SavedState.EIP) + "a"(SWITCH_MAGIC), "b"(thread->SavedState.ESP), + "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP) ); for(;;); // Shouldn't reach here } diff --git a/Kernel/debug.c b/Kernel/debug.c index b42459de..d9016419 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -152,7 +152,18 @@ void E9_Fmt(const char *format, va_list *args) if(!p) p = "(null)"; while(*p) E9(*p++); break; - + + // Single Character / Array + case 'c': + if(minSize == 1) { + E9(arg); + break; + } + p = (char*)(Uint)arg; + if(!p) goto printString; + while(minSize--) E9(*p++); + break; + default: E9(arg); break; } } diff --git a/Kernel/drv/proc.c b/Kernel/drv/proc.c index 82c84bbc..52a973c7 100644 --- a/Kernel/drv/proc.c +++ b/Kernel/drv/proc.c @@ -163,7 +163,7 @@ int SysFS_RegisterFile(char *Path, char *Data, int Length) ent->Node.ImplPtr = child; //else // gSysFS_DriverInfo.RootNode.ImplPtr = child; - // ^^^ Impossible (There is already /Version + // ^^^ Impossible (There is already /Version) } else prev->Next = child; @@ -171,7 +171,7 @@ int SysFS_RegisterFile(char *Path, char *Data, int Length) ent->Node.Size ++; else gSysFS_DriverInfo.RootNode.Size ++; - LOG("Added directory '%s'", child->Name); + Log("[SYSFS] Added directory '%s'", child->Name); } ent = child; diff --git a/Kernel/lib.c b/Kernel/lib.c index e5a02478..db014505 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -92,12 +92,12 @@ int strpos(const char *Str, char Ch) } /** - * \fn int ByteSum(void *Ptr, int Size) + * \fn Uint8 ByteSum(void *Ptr, int Size) * \brief Adds the bytes in a memory region and returns the sum */ -int ByteSum(void *Ptr, int Size) +Uint8 ByteSum(void *Ptr, int Size) { - int sum = 0; + Uint8 sum = 0; while(Size--) sum += *(Uint8*)Ptr++; return sum; } diff --git a/Makefile.cfg b/Makefile.cfg index 16a4b387..14ce84ba 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -16,7 +16,7 @@ xMKDIR = mmd xRMDIR = mdeltree xRM = mdel -ARCH = i386 +ARCH = i486 ARCHDIR = x86 FILESYSTEMS = fat -- 2.20.1