Kernel - Fixing and breaking SMP related stuff
authorJohn Hodge <[email protected]>
Sun, 4 Dec 2011 14:13:41 +0000 (22:13 +0800)
committerJohn Hodge <[email protected]>
Sun, 4 Dec 2011 14:13:41 +0000 (22:13 +0800)
Kernel/arch/x86/desctab.asm
Kernel/arch/x86/errors.c
Kernel/arch/x86/include/mm_virt.h
Kernel/arch/x86/kpanic.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.asm
Kernel/arch/x86/proc.c
Kernel/arch/x86/start.asm
Modules/USB/Core/usb_lowlevel.c
Modules/USB/UHCI/uhci.c

index fa7b84b..0c19fc0 100644 (file)
@@ -89,6 +89,7 @@ Desctab_Install:
        
        ; MP ISRs
        %if USE_MP
+       SETISR  0xED    ; 0xED Inter-processor HALT
        SETISR  0xEE    ; 0xEE Timer
        SETISR  0xEF    ; 0xEF Spurious Interrupt
        %endif
@@ -206,12 +207,21 @@ ISR_NOERR 31; 31: Reserved
 DEF_SYSCALL    0xAC    ; Acess System Call
 
 %if USE_MP
+[global Isr0xED]
+; 0xED - Interprocessor HALT
+Isr0xED:
+       cli
+.jmp:  hlt
+       jmp .jmp
+
 [global Isr0xEE]
 [extern SchedulerBase]
 ; AP's Timer Interrupt
 Isr0xEE:
-       push 0  ; Line up with interrupt number
-       xchg bx, bx     ; MAGIC BREAK
+       push eax        ; Line up with interrupt number
+       mov eax, dr1    ; CPU Number
+       push eax
+       mov eax, [esp-4]        ; Load EAX back
        jmp SchedulerBase
 ; Spurious Interrupt
 [global Isr0xEF]
index c66e49d..d73fcea 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <acess.h>
 #include <proc.h>
+#include <mm_virt.h>
 
 // === CONSTANTS ===
 #define        MAX_BACKTRACE   8       //!< Maximum distance to trace the stack backwards
