Kernel/x86_64 - Bugfixing
authorJohn Hodge <[email protected]>
Sun, 12 Jun 2011 02:24:15 +0000 (10:24 +0800)
committerJohn Hodge <[email protected]>
Sun, 12 Jun 2011 02:24:15 +0000 (10:24 +0800)
- Changed page dump to be more readable
- Fixed display issues in page dump
- Fixed a broken CallWithArgArray implementation

Kernel/arch/x86_64/errors.c
Kernel/arch/x86_64/include/mm_virt.h
Kernel/arch/x86_64/mm_virt.c
Kernel/arch/x86_64/start64.asm
Kernel/system.c

index 66ba443..711846c 100644 (file)
@@ -4,9 +4,13 @@
  */
 #include <acess.h>
 #include <proc.h>
+#include <mm_virt.h>
+
+#define MAX_BACKTRACE  6
 
 // === IMPORTS ===
 void   MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
+void   Error_Backtrace(Uint IP, Uint BP);
 
 // === PROTOTYPES ===
 void   Error_Handler(tRegs *Regs);
@@ -77,3 +81,53 @@ void Error_Handler(tRegs *Regs)
        for(;;)
                __asm__ __volatile__ ("hlt");
 }
+
+/**
+ * \fn void Error_Backtrace(Uint eip, Uint ebp)
+ * \brief Unrolls the stack to trace execution
+ * \param eip  Current Instruction Pointer
+ * \param ebp  Current Base Pointer (Stack Frame)
+ */
+void Error_Backtrace(Uint IP, Uint BP)
+{
+        int    i = 0;
+       
+       //if(eip < 0xC0000000 && eip > 0x1000)
+       //{
+       //      LogF("Backtrace: User - 0x%x\n", eip);
+       //      return;
+       //}
+       
+       if( IP > MM_USER_MAX
+        && IP < MM_KERNEL_CODE
+        && (MM_MODULE_MIN > IP || IP > MM_MODULE_MAX)
+               )
+       {
+               LogF("Backtrace: Data Area - %p\n", IP);
+               return;
+       }
+       
+       //str = Debug_GetSymbol(eip, &delta);
+       //if(str == NULL)
+               LogF("Backtrace: %p", IP);
+       //else
+       //      LogF("Backtrace: %s+0x%x", str, delta);
+       if( !MM_GetPhysAddr(BP) )
+       {
+               LogF("\nBacktrace: Invalid BP, stopping\n");
+               return;
+       }
+       
+       
+       while( MM_GetPhysAddr(BP) && i < MAX_BACKTRACE )
+       {
+               //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
+               //if(str == NULL)
+                       LogF(" >> 0x%llx", ((Uint*)BP)[1]);
+               //else
+               //      LogF(" >> %s+0x%x", str, delta);
+               BP = ((Uint*)BP)[0];
+               i++;
+       }
+       LogF("\n");
+}
index f1c5606..dd520a2 100644 (file)
@@ -72,6 +72,7 @@
 #define MM_FRACTAL_BASE        (MM_KERNEL_RANGE|(0xFE00##00000000))
 #define MM_TMPFRAC_BASE        (MM_KERNEL_RANGE|(0xFE80##00000000))
 #define MM_LOCALAPIC   (MM_KERNEL_RANGE|(0xFF80##00000000))
+#define MM_KERNEL_CODE (MM_KERNEL_RANGE|(0xFFFF##80000000))
 
 
 // === FUNCTIONS ===
index 708f78f..a0b384d 100644 (file)
 #define PAGEDIRPTR(idx)        PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK))
 #define PAGEMAPLVL4(idx)       PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK))
 
-#define TMPTABLE(idx)  (*((tPAddr*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK)))
-#define TMPDIR(idx)    TMPTABLE((MM_FRACTAL_BASE>>12)+((idx)&TABLE_MASK))
-#define TMPDIRPTR(idx) TMPDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK))
-#define TMPMAPLVL4(idx)        TMPDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK))
 #define TMPCR3()       PAGEMAPLVL4(MM_TMPFRAC_BASE>>39)
