Kernel/x86_64 - Bugfixing
authorJohn Hodge <[email protected]>
Mon, 26 Sep 2011 02:04:14 +0000 (10:04 +0800)
committerJohn Hodge <[email protected]>
Mon, 26 Sep 2011 02:04:14 +0000 (10:04 +0800)
- Fixed the ATA bug (caused by some IRQs not being acked)
- Fixed SYSRET/SYSRETQ issue
- Implemented DivModU64

Kernel/arch/x86/lib.c
Kernel/arch/x86_64/desctab.asm
Kernel/arch/x86_64/lib.c
Kernel/arch/x86_64/proc.asm
Kernel/arch/x86_64/proc.c
Kernel/arch/x86_64/start32.asm

index 3a70c75..8f8abe6 100644 (file)
@@ -1,6 +1,8 @@
 /*
- * AcessOS Microkernel Version
- * lib.c
+ * Acess2
+ *
+ * arch/x86/lib.c
+ * - General arch-specific stuff
  */
 #include <acess.h>
 #include <threads_int.h>
index 50fc126..694672c 100644 (file)
@@ -191,6 +191,8 @@ IRQ_AddHandler:
 [section .rodata]
 csIRQ_Assigned:
        db      "IRQ %p := %p (IRQ %i)",0
+csIRQ_Fired:
+       db      "IRQ %i fired",0
 [section .text]
 
 %macro ISR_NOERRNO     1
@@ -277,10 +279,14 @@ IrqCommon:
        PUSH_GPR
        push gs
        push fs
+
+;      mov rdi, csIRQ_Fired
+;      mov rsi, [rsp+(16+2)*8]
+;      call Log
        
-       mov rbx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
+       mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
 ;      xchg bx, bx     ; Bochs Magic break (NOTE: will clear the high-bits of RBX)
-       shl rbx, 2      ; *8*4
+       shl ebx, 2      ; *4
        mov rax, gaIRQ_Handlers
        lea rbx, [rax+rbx*8]
        
@@ -303,20 +309,17 @@ IrqCommon:
        
        ; ACK
        mov al, 0x20
-       mov rdi, [rsp+16*8]     ; Get IRQ number
+       mov rdi, [rsp+(16+2)*8] ; Get IRQ number
        cmp rdi, 8
        jb .skipAckSecondary
-       mov dx, 0x00A0
-       out dx, al
+       out 0xA0, al
 .skipAckSecondary:
-       mov dx, 0x0020
-       out dx, al
+       out 0x20, al
        
        pop fs
        pop gs
        POP_GPR
        add rsp, 8*2
-       ;xchg bx, bx
        iretq
 
 [extern Proc_Scheduler]
index 5f6bdd8..6ba12a4 100644 (file)
@@ -361,3 +361,15 @@ void *memsetd(void *__dest, Uint32 __val, size_t __count)
        return __dest;
 }
 
+Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
+{
+       Uint64  ret, rem;
+       __asm__ __volatile__(
+               "div %4"
+               : "=a" (ret), "=d" (rem)
+               : "a" ( Num ), "d" (0), "r" (Den)
+               );
+       if(Rem) *Rem = rem;
+       return ret;
+}
+
index 541abd6..664ad21 100644 (file)
@@ -50,23 +50,23 @@ NewTaskHeader:
 [global SaveState]
 SaveState:
        ; Save regs to RSI
-       xchg bx, bx
        add rsi, 0x80
        SAVE_GPR rsi
-       sub rsi, 0x80
+       ; Save return addr
+       mov rax, [rsp]
+       mov [rsi], rax
        ; Return RSI as the RSP value
+       sub rsi, 0x80
        mov [rdi], rsi
-       call GetRIP
-       cmp eax, 0x80000000
-       ja .fastret
+       ; Check for 
+       mov rax, .restore
+       ret
 .restore:
-       ; RSP = RSI from call
-       xchg bx, bx
+       ; RSP = RSI now
        POP_GPR
+       mov rax, [rsp]
        mov rsp, [rsp-0x60]     ; Restore RSP from the saved value
+       mov [rsp], rax  ; Restore return address
        xor eax, eax
        ret
-.fastret:
-       ; RAX is still the return addr
-       ret
        
index e83c20a..8cc1933 100644 (file)
@@ -467,7 +467,7 @@ int Proc_Clone(Uint Flags)
 {
        tThread *newThread, *cur = Proc_GetCurThread();
        Uint    rip;
-       Uint    _savedregs[16];
+       Uint    _savedregs[16+1];
        
        newThread = Threads_CloneTCB(NULL, Flags);
        if(!newThread)  return -1;
@@ -490,7 +490,12 @@ int Proc_Clone(Uint Flags)
                return -1;
        }
        
