*/
#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);
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");
+}
#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 ===
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);
*/
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;
|| (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) ) {
}
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
}
/**
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;
}
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;
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",
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",
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) ) {