@@ -233,6 +234,7 @@ void Error_Backtrace(Uint eip, Uint ebp)
        
        while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
        {
+               if( ebp >= MM_KERNEL_STACKS_END )       break;
                //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
                if(str == NULL)
                        LogF(" >> 0x%x", *(Uint*)(ebp+4));
index 4a11e71..31642c6 100644 (file)
 // 1024 items per page
 #define        MM_REFCOUNT_BASE        0xE4000000
 
+#define MM_KERNEL_STACKS       0xF0000000
+#define        MM_KERNEL_STACK_SIZE    0x00008000
+#define MM_KERNEL_STACKS_END   0xFC000000
+
 // === FUNCTIONS ===
 extern void    MM_FinishVirtualInit(void);
 extern void    MM_SetCR3(Uint CR3);
index ccb1073..6a7b9b0 100644 (file)
@@ -1,23 +1,34 @@
 /*
  * Acess 2 Kernel
- * By John Hodge (thePowersGang)
+ * - By John Hodge (thePowersGang)
+ * 
+ * kpanic.c
  * - x86 Kernel Panic Handler
  */
 
 #include <acess.h>
+#include <proc.h>
 
-
-
+// === CONSTANTS ===
 #define        FB      ((Uint16 *)(KERNEL_BASE|0xB8000))
 #define BGC    0x4F00  // White on Red
 //#define BGC  0xC000  // Black on Bright Red
 //#define BGC  0x1F00  // White on Blue (BSOD!)
 
+// === IMPORTS ===
 extern Uint32  GetEIP(void);
 extern void    Error_Backtrace(Uint32 eip, Uint32 ebp);
+#if USE_MP
+extern void    MP_SendIPIVector(int CPU, Uint8 Vector);
+extern int     giNumCPUs;
+extern int     GetCPUNum(void);
+#endif
 
- int   giKP_Pos = 0;
+// === PROTOTYPES ===
+void   KernelPanic_SetMode(void);
+void   KernelPanic_PutChar(char Ch);
 
+// === CONSTANTS ===
 const struct {
        Uint16  IdxPort;
        Uint16  DatPort;
@@ -57,9 +68,8 @@ const struct {
 };
 #define        NUM_REGVALUES   (sizeof(caRegValues)/sizeof(caRegValues[0]))
 
-// === PROTOTYPES ===
-void   KernelPanic_SetMode(void);
-void   KernelPanic_PutChar(char Ch);
+// === GLOBALS ===
+ int   giKP_Pos = 0;
 
 // === CODE ===
 /**
@@ -89,6 +99,16 @@ void KernelPanic_SetMode(void)
        inb(0x3DA);
        outb(0x3C0, 0x20);
        #endif
+
+       #if USE_MP
+       // Send halt to all processors
+       for( i = 0; i < giNumCPUs; i ++ )
+       {
+               if(i == GetCPUNum())    continue ;
+               FB[i] = BGC|'A'+i;
+               MP_SendIPIVector(i, 0xED);
+       }
+       #endif
        
        // Clear Screen
        for( i = 0; i < 80*25; i++ )
index af3d4bf..73e19d3 100644 (file)
 
 #define TAB    22
 
-#define KERNEL_STACKS          0xF0000000
-#define        KERNEL_STACK_SIZE       0x00008000
-#define KERNEL_STACKS_END      0xFC000000
 #define WORKER_STACKS          0x00100000      // Thread0 Only!
-#define        WORKER_STACK_SIZE       KERNEL_STACK_SIZE
+#define        WORKER_STACK_SIZE       MM_KERNEL_STACK_SIZE
 #define WORKER_STACKS_END      0xB0000000
 #define        NUM_WORKER_STACKS       ((WORKER_STACKS_END-WORKER_STACKS)/WORKER_STACK_SIZE)
 
@@ -125,7 +122,7 @@ void MM_InstallVirtual(void)
        {
                if( gaPageDir[ i ] )    continue;
                // Skip stack tables, they are process unique
-               if( i > KERNEL_STACKS >> 22 && i < KERNEL_STACKS_END >> 22) {
+               if( i > MM_KERNEL_STACKS >> 22 && i < MM_KERNEL_STACKS_END >> 22) {
                        gaPageDir[ i ] = 0;
                        continue;
                }
@@ -515,7 +512,7 @@ tPAddr MM_Clone(void)
        Uint    i, j;
        tVAddr  ret;
        Uint    page = 0;
-       tVAddr  kStackBase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE;
+       tVAddr  kStackBase = Proc_GetCurThread()->KernelStack - MM_KERNEL_STACK_SIZE;
        void    *tmp;
        
        Mutex_Acquire( &glTempFractal );
@@ -587,9 +584,7 @@ tPAddr MM_Clone(void)
        }
        
        // Allocate kernel stack
-       for(i = KERNEL_STACKS >> 22;
-               i < KERNEL_STACKS_END >> 22;
-               i ++ )
+       for(i = MM_KERNEL_STACKS >> 22; i < MM_KERNEL_STACKS_END >> 22; i ++ )
        {
                // Check if directory is allocated
                if( (gaPageDir[i] & 1) == 0 ) {
@@ -616,7 +611,7 @@ tPAddr MM_Clone(void)
                        }
                        
                        // We don't care about other kernel stacks
-                       if( ((i*1024+j)*4096 & ~(KERNEL_STACK_SIZE-1)) != kStackBase ) {
+                       if( ((i*1024+j)*4096 & ~(MM_KERNEL_STACK_SIZE-1)) != kStackBase ) {
                                gaTmpTable[i*1024+j] = 0;
                                continue;
                        }
@@ -647,27 +642,27 @@ tVAddr MM_NewKStack(void)
 {
        tVAddr  base;
        Uint    i;
-       for(base = KERNEL_STACKS; base < KERNEL_STACKS_END; base += KERNEL_STACK_SIZE)
+       for(base = MM_KERNEL_STACKS; base < MM_KERNEL_STACKS_END; base += MM_KERNEL_STACK_SIZE)
        {
                // Check if space is free
                if(MM_GetPhysAddr(base) != 0)   continue;
                // Allocate
-               //for(i = KERNEL_STACK_SIZE; i -= 0x1000 ; )
-               for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000 )
+               //for(i = MM_KERNEL_STACK_SIZE; i -= 0x1000 ; )
+               for(i = 0; i < MM_KERNEL_STACK_SIZE; i += 0x1000 )
                {
                        if( MM_Allocate(base+i) == 0 )
                        {
                                // On error, print a warning and return error
                                Warning("MM_NewKStack - Out of memory");
                                // - Clean up
-                               //for( i += 0x1000 ; i < KERNEL_STACK_SIZE; i += 0x1000 )
+                               //for( i += 0x1000 ; i < MM_KERNEL_STACK_SIZE; i += 0x1000 )
                                //      MM_Deallocate(base+i);
                                return 0;
                        }
                }
                // Success
-//             Log("MM_NewKStack - Allocated %p", base + KERNEL_STACK_SIZE);
-               return base+KERNEL_STACK_SIZE;
+//             Log("MM_NewKStack - Allocated %p", base + MM_KERNEL_STACK_SIZE);
+               return base+MM_KERNEL_STACK_SIZE;
        }
        // No stacks left
        Log_Warning("MMVirt", "MM_NewKStack - No address space left");
index 4e7d160..74a25d4 100644 (file)
@@ -162,8 +162,7 @@ SetAPICTimerCount:
        pop es
        pop ds
        popa
-       add esp, 4      ; CPU ID
-       ; No Error code / int num
+       add esp, 8      ; CPU ID / Error Code
        iret
 %endif
 ; --------------
@@ -376,3 +375,5 @@ User_Syscall_Exit:
        xor eax, eax
        mov ebx, [esp+4]
        int 0xAC
+
+; vim: ft=nasm, ts=8
index dfde359..9e8aa38 100644 (file)
@@ -14,7 +14,7 @@
 #include <hal_proc.h>
 
 // === FLAGS ===
-#define DEBUG_TRACE_SWITCH     0
+#define DEBUG_TRACE_SWITCH     1
 #define DEBUG_DISABLE_DOUBLEFAULT      1
 #define DEBUG_VERY_SLOW_SWITCH 0
 
@@ -34,7 +34,6 @@ typedef struct sCPU
        Uint8   State;  // 0: Unavaliable, 1: Idle, 2: Active
        Uint16  Resvd;
        tThread *Current;
-       tThread *IdleThread;
 }      tCPU;
 
 // === IMPORTS ===
@@ -66,6 +65,7 @@ extern void   Proc_DisableSSE(void);
 //void ArchThreads_Init(void);
 #if USE_MP
 void   MP_StartAP(int CPU);
+void   MP_SendIPIVector(int CPU, Uint8 Vector);
 void   MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode);
 #endif
 void   Proc_IdleThread(void *Ptr);
@@ -331,8 +331,8 @@ void ArchThreads_Init(void)
        Log("APIC Count %i", giMP_TimerCount);
        {
                Uint64  freq = giMP_TimerCount;
-               freq /= TIMER_DIVISOR;
                freq *= TIMER_BASE;
+               freq /= TIMER_DIVISOR;
                if( (freq /= 1000) < 2*1000)
                        Log("Bus Frequency %i KHz", freq);
                else if( (freq /= 1000) < 2*1000)
@@ -383,9 +383,12 @@ void ArchThreads_Init(void)
 }
 
 #if USE_MP
+/**
+ * \brief Start an AP
+ */
 void MP_StartAP(int CPU)
 {
-       Log("Starting AP %i (APIC %i)", CPU, gaCPUs[CPU].APICID);
+       Log_Log("Proc", "Starting AP %i (APIC %i)", CPU, gaCPUs[CPU].APICID);
        
        // Set location of AP startup code and mark for a warm restart
        *(Uint16*)(KERNEL_BASE|0x467) = (Uint)&APWait - (KERNEL_BASE|0xFFFF0);
@@ -409,11 +412,17 @@ void MP_StartAP(int CPU)
        giNumInitingCPUs ++;
 }
 
+void MP_SendIPIVector(int CPU, Uint8 Vector)
+{
+       MP_SendIPI(gaCPUs[CPU].APICID, Vector, 0);
+}
+
 /**
  * \brief Send an Inter-Processor Interrupt
  * \param APICID       Processor's Local APIC ID
  * \param Vector       Argument of some kind
- * \param DeliveryMode Type of signal?
+ * \param DeliveryMode Type of signal
+ * \note 3A 10.5 "APIC/Handling Local Interrupts"
  */
 void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode)
 {
@@ -421,23 +430,24 @@ void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode)
        
        // Hi
        val = (Uint)APICID << 24;
-       Log("*%p = 0x%08x", &gpMP_LocalAPIC->ICR[1], 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", &gpMP_LocalAPIC->ICR[0], val);
+//     Log("%p = 0x%08x", &gpMP_LocalAPIC->ICR[0], val);
        gpMP_LocalAPIC->ICR[0].Val = val;
 }
 #endif
 
 void Proc_IdleThread(void *Ptr)
 {
-       tCPU    *cpu = Ptr;
-       cpu->IdleThread->ThreadName = strdup("Idle Thread");
-       Threads_SetPriority( cpu->IdleThread, -1 );     // Never called randomly
-       cpu->IdleThread->Quantum = 1;   // 1 slice quantum
+       tCPU    *cpu = &gaCPUs[GetCPUNum()];
+       cpu->Current->ThreadName = strdup("Idle Thread");
+       Threads_SetPriority( cpu->Current, -1 );        // Never called randomly
+       cpu->Current->Quantum = 1;      // 1 slice quantum
        for(;;) {
-               HALT();
+               __asm__ __volatile__ ("sti");   // Make sure interrupts are enabled
+               __asm__ __volatile__ ("hlt");   // Make sure interrupts are enabled
                Proc_Reschedule();
        }
 }
@@ -461,7 +471,6 @@ void Proc_Start(void)
                
                // Create Idle Task
                tid = Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
-               gaCPUs[i].IdleThread = Threads_GetThread(tid);
                
                // Start the AP
                if( i != giProc_BootProcessorID ) {
@@ -473,7 +482,7 @@ void Proc_Start(void)
        gaCPUs[0].Current = &gThreadZero;
        
        // Start interrupts and wait for APs to come up
-       Log("Waiting for APs to come up\n");
+       Log_Debug("Proc", "Waiting for APs to come up");
        __asm__ __volatile__ ("sti");
        while( giNumInitingCPUs )       __asm__ __volatile__ ("hlt");
        #else
@@ -484,9 +493,6 @@ void Proc_Start(void)
        // Set current task
        gaCPUs[0].Current = &gThreadZero;
 
-//     while( gaCPUs[0].IdleThread == NULL )
-//             Threads_Yield();
-       
        // Start Interrupts (and hence scheduler)
        __asm__ __volatile__("sti");
        #endif
@@ -906,18 +912,21 @@ void Proc_Reschedule(void)
 
        nextthread = Threads_GetNextToRun(cpu, curthread);
 
-       if(!nextthread)
-               nextthread = gaCPUs[cpu].IdleThread;
        if(!nextthread || nextthread == curthread)
                return ;
 
        #if DEBUG_TRACE_SWITCH
-       LogF("\nSwitching to task %i, CR3 = 0x%x, EIP = %p, ESP = %p\n",
-               nextthread->TID,
-               nextthread->MemState.CR3,
-               nextthread->SavedState.EIP,
-               nextthread->SavedState.ESP
-               );
+       // HACK: Ignores switches to the idle threads
+       if( nextthread->TID == 0 || nextthread->TID > giNumCPUs )
+       {
+               LogF("\nSwitching CPU %i to %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n",
+                       GetCPUNum(),
+                       nextthread, nextthread->TID, nextthread->ThreadName,
+                       nextthread->MemState.CR3,
+                       nextthread->SavedState.EIP,
+                       nextthread->SavedState.ESP
+                       );
+       }
        #endif
 
        // Update CPU state
@@ -926,7 +935,7 @@ void Proc_Reschedule(void)
        __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) );
 
        // Save FPU/MMX/XMM/SSE state
