Fixes to x86_64 - Fixed MM_phys corrupting memory (forgot to initialise bitmap pointers)
authorJohn Hodge <[email protected]>
Sat, 31 Jul 2010 15:06:33 +0000 (23:06 +0800)
committerJohn Hodge <[email protected]>
Sat, 31 Jul 2010 15:06:33 +0000 (23:06 +0800)
- Some other changes to allow compilation against new threading code (not yet in tree)

Kernel/arch/x86_64/desctab.asm
Kernel/arch/x86_64/include/arch.h
Kernel/arch/x86_64/main.c
Kernel/arch/x86_64/mm_phys.c
Kernel/arch/x86_64/proc.c

index 039fe95..cf1b0f6 100644 (file)
@@ -3,6 +3,8 @@
 ;
 [BITS 64]
 
+[extern Log]
+
 %define NUM_IRQ_CALLBACKS      4
 
 MM_LOCALAPIC   equ     0xFFFFFD0000000000
@@ -171,11 +173,31 @@ IRQ_AddHandler:
        
        ; Assign the IRQ Callback
 .assign:
+       ; A little bit of debug
+       push rdi
+       push rsi
+       push rax
+       sub rsp, 8
+       mov rcx, rdi    ; IRQ Number
+       mov rdx, rsi    ; Callback
+       mov rsi, rax    ; Pointer
+       mov rdi, csIRQ_Assigned
+       call Log
+       add rsp, 8
+       pop rax
+       pop rsi
+       pop rdi
+
        mov [rax], rsi
        xor rax, rax
 
 .ret:
        ret
+       
+[section .rodata]
+csIRQ_Assigned:
+       db      "IRQ %p := %p (IRQ %i)",0
+[section .text]
 
 %macro ISR_NOERRNO     1
 Isr%1:
index fd54898..d419234 100644 (file)
@@ -37,10 +37,13 @@ typedef Uint64      size_t;
 
 typedef volatile int    tSpinlock;
 #define IS_LOCKED(lockptr)      (!!(*(tSpinlock*)lockptr))
-#define LOCK(lockptr)   do {int v=1;\
+#define _LOCK(lockptr,action)   do {int v=1;\
        while(v)\
        __asm__ __volatile__("lock xchgl %0, (%2)":"=r"(v):"r"(1),"r"(lockptr));\
+       if(v)   action;\
        }while(0)
+#define TIGHTLOCK(lockptr)   _LOCK(lockptr, __asm__ __volatile__ ("hlt"));
+#define LOCK(lockptr)   _LOCK(lockptr, Threads_Yield());
 #define RELEASE(lockptr)       __asm__ __volatile__("lock andl $0, (%0)"::"r"(lockptr));
 #define HALT()  __asm__ __volatile__ ("hlt")
 
index 5ea1934..7d69368 100644 (file)
@@ -36,6 +36,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                // Adjust Multiboot structure address
                mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE );
                gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE);
+               Log("gsBootCmdLine = '%s'", gsBootCmdLine);
                
                MM_InitPhys_Multiboot( mbInfo );        // Set up physical memory manager
                break;
@@ -45,6 +46,8 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
                return ;
        }
        
+       Log("gsBootCmdLine = '%s'", gsBootCmdLine);
+       
        *(Uint16*)(0xB8000) = 0x1F00|'D';
        Heap_Install();
        
index e5c28c2..55fc68a 100644 (file)
@@ -32,9 +32,9 @@ void  MM_DerefPhys(tPAddr PAddr);
 
 // === GLOBALS ===
 tSpinlock      glPhysicalPages;
-Uint64 *gaSuperBitmap; // 1 bit = 64 Pages, 16 MiB Per Word
-Uint64 *gaMainBitmap;  // 1 bit = 1 Page, 256 KiB per Word
-Uint64 *gaMultiBitmap; // Each bit means that the page is being used multiple times
+Uint64 *gaSuperBitmap = (void*)MM_PAGE_SUPBMP; // 1 bit = 64 Pages, 16 MiB Per Word
+Uint64 *gaMainBitmap = (void*)MM_PAGE_BITMAP;  // 1 bit = 1 Page, 256 KiB per Word
+Uint64 *gaMultiBitmap = (void*)MM_PAGE_DBLBMP; // Each bit means that the page is being used multiple times
 Uint32 *gaiPageReferences = (void*)MM_PAGE_COUNTS;     // Reference Counts
 tPAddr giFirstFreePage;        // First possibly free page
 Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES];    // Number of free pages in each range
@@ -208,9 +208,10 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot)
        
        LOG("Clearing multi bitmap");
        // Fill the bitmaps
-       memset(gaMultiBitmap, 0, numPages<<12);
+       memset(gaMultiBitmap, 0, (numPages<<12)/8);
        // - initialise to one, then clear the avaliable areas
-       memset(gaMainBitmap, -1, numPages<<12);
+       memset(gaMainBitmap, -1, (numPages<<12)/8);
+       memset(gaSuperBitmap, -1, (numPages<<12)/(8*64));
        LOG("Setting main bitmap");
        // - Clear all Type=1 areas
        LOG("Clearing valid regions");
index 2ee2d4a..8e7d24c 100644 (file)
 // Base is 1193182
 #define TIMER_DIVISOR  11931   //~100Hz
 
+// === TYPES ===
+typedef struct sCPU
+{
+       Uint8   APICID;
+       Uint8   State;  // 0: Unavaliable, 1: Idle, 2: Active
+       Uint16  Resvd;
+       tThread *Current;
+       tThread *IdleThread;
+}      tCPU;
+
 // === IMPORTS ===
 extern tGDT    gGDT[];
 extern void    APStartup(void);        // 16-bit AP startup code
