More work on x86_64 port, near compiling now
authorJohn Hodge <[email protected]>
Fri, 14 May 2010 12:54:59 +0000 (20:54 +0800)
committerJohn Hodge <[email protected]>
Fri, 14 May 2010 12:54:59 +0000 (20:54 +0800)
Kernel/Makefile.BuildNum
Kernel/arch/x86/proc.asm
Kernel/arch/x86/proc.c
Kernel/arch/x86_64/desctab.asm
Kernel/arch/x86_64/include/arch.h
Kernel/arch/x86_64/include/proc.h
Kernel/arch/x86_64/mm_phys.c
Kernel/arch/x86_64/mm_virt.c
Kernel/arch/x86_64/proc.c
Kernel/arch/x86_64/start64.asm

index efeefa4..70cc0b3 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 2158
+BUILD_NUM = 2159
index b1843c7..d905c24 100644 (file)
@@ -74,13 +74,12 @@ SpawnTask:
 ;
 ; Calls a user fault handler
 ;
-[global Proc_AlterUserReturnAddr]
+[global Proc_ReturnToUser]
 [extern Proc_GetCurThread]
-Proc_AlterUserReturnAddr:
+Proc_ReturnToUser:
        ; EBP is the handler to use
        
        call Proc_GetCurThread
-       xchg bx, bx
        
        ; EAX is the current thread
        mov ebx, eax
index 2451cd0..45c5a56 100644 (file)
@@ -39,7 +39,7 @@ extern tThread        *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump();
 extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
 extern void    Isr8(); // Double Fault
-extern void    Proc_AlterUserReturnAddr();
+extern void    Proc_ReturnToUser();
 
 // === PROTOTYPES ===
 void   ArchThreads_Init();
@@ -703,7 +703,7 @@ void Proc_CallFaultHandler(tThread *Thread)
 {
        // Rewinds the stack and calls the user function
        // Never returns
-       __asm__ __volatile__ ("mov %0, %%ebp;\n\tcall Proc_AlterUserReturnAddr" :: "r"(Thread->FaultHandler));
+       __asm__ __volatile__ ("mov %0, %%ebp;\n\tcall Proc_ReturnToUser" :: "r"(Thread->FaultHandler));
        for(;;);
 }
 
index aec7656..de606ea 100644 (file)
@@ -3,49 +3,12 @@
 ;
 [BITS 64]
 
-MM_LOCALAPIC   equ     0xFFFFFD0000000000
-
-[section .text]
-Desctab_Init:
-       ; Install IRQ Handlers
-
-[section .data]
-gIDT:
-       times 256       dw      0x00080000, 0x00008E00, 0, 0    ; 64-bit Interrupt Gate, CS = 0x8, IST0
-
-%macro DEFERR  1
-Isr%1:
-       push    0
-       push    %1
-       jmp     ErrorCommon
-%endmacro
-%macro DEFERRNO        1
-Isr%1:
-       push    %1
-       jmp     ErrorCommon
-%endmacro
-
-%macro DEFIRQ  1
-Irq%1:
-       push    0
-       push    %1
-       jmp     IrqCommon
-%endmacro
+%define NUM_IRQ_CALLBACKS      4
 
-%macro PUSH_EX 1-*
-       %rep %0
-       push %1
-       %rotate 1
-       %endrep
-%endmacro
-%macro POP_EX  1-*
-       %rep %0
-       %rotate -1
-       pop %1
-       %endrep
-%endmacro
+MM_LOCALAPIC   equ     0xFFFFFD0000000000
 
 %macro PUSH_GPR        0
+       mov [rsp-0x60], rsp
        mov [rsp-0x08], r15
        mov [rsp-0x10], r14
        mov [rsp-0x18], r13
@@ -57,7 +20,6 @@ Irq%1:
        mov [rsp-0x48], rdi
        mov [rsp-0x50], rsi
        mov [rsp-0x58], rbp
-       mov [rsp-0x60], rsp
        mov [rsp-0x68], rbx
        mov [rsp-0x70], rdx
        mov [rsp-0x78], rcx
@@ -72,8 +34,8 @@ Irq%1:
        mov r12, [rsp-0x20]
        mov r11, [rsp-0x28]
        mov r10, [rsp-0x30]
-       mov r9, [rsp-0x38]
-       mov r8, [rsp-0x40]
+       mov r9,  [rsp-0x38]
+       mov r8,  [rsp-0x40]
        mov rdi, [rsp-0x48]
        mov rsi, [rsp-0x50]
        mov rbp, [rsp-0x58]
@@ -84,6 +46,107 @@ Irq%1:
        mov rax, [rsp-0x80]
 %endmacro
 