-       if( curthread->SavedState.SSE )
+       if( curthread && curthread->SavedState.SSE )
        {
                Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
                curthread->SavedState.bSSEModified = 0;
index d504a5d..68bdc55 100644 (file)
@@ -120,6 +120,7 @@ APWait:
 .hlt:
        ;hlt
        jmp .hlt
+[extern Proc_Reschedule]
 [global APStartup]
 APStartup:
        ;xchg bx, bx    ; MAGIC BREAK!
@@ -160,11 +161,13 @@ APStartup:
        mov ebx, [ebp+0x20]     ; Read ID
        shr ebx, 24
        ;xchg bx, bx    ; MAGIC BREAK
-       ; CL is now local APIC ID
+       ; BL is now local APIC ID
        mov cl, BYTE [gaAPIC_to_CPU+ebx]
        xor ebx, ebx
        mov bl, cl
        ; BL is now the CPU ID
+       mov dr1, ebx    ; Save the CPU number to a debug register
+       ; Mark the CPU as up
        mov BYTE [gaCPUs+ebx*8+1], 1
        ; Decrement the remaining CPU count
        dec DWORD [giNumInitingCPUs]
@@ -179,8 +182,6 @@ APStartup:
        ; Set TSS
        lea ecx, [ebx*8+0x30]
        ltr cx
-       ; Save the CPU number to a debug register
-       mov dr1, ebx
        
        ;xchg bx, bx    ; MAGIC_BREAK
        ; Enable Local APIC
@@ -196,9 +197,10 @@ APStartup:
        mov DWORD [ebp+0x0B0], 0        ; Send an EOI (just in case)
        
        ; CPU is now marked as initialised
-       sti
-       ;xchg bx, bx    ; MAGIC BREAK
+
 .hlt:
+       sti
+       call Proc_Reschedule    
        hlt
        jmp .hlt
 %endif
@@ -252,4 +254,5 @@ ALIGN 4096
 Kernel_Stack_Top:
 gInitAPStacks:
        times 32*MAX_CPUS       dd      0
-       
+
+; vim: ft=nasm ts=8    
index 65365d3..0e53bad 100644 (file)
@@ -122,8 +122,15 @@ char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index)
        struct sDescriptor_String       str;
         int    src_len, new_len;
        char    *ret;