+#define TMPTABLE(idx)  (*((tPAddr*)MM_TMPFRAC_BASE+((idx)&PAGE_MASK)))
+#define TMPDIR(idx)    PAGETABLE((MM_TMPFRAC_BASE>>12)+((idx)&TABLE_MASK))
+#define TMPDIRPTR(idx) PAGEDIR((MM_TMPFRAC_BASE>>21)+((idx)&PDP_MASK))
+#define TMPMAPLVL4(idx)        PAGEDIRPTR((MM_TMPFRAC_BASE>>30)+((idx)&PML4_MASK))
 
 #define INVLPG(__addr) __asm__ __volatile__ ("invlpg (%0)"::"r"(__addr));
 
 // === CONSTS ===
 //tPAddr       * const gaPageTable = MM_FRACTAL_BASE;
 
-// === EXTERNS ===
+// === IMPORTS ===
+extern void    Error_Backtrace(Uint IP, Uint BP);
 extern tPAddr  gInitialPML4[512];
 
 // === PROTOTYPES ===
@@ -138,7 +139,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
        
        Log("Code at %p accessed %p", Regs->RIP, Addr);
        // Print Stack Backtrace
-//     Error_Backtrace(Regs->RIP, Regs->RBP);
+       Error_Backtrace(Regs->RIP, Regs->RBP);
        
        MM_DumpTables(0, -1);
        