+[section .text]
+Desctab_Init:
+       ; Install IRQ Handlers
+       ret
+
+; int IRQ_AddHandler(int IRQ, void (*Handler)(int IRQ))
+; Return Values:
+;  0 on Success
+; -1 on an invalid IRQ Number
+; -2 when no slots are avaliable
+[global IRQ_AddHandler]
+IRQ_AddHandler:
+       ; RDI - IRQ Number
+       ; RSI - Callback
+       
+       cmp rdi, 16
+       jb .numOK
+       xor rax, rax
+       dec rax
+       jmp .ret
+.numOK:
+
+       mov rax, rdi
+       shr rax, 3+2
+       mov rcx, gaIRQ_Handlers
+       add rax, rcx
+       
+       ; Find a free callback slot
+       %rep NUM_IRQ_CALLBACKS
+       mov rdx, [rax]
+       test rdx, rdx
+       jz .assign
+       add rax, 8
+       %endrep
+       ; None found, return -2
+       xor rax, rax
+       dec rax
+       dec rax
+       jmp .ret
+       
+       ; Assign the IRQ Callback
+.assign:
+       mov [rax], rsi
+       xor rax, rax
+
+.ret:
+       ret
+
+%macro DEFERR  1
+Isr%1:
+       push    0
+       push    %1
+       jmp     ErrorCommon
+%endmacro
+%macro DEFERRNO        1
+Isr%1:
+       push    %1
+       jmp     ErrorCommon
+%endmacro
+
+%macro DEFIRQ  1
+Irq%1:
+       push    0
+       push    %1
+       jmp     IrqCommon
+%endmacro
+
+IrqCommon:
+       PUSH_GPR
+       
+       mov rbx, [rsp+16*8]     ; Calculate address
+       shr rbx, 3+2    ; *8*4
+       mov rax, gaIRQ_Handlers
+       add rbx, rax
+       
+       %assign i 0
+       %rep NUM_IRQ_CALLBACKS
+       mov rax, [rbx]
+       test rax, rax
+       mov rdi, [rsp+16*8]     ; Get IRQ number
+       jz .skip.%[i]
+       call rax        ; 2 Bytes (Op and Mod/RM)
+.skip.%[i]:
+       add rbx, 8
+       %assign i i+1
+       %endrep
+       
+       mov rdi, [rsp+16*8]     ; Get IRQ number
+       cmp rdi, 8
+       mov al, 0x20
+       jb .skipAckSecondary
+       mov dx, 0x00A0
+       out dx, al
+.skipAckSecondary:
+       mov dx, 0x0020
+       out dx, al
+       
+       POP_GPR
+       add rsp, 16
+       iret
+
 [extern Proc_Scheduler]
 SchedulerIRQ:
        ; TODO: Find Current CPU
@@ -100,3 +163,10 @@ SchedulerIRQ:
        ;POP_FPU
        POP_GPR
        iret
+
+[section .data]
+gIDT:
+       times 256       dw      0x00080000, 0x00008E00, 0, 0    ; 64-bit Interrupt Gate, CS = 0x8, IST0
+
+gaIRQ_Handlers:
+       times   16*NUM_IRQ_CALLBACKS    dq      0
index 22c551f..0dc9927 100644 (file)
@@ -44,25 +44,24 @@ typedef volatile int    tSpinlock;
 // TODO: Fix this structure
 typedef struct sSyscallRegs
 {
-       Uint    Arg4, Arg5;     // RDI, RSI
-       Uint    Arg6;   // RBP
-       Uint    Resvd2[1];      // Kernel RSP
        union {
-               Uint    Arg1;
-               Uint    Error;
-       };      // RBX
-       union {
-               Uint    Arg3;
-               Uint    RetHi;  // High 64 bits of ret
-       };      // RDX
-       Uint    Arg2;   // RCX
-       union {
-               Uint    Num;
-               Uint    Return;
+               Uint    Num;
+               Uint    Return;
        };      // RAX
-       Uint    Resvd3[5];      // Int, Err, rip, CS, ...
-       Uint    StackPointer;   // RSP
-       Uint    Resvd4[1];      // SS   
+       Uint    Arg4;   // RCX
+       Uint    Arg3;   // RDX
+       Uint    Error;  // RBX
+       Uint    Resvd1[2];      // Kernel RSP, RBP
+       Uint    Arg2;   // RSI
+       Uint    Arg1;   // RDI
+       Uint    Arg5;   // R8
+       Uint    Arg6;   // R9
+       Uint    Resvd2[6];      // R10 - R15
+       Uint    Resvd3[5];      // IntNum, ErrCode, RIP, CS, RFLAGS
+       
+       Uint    Resvd4[5];      // Int, Err, rip, CS, ...
+       Uint    StackPointer;   // RSP
+       Uint    Resvd5[1];      // SS   
 }      tSyscallRegs;
 
 #endif
