From dfc350d6575a28a419c47fa378123899b35e2b31 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 20 Aug 2011 18:28:32 +0800 Subject: [PATCH] Kernel/x86_64 - Working on 64-bit build, required reworking part of init script code --- Kernel/arch/x86_64/include/arch_config.h | 13 +++++ Kernel/arch/x86_64/include/mm_virt.h | 8 ++- Kernel/arch/x86_64/mm_virt.c | 37 ++++++++++--- Kernel/arch/x86_64/proc.c | 32 ++++++++--- Kernel/include/acess.h | 2 +- Kernel/system.c | 69 ++++++++++++++++++------ 6 files changed, 128 insertions(+), 33 deletions(-) create mode 100644 Kernel/arch/x86_64/include/arch_config.h diff --git a/Kernel/arch/x86_64/include/arch_config.h b/Kernel/arch/x86_64/include/arch_config.h new file mode 100644 index 00000000..c9f47b0d --- /dev/null +++ b/Kernel/arch/x86_64/include/arch_config.h @@ -0,0 +1,13 @@ +/* + */ +#ifndef _ARCH_CONFIG_H_ +#define _ARCH_CONFIG_H_ + + +#define PIT_TIMER_BASE_N 3579545 +#define PIT_TIMER_BASE_D 3 +// PIT Ticks at 1.1931816666666 MHz +// Base is 1193182 HZ +#define PIT_TIMER_DIVISOR 11931 //~100Hz + +#endif diff --git a/Kernel/arch/x86_64/include/mm_virt.h b/Kernel/arch/x86_64/include/mm_virt.h index ebb69232..1a7484cd 100644 --- a/Kernel/arch/x86_64/include/mm_virt.h +++ b/Kernel/arch/x86_64/include/mm_virt.h @@ -11,6 +11,8 @@ #include +#define PAGE_SIZE 0x1000 + // === Memory Location Definitions === /* * Userland - Lower Half @@ -36,9 +38,9 @@ * ---- GAP ---- 9 TiB * FE00 00000000 - FE80 00000000 39 512 GiB Fractal Mapping (PML4 508) * FE80 00000000 - FF00 00000000 39 512 GiB Temp Fractal Mapping - * ---- GAP ---- 512 GiB -- UNUSED -- + * FF00 00000000 - FF80 00000000 39 512 GiB Temporary page mappings * FF80 00000000 - FF80 80000000 31 2 GiB Local APIC - * ---- GAP ---- + * ---- GAP ---- 506 GiB * FFFF 00000000 - FFFF 80000000 31 2 GiB User Code * FFFF 80000000 - FFFF FFFFFFFF 31 2 GiB Kernel code / data */ @@ -71,6 +73,8 @@ #define MM_FRACTAL_BASE (MM_KERNEL_RANGE|(0xFE00##00000000)) #define MM_TMPFRAC_BASE (MM_KERNEL_RANGE|(0xFE80##00000000)) +#define MM_TMPMAP_BASE (MM_KERNEL_RANGE|(0xFF00##00000000)) +#define MM_TMPMAP_END (MM_KERNEL_RANGE|(0xFF80##00000000)) #define MM_LOCALAPIC (MM_KERNEL_RANGE|(0xFF80##00000000)) #define MM_KERNEL_CODE (MM_KERNEL_RANGE|(0xFFFF##80000000)) diff --git a/Kernel/arch/x86_64/mm_virt.c b/Kernel/arch/x86_64/mm_virt.c index ae8784b1..0b856573 100644 --- a/Kernel/arch/x86_64/mm_virt.c +++ b/Kernel/arch/x86_64/mm_virt.c @@ -634,13 +634,29 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) // --- Tempory Mappings --- tVAddr MM_MapTemp(tPAddr PAddr) { - Log_KernelPanic("MM", "TODO: Implement MM_MapTemp"); + const int max_slots = (MM_TMPMAP_END - MM_TMPMAP_BASE) / PAGE_SIZE; + tVAddr ret = MM_TMPMAP_BASE; + int i; + + for( i = 0; i < max_slots; i ++, ret += PAGE_SIZE ) + { + tPAddr *ent; + if( MM_GetPageEntryPtr( ret, 0, 1, 0, &ent) < 0 ) { + continue ; + } + + if( *ent & 1 ) + continue ; + + *ent = PAddr | 3; + return ret; + } return 0; } void MM_FreeTemp(tVAddr VAddr) { - Log_KernelPanic("MM", "TODO: Implement MM_FreeTemp"); + MM_Deallocate(VAddr); return ; } @@ -650,7 +666,13 @@ tPAddr MM_Clone(void) { tPAddr ret; int i; - tVAddr kstackbase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE + 0x1000; + tVAddr kstackbase; + + // tThread->KernelStack is the top + // There is 1 guard page below the stack + kstackbase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE + 0x1000; + + Log("MM_Clone: kstackbase = %p", kstackbase); // #1 Create a copy of the PML4 ret = MM_AllocPhys(); @@ -661,8 +683,6 @@ tPAddr MM_Clone(void) TMPCR3() = ret | 3; INVLPG_ALL(); -// Log_KernelPanic("MM", "TODO: Implement MM_Clone"); - // #3 Set Copy-On-Write to all user pages for( i = 0; i < 256; i ++) { @@ -686,13 +706,17 @@ tPAddr MM_Clone(void) if( i == 509 ) continue; // 510 0xFFFFFE8.. - Temp fractal mapping if( i == 510 ) continue; + + TMPMAPLVL4(i) = PAGEMAPLVL4(i); + if( TMPMAPLVL4(i) & 1 ) + MM_RefPhys( TMPMAPLVL4(i) & PADDR_MASK ); } // #5 Set fractal mapping TMPMAPLVL4(509) = ret | 3; TMPMAPLVL4(510) = 0; // Temp - // #6 Create kernel stack + // #6 Create kernel stack (-1 to account for the guard) TMPMAPLVL4(320) = 0; for( i = 0; i < KERNEL_STACK_SIZE/0x1000-1; i ++ ) { @@ -709,6 +733,7 @@ tPAddr MM_Clone(void) TMPCR3() = 0; INVLPG_ALL(); Mutex_Release(&glMM_TempFractalLock); + Log("MM_Clone: RETURN %P\n", ret); return ret; } diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index 06c7d85d..ed2b6843 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -16,6 +16,7 @@ // === FLAGS === #define DEBUG_TRACE_SWITCH 0 +//#define BREAK_ON_SWITCH 1 // Break into bochs debugger on a task switch // === CONSTANTS === #define SWITCH_MAGIC 0x55ECAFFF##FFFACE55 // There is no code in this area @@ -498,6 +499,7 @@ int Proc_Clone(Uint *Err, Uint Flags) Log("Proc_Clone: Cloning VM"); newThread->MemState.CR3 = MM_Clone(); newThread->KernelStack = cur->KernelStack; +// MAGIC_BREAK(); } else { Uint tmp_rbp, old_rsp = rsp; @@ -542,6 +544,7 @@ int Proc_Clone(Uint *Err, Uint Flags) if(rip == SWITCH_MAGIC) { outb(0x20, 0x20); // ACK Timer and return as child __asm__ __volatile__ ("sti"); +// MAGIC_BREAK(); return 0; } @@ -597,7 +600,7 @@ int Proc_SpawnWorker(void) // Set EIP as parent new->SavedState.RIP = rip; // Mark as active - new->Status = THREAD_STAT_ACTIVE; + new->Status = THREAD_STAT_PREINIT; Threads_AddActive( new ); return new->TID; @@ -789,7 +792,12 @@ void Proc_Scheduler(int CPU) thread->SavedState.UserCS = regs->CS; thread->SavedState.UserRIP = regs->RIP; } - + + #if BREAK_ON_SWITCH + { + tThread *oldthread = thread; + #endif + // Get next thread thread = Threads_GetNextToRun(CPU, thread); @@ -797,9 +805,18 @@ void Proc_Scheduler(int CPU) if(thread == NULL) { thread = gaCPUs[CPU].IdleThread; //Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n"); - //LogF("Zzzzz.\n"); +// LogF("Zzzzz.\n"); //return; } + if(thread == NULL ) { + return ; + } + #if BREAK_ON_SWITCH + if( thread != oldthread ) { + MAGIC_BREAK(); + } + } + #endif #if DEBUG_TRACE_SWITCH LogF("Switching to task %i, CR3 = 0x%x, RIP = %p", @@ -818,16 +835,15 @@ void Proc_Scheduler(int CPU) // Update Kernel Stack pointer gTSSs[CPU].RSP0 = thread->KernelStack-4; - // Set address space - __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3)); - // Switch threads __asm__ __volatile__ ( + "mov %4, %%cr3\n\t" "mov %1, %%rsp\n\t" // Restore RSP "mov %2, %%rbp\n\t" // and RBP "jmp *%3" : : // And return to where we saved state (Proc_Clone or Proc_Scheduler) - "a"(SWITCH_MAGIC), "b"(thread->SavedState.RSP), - "d"(thread->SavedState.RBP), "c"(thread->SavedState.RIP) + "a"(SWITCH_MAGIC), "r"(thread->SavedState.RSP), + "r"(thread->SavedState.RBP), "r"(thread->SavedState.RIP), + "r"(thread->MemState.CR3) ); for(;;); // Shouldn't reach here } diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index ee069eee..f0e537aa 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -441,7 +441,7 @@ extern void Time_Delay(int Delay); * \{ */ extern int Proc_SpawnWorker(void); -extern int Proc_Spawn(char *Path); +extern int Proc_Spawn(const char *Path); extern void Threads_Exit(int TID, int Status); extern void Threads_Yield(void); extern void Threads_Sleep(void); diff --git a/Kernel/system.c b/Kernel/system.c index 66f645f2..cbf828c6 100644 --- a/Kernel/system.c +++ b/Kernel/system.c @@ -27,8 +27,8 @@ typedef struct int MinArgs; // Minimum number of arguments int MaxArgs; // Maximum number of arguments Uint IntArgs; // Bitmap of arguments that should be treated as integers - void *Func; // Function pointer - Uint OptDefaults[N_MAX_ARGS]; // Default values for optional arguments + int Index; // + const char *OptDefaults[N_MAX_ARGS]; // Default values for optional arguments } tConfigCommand; // === IMPORTS === @@ -48,18 +48,28 @@ void System_ExecuteScript(void); tConfigFile *System_Int_ParseFile(char *File); // === CONSTANTS === +enum eConfigCommands { + CC_LOADMODULE, + CC_SPAWN, + CC_MOUNT, + CC_SYMLINK, + CC_MKDIR, + CC_OPEN, + CC_CLOSE, + CC_IOCTL +}; const tConfigCommand caConfigCommands[] = { - {"module", 1,2, 00, Module_LoadFile, {(Uint)"",0}}, // Load a module from a file - {"spawn", 1,1, 00, Proc_Spawn, {0}}, // Spawn a process + {"module", 1,2, 00, CC_LOADMODULE, {"",NULL}}, // Load a module from a file + {"spawn", 1,1, 00, CC_SPAWN, {NULL}}, // Spawn a process // --- VFS --- - {"mount", 3,4, 00, VFS_Mount, {(Uint)"",0}}, // Mount a device - {"symlink", 2,2, 00, VFS_Symlink, {0}}, // Create a Symbolic Link - {"mkdir", 1,1, 00, VFS_MkDir, {0}}, // Create a Directory - {"open", 1,2, 00, VFS_Open, {VFS_OPENFLAG_READ,0}}, // Open a file - {"close", 1,1, 01, VFS_Close, {0}}, // Close an open file - {"ioctl", 3,3, 03, VFS_IOCtl, {0}}, // Call an IOCtl + {"mount", 3,4, 00, CC_MOUNT, {"",0}}, // Mount a device + {"symlink", 2,2, 00, CC_SYMLINK, {0}}, // Create a Symbolic Link + {"mkdir", 1,1, 00, CC_MKDIR, {0}}, // Create a Directory + {"open", 1,2, 00, CC_OPEN, {(void*)VFS_OPENFLAG_READ,0}}, // Open a file + {"close", 1,1, 01, CC_CLOSE, {0}}, // Close an open file + {"ioctl", 3,3, 03, CC_IOCTL, {0}}, // Call an IOCtl - {"", 0,0, 0, NULL, {0}} + {"", 0,0, 0, 0, {0}} }; #define NUM_CONFIG_COMMANDS (sizeof(caConfigCommands)/sizeof(caConfigCommands[0])) @@ -361,7 +371,7 @@ void System_ExecuteScript(void) // Find the command name for( j = 0; j < NUM_CONFIG_COMMANDS; j++ ) { - Uint args[N_MAX_ARGS]; + const char *args[N_MAX_ARGS]; if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0) continue; @@ -394,14 +404,41 @@ void System_ExecuteScript(void) for( k = line->nParts-1; k--; ) { if( k < 32 && (caConfigCommands[j].IntArgs & (1 << k)) ) { - args[k] = atoi(line->Parts[k+1]); + args[k] = (const char *)(Uint)atoi(line->Parts[k+1]); } else { - args[k] = (Uint)line->Parts[k+1]; + args[k] = (char *)line->Parts[k+1]; } - Log_Debug("Config", "args[%i] = 0x%x", k, args[k]); + Log_Debug("Config", "args[%i] = %p", k, args[k]); + } + switch( (enum eConfigCommands) caConfigCommands[j].Index ) + { + case CC_LOADMODULE: + result = Module_LoadFile( args[0], args[1] ); + break; + case CC_SPAWN: + result = Proc_Spawn( args[0] ); + break; + case CC_MOUNT: + result = VFS_Mount( args[0], args[1], args[2], args[3] ); + break; + case CC_SYMLINK: + result = VFS_Symlink( args[0], args[1] ); + break; + case CC_OPEN: + result = VFS_Open( args[0], (Uint)args[1] ); + break; + case CC_CLOSE: + VFS_Close( (Uint)args[0] ); + result = 0; + break; + case CC_MKDIR: + result = VFS_MkDir( args[0] ); + break; + case CC_IOCTL: + result = VFS_IOCtl( (Uint)args[0], (Uint)args[1], (void *)args[2] ); + break; } - result = CallWithArgArray(caConfigCommands[j].Func, caConfigCommands[j].MaxArgs, args); Log_Debug("Config", "result = %i", result); break; } -- 2.20.1