More work on x86_64 port of usermode
[tpg/acess2.git] / Kernel / arch / x86 / proc.c
index 7596212..a204b49 100644 (file)
@@ -14,6 +14,7 @@
 
 // === FLAGS ===
 #define DEBUG_TRACE_SWITCH     0
+#define DEBUG_DISABLE_DOUBLEFAULT      1
 
 // === CONSTANTS ===
 #define        SWITCH_MAGIC    0xFF5317C8      // FF SWITCH - There is no code in this area
@@ -46,9 +47,8 @@ extern tShortSpinlock glThreadListLock;
 extern int     giNumCPUs;
 extern int     giNextTID;
 extern tThread gThreadZero;
-extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
 extern void    Isr8(void);     // Double Fault
-extern void    Proc_ReturnToUser(tVAddr Handler, Uint Argument);
+extern void    Proc_ReturnToUser(tVAddr Handler, Uint Argument, tVAddr KernelStack);
 
 // === PROTOTYPES ===
 void   ArchThreads_Init(void);
@@ -56,11 +56,14 @@ void        ArchThreads_Init(void);
 void   MP_StartAP(int CPU);
 void   MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode);
 #endif
-void   Proc_Start(void);
-tThread        *Proc_GetCurThread(void);
+//void Proc_Start(void);
+//tThread      *Proc_GetCurThread(void);
 void   Proc_ChangeStack(void);
- int   Proc_Clone(Uint *Err, Uint Flags);
+// int Proc_Clone(Uint *Err, Uint Flags);
+Uint   Proc_MakeUserStack(void);
+void   Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize);
 void   Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP);
+ int   Proc_Demote(Uint *Err, int Dest, tRegs *Regs);
 void   Proc_CallFaultHandler(tThread *Thread);
 void   Proc_Scheduler(int CPU);
 
@@ -286,7 +289,7 @@ void ArchThreads_Init(void)
        MM_FinishVirtualInit();
        #endif
        
-       #if 0
+       #if !DEBUG_DISABLE_DOUBLEFAULT
        // Initialise Double Fault TSS
        gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF;
        gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
@@ -367,7 +370,10 @@ void ArchThreads_Init(void)
        #endif
        
        // Create Per-Process Data Block
-       MM_Allocate(MM_PPD_CFG);
+       if( !MM_Allocate(MM_PPD_CFG) )
+       {
+               Panic("OOM - No space for initiali Per-Process Config");
+       }
        
        // Change Stacks
        Proc_ChangeStack();
@@ -444,8 +450,8 @@ void Proc_Start(void)
                        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->ThreadName = (char*)"Idle Thread";
+               Threads_SetPriority( gaCPUs[i].IdleThread, -1 );        // Never called randomly
                gaCPUs[i].IdleThread->Quantum = 1;      // 1 slice quantum
                
                
@@ -467,8 +473,8 @@ void Proc_Start(void)
        if(Proc_Clone(0, 0) == 0)
        {
                gpIdleThread = Proc_GetCurThread();
-               gpIdleThread->ThreadName = "Idle Thread";
-               gpIdleThread->NumTickets = 0;   // Never called randomly
+               gpIdleThread->ThreadName = strdup("Idle Thread");
+               Threads_SetPriority( gpIdleThread, -1 );        // Never called randomly
                gpIdleThread->Quantum = 1;      // 1 slice quantum
                for(;;) HALT(); // Just yeilds
        }
@@ -565,6 +571,11 @@ int Proc_Clone(Uint *Err, Uint Flags)
        // Initialise Memory Space (New Addr space or kernel stack)
        if(Flags & CLONE_VM) {
                newThread->MemState.CR3 = MM_Clone();
+               // Check for errors
+               if(newThread->MemState.CR3 == 0) {
+                       Threads_Kill(newThread, -2);
+                       return -1;
+               }
                newThread->KernelStack = cur->KernelStack;
        } else {
                Uint    tmpEbp, oldEsp = esp;
@@ -580,7 +591,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
                newThread->KernelStack = MM_NewKStack();
                // Check for errors
                if(newThread->KernelStack == 0) {
-                       free(newThread);
+                       Threads_Kill(newThread, -2);
                        return -1;
                }
 
@@ -640,14 +651,11 @@ int Proc_SpawnWorker(void)
        cur = Proc_GetCurThread();
        
        // Create new thread
-       new = malloc( sizeof(tThread) );
+       new = Threads_CloneThreadZero();
        if(!new) {
                Warning("Proc_SpawnWorker - Out of heap space!\n");
                return -1;
        }
-       memcpy(new, &gThreadZero, sizeof(tThread));
-       // Set Thread ID
-       new->TID = giNextTID++;
        // Create a new worker stack (in PID0's address space)
        // - The stack is relocated by this function
        new->KernelStack = MM_NewWorkerStack();
@@ -678,7 +686,6 @@ int Proc_SpawnWorker(void)
        // Set EIP as parent
        new->SavedState.EIP = eip;
        // Mark as active
-       new->Status = THREAD_STAT_ACTIVE;
        Threads_AddActive( new );
        
        return new->TID;
@@ -702,7 +709,13 @@ Uint Proc_MakeUserStack(void)
        
        // Allocate Stack - Allocate incrementally to clean up MM_Dump output
        for( i = 0; i < USER_STACK_SZ/0x1000; i++ )
-               MM_Allocate( base + (i<<12) );
+       {
+               if( !MM_Allocate( base + (i<<12) ) )
+               {
+                       Warning("OOM: Proc_MakeUserStack");
+                       return 0;
+               }
+       }
        
        return base + USER_STACK_SZ;
 }
@@ -833,7 +846,7 @@ void Proc_CallFaultHandler(tThread *Thread)
 {
        // Rewinds the stack and calls the user function
        // Never returns
-       Proc_ReturnToUser( Thread->FaultHandler, Thread->CurFaultNum );
+       Proc_ReturnToUser( Thread->FaultHandler, Thread->CurFaultNum, Thread->KernelStack );
        for(;;);
 }
 
@@ -911,13 +924,6 @@ void Proc_Scheduler(int CPU)
        // Update Kernel Stack pointer
        gTSSs[CPU].ESP0 = 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.ESP > 0xC0000000
        && thread->SavedState.ESP < thread->KernelStack-0x2000) {
@@ -925,14 +931,20 @@ void Proc_Scheduler(int CPU)
        }
        #endif
        
+       #if USE_PAE
+       # error "Todo: Implement PAE Address space switching"
+       #else
        // Switch threads
        __asm__ __volatile__ (
+               "mov %4, %%cr3\n\t"     // Set address space
                "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"(thread->SavedState.ESP),
-               "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP)
+               "d"(thread->SavedState.EBP), "c"(thread->SavedState.EIP),
+               "r"(thread->MemState.CR3)
                );
+       #endif
        for(;;);        // Shouldn't reach here
 }
 

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