index d78019d..8217c68 100644 (file)
 // Register Structure
 // TODO: Rebuild once IDT code is done
 typedef struct {
-       Uint    ds, es, fs, gs;
-       Uint    r15, r14, r13, r12;
-       Uint    r11, r10, r9, r8;
-    Uint       rdi, rsi, rbp, krsp;
-       Uint    rbx, rdx, rcx, rax;
+       Uint    rax, rcx, rdx, rbx;
+    Uint       krsp, rbp, rsi, rdi;
+       Uint    r8, r9, r10, r11;
+       Uint    r12, r13, r14, r15;
     Uint       int_num, err_code;
-    Uint       eip, cs;
-       Uint    eflags, esp, ss;
+    Uint       rip, cs;
+       Uint    rflags, rsp, ss;
 } tRegs;
 
 /**
index 3535fbc..dd8ddf6 100644 (file)
@@ -4,6 +4,7 @@
  * Physical Memory Manager
  */
 #include <acess.h>
+#include <mboot.h>
 //#include <mm_phys.h>
 
 enum eMMPhys_Ranges
@@ -28,8 +29,33 @@ Uint64       giPhysRangeLast[NUM_MM_PHYS_RANGES];    // Last free page in each range
 Uint64 giMaxPhysPage = 0;      // Maximum Physical page
 
 // === CODE ===
-void MM_InitPhys()
+void MM_InitPhys(tMBoot_Info *MBoot)
 {
+       tMBoot_MMapEnt  *mmapStart;
+       tMBoot_MMapEnt  *ent;
+       Uint64  maxAddr = 0;
+       
+       // Scan the physical memory map
+       mmapStart = (void *)( KERNEL_BASE | MBoot->MMapAddr );
+       ent = mmapStart;
+       while( (Uint)ent < (Uint)mmapStart + MBoot->MMapLength )
+       {
+               // Adjust for the size of the entry
+               ent->Size += 4;
+               
+               // If entry is RAM and is above `maxAddr`, change `maxAddr`
+               if(ent->Type == 1 && ent->Base + ent->Length > maxAddr)
+                       maxAddr = ent->Base + ent->Length;
+               // Go to next entry
+               ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size );
+       }
+       
+       if(maxAddr == 0) {
+               giMaxPhysPage = (MBoot->HighMem >> 2) + 256;    // HighMem is a kByte value
+       }
+       else {
+               giMaxPhysPage = maxAddr >> 12;
+       }
 }
 
 /**
@@ -162,9 +188,12 @@ tPAddr MM_AllocPhys(void)
        return MM_AllocPhysRange(1, -1);
 }
 
+/**
+ * \brief Reference a physical page
+ */
 void MM_RefPhys(tPAddr PAddr)
 {
-       if( PAddr > giMaxPhysPage )     return ;
+       if( PAddr >> 12 > giMaxPhysPage )       return ;
        gaiPageReferences[ PAddr >> 12 ] ++;
        
        gaPrimaryBitmap[PAddr >> 18] |= 1 << ((PAddr>>12) & 63);
@@ -172,9 +201,12 @@ void MM_RefPhys(tPAddr PAddr)
                gaSuperBitmap[PAddr >> 24] |= 1 << ((PAddr >> 18) & 64);
 }
 
+/**
+ * \brief Dereference a physical page
+ */
 void MM_DerefPhys(tPAddr PAddr)
 {
-       if( PAddr > giMaxPhysPage )     return ;
+       if( PAddr >> 12 > giMaxPhysPage )       return ;
        gaiPageReferences[ PAddr >> 12 ] --;
        if( gaiPageReferences[ PAddr >> 12 ] )
        {
index 4107575..4cce485 100644 (file)
@@ -76,6 +76,18 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr)
        return 1;
 }
 
+void MM_Unmap(tVAddr VAddr)
+{
+       // Check PML4
+       if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )   return ;
+       // Check PDP
+       if( !(PAGEDIRPTR(VAddr >> 30) & 1) )    return ;
+       // Check Page Dir
+       if( !(PAGEDIR(VAddr >> 21) & 1) )       return ;
+       
+       PAGETABLE(VAddr >> 12) = 0;
+}
+
 /**
  * \brief Allocate a block of memory at the specified virtual address
  */
@@ -95,6 +107,18 @@ tPAddr MM_Allocate(tVAddr VAddr)
        return ret;
 }
 
+void MM_Deallocate(tVAddr VAddr)
+{
+       tPAddr  phys;
+       
+       phys = MM_GetPhysAddr(VAddr);
+       if(!phys)       return ;
+       
+       MM_Unmap(VAddr);
+       
+       MM_DerefPhys(phys);
+}
+
 /**
  * \brief Get the physical address of a virtual location
  */