@@ -32,10 +42,7 @@ extern int   giNextTID;
 extern int     giTotalTickets;
 extern int     giNumActiveThreads;
 extern tThread gThreadZero;
-extern tThread *gActiveThreads;
-extern tThread *gSleepingThreads;
-extern tThread *gDeleteThreads;
-extern tThread *Threads_GetNextToRun(int CPU);
+//extern tThread       *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump(void);
 extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
 extern void    Proc_ReturnToUser(void);
@@ -62,10 +69,8 @@ volatile int giNumInitingCPUs = 0;
 tMPInfo        *gMPFloatPtr = NULL;
 tAPIC  *gpMP_LocalAPIC = NULL;
 Uint8  gaAPIC_to_CPU[256] = {0};
-tCPU   gaCPUs[MAX_CPUS];
-#else
-tThread        *gCurrentThread = NULL;
 #endif
+tCPU   gaCPUs[MAX_CPUS];
 tTSS   *gTSSs = NULL;
 tTSS   gTSS0 = {0};
 // --- Error Recovery ---
@@ -284,11 +289,7 @@ void ArchThreads_Init(void)
        }
        #endif
        
-       #if USE_MP
        gaCPUs[0].Current = &gThreadZero;
-       #else
-       gCurrentThread = &gThreadZero;
-       #endif
        
        gThreadZero.MemState.CR3 = (Uint)gInitialPML4 - KERNEL_BASE;
        
@@ -338,8 +339,59 @@ void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode)
  */
 void Proc_Start(void)
 {
+       #if USE_MP
+        int    i;
+       #endif
+       
+       #if USE_MP
+       // Start APs
+       for( i = 0; i < giNumCPUs; i ++ )
+       {
+                int    tid;
+               if(i)   gaCPUs[i].Current = NULL;
+               
+               // Create Idle Task
+               if( (tid = Proc_Clone(0, 0)) == 0)
+               {
+                       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->Quantum = 1;      // 1 slice quantum
+               
+               
+               // Start the AP
+               if( i != giProc_BootProcessorID ) {
+                       MP_StartAP( i );
+               }
+       }
+       
+       // BSP still should run the current task
+       gaCPUs[0].Current = &gThreadZero;
+       
+       // Start interrupts and wait for APs to come up
+       Log("Waiting for APs to come up\n");
+       __asm__ __volatile__ ("sti");
+       while( giNumInitingCPUs )       __asm__ __volatile__ ("hlt");
+       #else
+       // Create Idle Task
+       if(Proc_Clone(0, 0) == 0)
+       {
+               gaCPUs[0].IdleThread = Proc_GetCurThread();
+               gaCPUs[0].IdleThread->ThreadName = "Idle Thread";
+               gaCPUs[0].IdleThread->NumTickets = 0;   // Never called randomly
+               gaCPUs[0].IdleThread->Quantum = 1;      // 1 slice quantum
+               for(;;) HALT(); // Just yeilds
+       }
+       
+       // Set current task
+       gaCPUs[0].Current = &gThreadZero;
+       
        // Start Interrupts (and hence scheduler)
        __asm__ __volatile__("sti");
+       #endif
+       MM_FinishVirtualInit();
 }
 
 /**
@@ -351,7 +403,7 @@ tThread *Proc_GetCurThread(void)
        #if USE_MP
        return gaCPUs[ GetCPUNum() ].Current;
        #else
-       return gCurrentThread;
+       return gaCPUs[ 0 ].Current;
        #endif
 }
 
@@ -674,31 +726,9 @@ void Proc_Scheduler(int CPU)
        
        // If the spinlock is set, let it complete
        if(IS_LOCKED(&glThreadListLock))        return;
-       
-       // Clear Delete Queue
-       while(gDeleteThreads)
-       {
-               thread = gDeleteThreads->Next;
-               if(gDeleteThreads->IsLocked) {  // Only free if structure is unused
-                       gDeleteThreads->Status = THREAD_STAT_NULL;
-                       free( gDeleteThreads );
-               }
-               gDeleteThreads = thread;
-       }
-       
-       // Check if there is any tasks running
-       if(giNumActiveThreads == 0) {
-               Log("No Active threads, sleeping");
-               __asm__ __volatile__ ("hlt");
-               return;
-       }
-       
+               
        // Get current thread
-       #if USE_MP
        thread = gaCPUs[CPU].Current;
-       #else
-       thread = gCurrentThread;
-       #endif
        
        // Reduce remaining quantum and continue timeslice if non-zero
        if(thread->Remaining--) return;
@@ -717,10 +747,11 @@ void Proc_Scheduler(int CPU)
        thread->SavedState.RIP = rip;
        
        // Get next thread
-       thread = Threads_GetNextToRun(CPU);
+       thread = Threads_GetNextToRun(CPU, thread);
        
        // Error Check
        if(thread == NULL) {
+               thread = gaCPUs[CPU].IdleThread;
                Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n");
                return;
        }
@@ -734,28 +765,13 @@ void Proc_Scheduler(int CPU)
        #endif
        
        // Set current thread
-       #if USE_MP
        gaCPUs[CPU].Current = thread;
-       #else
-       gCurrentThread = thread;
-       #endif
        
        // Update Kernel Stack pointer
        gTSSs[CPU].RSP0 = 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.RSP > 0xC0000000
-       && thread->SavedState.RSP < thread->KernelStack-0x2000) {
-               Log_Warning("Proc", "Possible bad ESP %p (PID %i)", thread->SavedState.ESP);
-       }
-       #endif
+       __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3));
        
        // Switch threads
        __asm__ __volatile__ (

UCC git Repository :: git.ucc.asn.au