+
+       if(Index == 0)  return strdup("");
        
        USB_int_ReadDescriptor(Dev, Endpoint, 3, Index, sizeof(str), &str);
+       if(str.Length < 2) {
+               Log_Error("USB", "String %p:%i:%i:%i descriptor is undersized (%i)",
+                       Dev->Host, Dev->Address, Endpoint, Index, str.Length);
+               return NULL;
+       }
 //     if(str.Length > sizeof(str)) {
 //             // IMPOSSIBLE!
 //             Log_Error("USB", "String is %i bytes, which is over prealloc size (%i)",
index 5ea3566..9ef8b0b 100644 (file)
@@ -97,8 +97,6 @@ int UHCI_Initialise(char **Arguments)
                cinfo->RootHub = USB_RegisterHost(&gUHCI_HostDef, cinfo, 2);
                LOG("cinfo->RootHub = %p", cinfo->RootHub);
 
-               UHCI_CheckPortUpdate(cinfo);
-
                i ++;
        }
 
@@ -271,7 +269,7 @@ int UHCI_IsTransferComplete(void *Ptr, void *Handle)
        ret = !(td->Control & (1 << 23));
        if(ret) {
                td->_info.Callback = NULL;
-               td->Link = 1;
+               td->Link = 0;
        }
        return ret;
 }
@@ -399,7 +397,7 @@ void UHCI_InterruptHandler(int IRQ, void *Ptr)
                                }
                                link = td->Link;
                                if( td->_info.Callback != INVLPTR )
-                                       td->Link = 1;
+                                       td->Link = 0;
                        }
                        
                        if(frame == 0)

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