@@ -152,6 +153,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
  */
 void MM_DumpTables(tVAddr Start, tVAddr End)
 {
+       #define CANOICAL(addr)  ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
        const tPAddr    CHANGEABLE_BITS = 0xFF8;
        const tPAddr    MASK = ~CHANGEABLE_BITS;        // Physical address and access bits
        tVAddr  rangeStart = 0;
@@ -186,17 +188,15 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
                ||  (PAGETABLE(page) & MASK) != expected)
                {                       
                        if(expected != CHANGEABLE_BITS) {
-                               #define CANOICAL(addr)  ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr))
-                               Log("%016x-0x%016x => %013x-%013x (%c%c%c%c)",
-                                       CANOICAL(rangeStart), CANOICAL(curPos - 1),
+                               Log("%016llx => %013llx : 0x%6llx (%c%c%c%c)",
+                                       CANOICAL(rangeStart),
                                        PAGETABLE(rangeStart>>12) & ~0xFFF,
-                                       (expected & ~0xFFF) - 1,
+                                       curPos - rangeStart,
                                        (expected & PF_PAGED ? 'p' : '-'),
                                        (expected & PF_COW ? 'C' : '-'),
                                        (expected & PF_USER ? 'U' : '-'),
                                        (expected & PF_WRITE ? 'W' : '-')
                                        );
-                               #undef CANOICAL
                                expected = CHANGEABLE_BITS;
                        }
                        if( !(PAGEMAPLVL4(page>>27) & PF_PRESENT) ) {
@@ -227,17 +227,18 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
        }
        
        if(expected != CHANGEABLE_BITS) {
-               Log("%016x-%016x => %013x-%013x (%s%s%s%s)",
-                       rangeStart, curPos - 1,
+               Log("%016llx => %013llx : 0x%6llx (%c%c%c%c)",
+                       CANOICAL(rangeStart),
                        PAGETABLE(rangeStart>>12) & ~0xFFF,
-                       (expected & ~0xFFF) - 1,
-                       (expected & PF_PAGED ? "p" : "-"),
-                       (expected & PF_COW ? "C" : "-"),
-                       (expected & PF_USER ? "U" : "-"),
-                       (expected & PF_WRITE ? "W" : "-")
+                       curPos - rangeStart,
+                       (expected & PF_PAGED ? 'p' : '-'),
+                       (expected & PF_COW ? 'C' : '-'),
+                       (expected & PF_USER ? 'U' : '-'),
+                       (expected & PF_WRITE ? 'W' : '-')
                        );
                expected = 0;
        }
+       #undef CANOICAL
 }
 
 /**
@@ -646,15 +647,17 @@ tPAddr MM_Clone(void)
        Mutex_Acquire(&glMM_TempFractalLock);
        TMPCR3() = ret | 3;
        
-       INVLPG(TMPMAPLVL4(0));
+       INVLPG(&TMPMAPLVL4(0));
        memcpy(&TMPMAPLVL4(0), &PAGEMAPLVL4(0), 0x1000);
        
        Log_KernelPanic("MM", "TODO: Implement MM_Clone");
        
        // #3 Set Copy-On-Write to all user pages
+       
+       
        // #4 Return
        TMPCR3() = 0;
-       INVLPG(TMPMAPLVL4(0));
+       INVLPG(&TMPMAPLVL4(0));
        Mutex_Release(&glMM_TempFractalLock);
        return 0;
 }
index d0cc503..b0a8586 100644 (file)
@@ -106,16 +106,53 @@ Proc_ReturnToUser:
 CallWithArgArray:
        push rbp
        mov rbp, rsp
-       mov rcx, [rbp+3*8]      ; Get NArgs
-       mov rdx, [rbp+4*8]
-
-.top:
-       mov rax, [rdx+rcx*8-8]
-       push rax
-       loop .top
+       push r10
+       push r11
+       
+       mov [rbp+2*8], rdi      ; Save Ptr to stack
        
-       mov rax, [rbp+2*8]
+       mov r11, rsi    ; NArgs
+       mov r10, rdx    ; Args
+
+       ; Arg 1: RDI
+       mov rdi, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; Arg 2: RSI
+       mov rsi, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; Arg 3: RDX
+       mov rdx, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; Arg 4: RCX
+       mov rcx, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; Arg 5: R8
+       mov r8, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; Arg 6: R9
+       mov r9, [r10]
+       add r10, 8
+       dec r11
+       jz .call
+       ; No support for more
+
+.call:
+       mov rax, [rbp+2*8]      ; Ptr
        call rax
+       
+       pop r11
+       pop r10
+       
        lea rsp, [rbp]
        pop rbp
        ret
index a996038..5450883 100644 (file)
@@ -338,7 +338,8 @@ void System_ExecuteScript(void)
                if(line->Parts[0][0] == ':')    continue;       // Ignore labels
                
                // Prescan and eliminate variables
-               for( j = 1; j < line->nParts; j++ ) {
+               for( j = 1; j < line->nParts; j++ )
+               {
                        Log_Debug("Config", "Arg #%i is '%s'", j, line->Parts[j]);
                        bReplaced[j] = 0;
                        if( line->Parts[j][0] != '$' )  continue;
@@ -356,13 +357,16 @@ void System_ExecuteScript(void)
                        bReplaced[j] = 1;
                }
                
+               // Find the command name
                for( j = 0; j < NUM_CONFIG_COMMANDS; j++ )
                {
                        Uint    args[N_MAX_ARGS];
+                       
                        if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0)       continue;
                        
                        Log_Debug("Config", "Command '%s', %i args passed", line->Parts[0], line->nParts-1);
                        
+                       // Check against minimum argument count
                        if( line->nParts - 1 < caConfigCommands[j].MinArgs ) {
                                Log_Warning("Config",
                                        "Configuration command '%s' requires at least %i arguments, %i given",
@@ -371,6 +375,7 @@ void System_ExecuteScript(void)
                                break;
                        }
                        
+                       // Check for extra arguments
                        if( line->nParts - 1 > caConfigCommands[j].MaxArgs ) {
                                Log_Warning("Config",
                                        "Configuration command '%s' takes at most %i arguments, %i given",
@@ -379,10 +384,12 @@ void System_ExecuteScript(void)
                                break;
                        }
                        
+                       // Fill in defaults
                        for( k = caConfigCommands[j].MaxArgs-1; k > line->nParts - 1; k-- ) {
                                args[k] = caConfigCommands[j].OptDefaults[k];
                        }
                        
+                       // Convert arguments to integers
                        for( k = line->nParts-1; k--; )
                        {
                                if( caConfigCommands[j].IntArgs & (1 << k) ) {

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