-       Log("New (Clone) %p, rsp = %p\n", rip, newThread->SavedState.RSP);
+       Log("New (Clone) %p, rsp = %p", rip, newThread->SavedState.RSP);
+       {
+               Uint cr3;
+               __asm__ __volatile__ ("mov %%cr3, %0" : "=r" (cr3));
+               Log(" CR3 = %x, PADDR(RSP) = %x", cr3, MM_GetPhysAddr(newThread->SavedState.RSP));
+       }
        
        // Set EIP as parent
        newThread->SavedState.RIP = rip;
@@ -603,7 +608,8 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **
        for( i = 0; EnvP[i]; i++ )      EnvP[i] += delta;
        
        // User Mode Segments
-       ss = 0x23;      cs = 0x1B;
+       // 0x2B = 64-bit
+       ss = 0x23;      cs = 0x2B;
        
        // Arguments
        *--stack = (Uint)EnvP;
@@ -611,26 +617,39 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **
        *--stack = (Uint)ArgC;
        while(*Bases)
                *--stack = *Bases++;
-       *--stack = 0;   // Return Address
        
        Proc_StartProcess(ss, (Uint)stack, 0x202, cs, Entrypoint);
 }
 
 void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP)
 {
-       if( CS != 0x1B || SS != 0x23 ) {
+       if( !(CS == 0x1B || CS == 0x2B) || SS != 0x23 ) {
                Log_Error("Proc", "Proc_StartProcess: CS / SS are not valid (%x, %x)",
                        CS, SS);
                Threads_Exit(0, -1);
        }
-//     MAGIC_BREAK();  
-       __asm__ __volatile__ (
-               "mov %0, %%rsp;\n\t"    // Set stack pointer
-               "mov %1, %%r11;\n\t"    // Set stack pointer
-               "sysret;\n\t"
-               : : "r" (Stack), "c" (IP), "r" (Flags)
-               : "r11"
-               );
+       Log("Proc_StartProcess: (SS=%x, Stack=%p, Flags=%x, CS=%x, IP=%p)",
+               SS, Stack, Flags, CS, IP);
+       if(CS == 0x1B)
+       {
+               // 32-bit return
+               __asm__ __volatile__ (
+                       "mov %0, %%rsp;\n\t"    // Set stack pointer
+                       "mov %2, %%r11;\n\t"    // Set RFLAGS
+                       "sysret;\n\t"
+                       : : "r" (Stack), "c" (IP), "r" (Flags)
+                       );
+       }
+       else
+       {
+               // 64-bit return
+               __asm__ __volatile__ (
+                       "mov %0, %%rsp;\n\t"    // Set stack pointer
+                       "mov %2, %%r11;\n\t"    // Set RFLAGS
+                       "sysretq;\n\t"
+                       : : "r" (Stack), "c" (IP), "r" (Flags)
+                       );
+       }
        for(;;);
 }
 
@@ -769,9 +788,10 @@ void Proc_Scheduler(int CPU, Uint RSP, Uint RIP)
                "invlpg (%%rsp)\n\t"
                "invlpg 0x1000(%%rsp)\n\t"
                "invlpg -0x1000(%%rsp)\n\t"
+               "xor %%eax, %%eax\n\t"
                "jmp *%1" : :   // And return to where we saved state (Proc_Clone or Proc_Scheduler)
                "r"(thread->SavedState.RSP), "r"(thread->SavedState.RIP),
-               "r"(thread->MemState.CR3), "a" (0)
+               "r"(thread->MemState.CR3)
                );
        for(;;);        // Shouldn't reach here
 }
index e1db2c5..6de3a87 100644 (file)
@@ -94,10 +94,10 @@ gGDT:
        dd      0,0
        dd      0x00000000, 0x00209A00  ; 0x08: 64-bit Code
        dd      0x00000000, 0x00009200  ; 0x10: 64-bit Data
-       dd      0x00000000, 0x0020FA00  ; 0x18: 64-bit User Code
-       dd      0x00000000, 0x0000F200  ; 0x20: 64-bit User Data
-       dd      0x00000000, 0x0040FA00  ; 0x28: 32-bit User Code
-       dd      0x00000000, 0x0040F200  ; 0x30: 32-bit User Data
+       dd      0x00000000, 0x0040FA00  ; 0x18: 32-bit User Code
+       dd      0x00000000, 0x0040F200  ; 0x20: User Data
+       dd      0x00000000, 0x0020FA00  ; 0x28: 64-bit User Code
+       dd      0x00000000, 0x0000F200  ; 0x30: User Data (64 version)
        times MAX_CPUS  dd      0, 0x00008900, 0, 0     ; 0x38+16*n: TSS 0
 gGDTPtr:
        dw      $-gGDT-1

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