@@ -179,6 +203,9 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
        }
 }
 
+/**
+ * \brief Get the flags applied to a page
+ */
 Uint MM_GetFlags(tVAddr VAddr)
 {
        tPAddr  *ent;
@@ -208,3 +235,34 @@ Uint MM_GetFlags(tVAddr VAddr)
        
        return ret;
 }
+
+// --- Hardware Mappings ---
+/**
+ * \brief Map a range of hardware pages
+ */
+tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
+{
+       Log_KernelPanic("MM", "TODO: Implement MM_MapHWPages");
+       return 0;
+}
+
+/**
+ * \brief Free a range of hardware pages
+ */
+void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
+{
+       Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
+}
+
+// --- Tempory Mappings ---
+tVAddr MM_MapTemp(tPAddr PAddr)
+{
+       Log_KernelPanic("MM", "TODO: Implement MM_MapTemp");
+       return 0;
+}
+
+void MM_FreeTemp(tVAddr VAddr)
+{
+       Log_KernelPanic("MM", "TODO: Implement MM_FreeTemp");
+       return ;
+}
index b30eb22..038cc61 100644 (file)
@@ -38,7 +38,7 @@ extern tThread        *gDeleteThreads;
 extern tThread *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump();
 extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
-extern void    Proc_AlterUserReturnAddr();
+extern void    Proc_ReturnToUser();
 
 // === PROTOTYPES ===
 void   ArchThreads_Init();
@@ -640,11 +640,6 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs)
        // Change the Segment Registers
        Regs->cs = (((Dest+1)<<4) | Dest) - 8;
        Regs->ss = ((Dest+1)<<4) | Dest;
-       // Check if the GP Segs are GDT, then change them
-       if(!(Regs->ds & 4))     Regs->ds = ((Dest+1)<<4) | Dest;
-       if(!(Regs->es & 4))     Regs->es = ((Dest+1)<<4) | Dest;
-       if(!(Regs->fs & 4))     Regs->fs = ((Dest+1)<<4) | Dest;
-       if(!(Regs->gs & 4))     Regs->gs = ((Dest+1)<<4) | Dest;
        
        return 0;
 }
@@ -657,7 +652,7 @@ void Proc_CallFaultHandler(tThread *Thread)
 {
        // Rewinds the stack and calls the user function
        // Never returns
-       __asm__ __volatile__ ("mov %0, %%rbp;\n\tcall Proc_AlterUserReturnAddr" :: "r"(Thread->FaultHandler));
+       __asm__ __volatile__ ("mov %0, %%rbp;\n\tcall Proc_ReturnToUser" :: "r"(Thread->FaultHandler));
        for(;;);
 }
 
index beb22e5..c1f1e58 100644 (file)
@@ -15,7 +15,56 @@ GetRIP:
        mov rax, [rsp]
        ret
 
+KSTACK_USERSTATE_SIZE  equ     (4+8+1+5)*4     ; SRegs, GPRegs, CPU, IRET
+[global Proc_ReturnToUser]
+[extern Proc_GetCurThread]
+Proc_ReturnToUser:
+       ; RBP is the handler to use
+       
+       call Proc_GetCurThread
+       
+       ; EAX is the current thread
+       mov rbx, rax
+       mov rax, [rbx+40]       ; Get Kernel Stack
+       sub rax, KSTACK_USERSTATE_SIZE
+       
+       ;
+       ; NOTE: This can cause corruption if the signal happens while the user
+       ;       has called a kernel operation.
+       ; Good thing this can only be called on a user fault.
+       ;
+       
+       ; Get and alter User SP
+       mov rcx, [rax+KSTACK_USERSTATE_SIZE-3*8]
+       mov rdx, [rbx+60]       ; Get Signal Number
+       mov [rcx-8], rdx
+       mov QWORD [rcx-16], User_Syscall_RetAndExit
+       sub rcx, 16
+       
+       ; Restore Segment Registers
+       mov ax, 0x23
+       mov ds, ax
+       mov es, ax
+       
+       push 0x23       ; SS
+       push rcx        ; RSP
+       push 0x202      ; RFLAGS (IF and Rsvd)
+       push 0x1B       ; CS
+       push rbp        ; RIP
+       
+       iret
+
+[section .usertext]
+User_Syscall_RetAndExit:
+       mov rdi, rax
+       jmp User_Syscall_Exit
+User_Syscall_Exit:
+       xor rax, rax
+       ; RDI: Return Value
+       int 0xAC
+
 [section .bss]
 [global gInitialKernelStack]
        resd    1024*1  ; 1 Page
 gInitialKernelStack:
+

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