From: John Hodge Date: Thu, 13 May 2010 04:40:09 +0000 (+0800) Subject: Working on separating architecture dependent and independent stuff, X-Git-Tag: rel0.06~194 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=43f12a083f112a410859597c5f45e78b1de2e7c8;p=tpg%2Facess2.git Working on separating architecture dependent and independent stuff, Also did more work on getting the x86_64 port working. - Related changes to VESA driver and usermode --- diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index c6eedfba..aa077e66 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 2150 +BUILD_NUM = 2156 diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 4007a71f..dd52e845 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -6,23 +6,8 @@ #ifndef _ARCH_H_ #define _ARCH_H_ -// - Memory Layout -#define MM_USER_MIN 0x00200000 -#define USER_STACK_SZ 0x00010000 -#define USER_STACK_TOP 0x00800000 -#define MM_USER_MAX 0xBC000000 -#define MM_PPD_MIN 0xBC000000 // Per-Process Data -#define MM_PPD_VFS 0xBC000000 // -#define MM_PPD_CFG 0xBFFFF000 // -#define MM_PPD_MAX 0xB0000000 +// - Base Defintions #define KERNEL_BASE 0xC0000000 -#define MM_KHEAP_BASE 0xC0400000 // C+4MiB -#define MM_KHEAP_MAX 0xCF000000 // -#define MM_KERNEL_VFS 0xCF000000 // -#define MM_KUSER_CODE 0xCFFF0000 // 16 Pages -#define MM_MODULE_MIN 0xD0000000 // Lowest Module Address -#define MM_MODULE_MAX 0xF0000000 // 512 MiB - #define BITS 32 // - Processor/Machine Specific Features diff --git a/Kernel/arch/x86/include/mm_virt.h b/Kernel/arch/x86/include/mm_virt.h index cc2d5d81..4f650e8c 100644 --- a/Kernel/arch/x86/include/mm_virt.h +++ b/Kernel/arch/x86/include/mm_virt.h @@ -5,9 +5,28 @@ #ifndef _MM_VIRT_H #define _MM_VIRT_H + +// - Memory Layout +#define MM_USER_MIN 0x00200000 +#define USER_STACK_SZ 0x00010000 +#define USER_STACK_TOP 0x00800000 +#define USER_LIB_MAX 0xBC000000 +#define MM_USER_MAX 0xBC000000 // Top load address for user libraries +#define MM_PPD_MIN 0xBC000000 // Per-Process Data +#define MM_PPD_VFS 0xBC000000 // +#define MM_PPD_CFG 0xBFFFF000 // +#define MM_PPD_MAX 0xC0000000 // + +#define MM_KHEAP_BASE 0xC0400000 // C+4MiB +#define MM_KHEAP_MAX 0xCF000000 // +#define MM_KERNEL_VFS 0xCF000000 // +#define MM_KUSER_CODE 0xCFFF0000 // 16 Pages +#define MM_MODULE_MIN 0xD0000000 // Lowest Module Address +#define MM_MODULE_MAX 0xF0000000 // 512 MiB + // === FUNCTIONS === extern void MM_FinishVirtualInit(); -extern void MM_SetCR3(Uint32 CR3); +extern void MM_SetCR3(Uint CR3); extern tPAddr MM_Allocate(tVAddr VAddr); extern void MM_Deallocate(tVAddr VAddr); extern int MM_Map(tVAddr VAddr, tPAddr PAddr); diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index 9c933342..cbf03fc6 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -12,6 +12,7 @@ #define DEBUG 0 #define SANITY 1 #include +#include #include #include @@ -429,10 +430,10 @@ int MM_IsUser(tVAddr VAddr) } /** - * \fn void MM_SetCR3(tPAddr CR3) + * \fn void MM_SetCR3(Uint CR3) * \brief Sets the current process space */ -void MM_SetCR3(tPAddr CR3) +void MM_SetCR3(Uint CR3) { __asm__ __volatile__ ("mov %0, %%cr3"::"r"(CR3)); } diff --git a/Kernel/arch/x86_64/Makefile b/Kernel/arch/x86_64/Makefile index 68b9b615..6824c9fd 100644 --- a/Kernel/arch/x86_64/Makefile +++ b/Kernel/arch/x86_64/Makefile @@ -9,9 +9,11 @@ #LD = ld #OBJDUMP = objdump -CPPFLAGS = -CFLAGS = $(KERNEL_CFLAGS) -ASFLAGS = -f elf +MAX_CPUS := 4 + +CPPFLAGS := -DMAX_CPUS=$(MAX_CPUS) +CFLAGS := $(KERNEL_CFLAGS) +ASFLAGS := -f elf64 -D MAX_CPUS=$(MAX_CPUS) ifeq ($(ARCH),amd64) ASFLAGS += -D AMD64=1 @@ -24,5 +26,5 @@ else endif -A_OBJ = start32.ao start64.ao -A_OBJ += main.o lib.o +A_OBJ = start32.ao start64.ao desctab.ao +A_OBJ += main.o lib.o proc.o diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm new file mode 100644 index 00000000..eef93f0d --- /dev/null +++ b/Kernel/arch/x86_64/desctab.asm @@ -0,0 +1,72 @@ +; +; +; +[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 + +%macro PUSH_EX 1-* + %rep %0 + push %1 + %rotate 1 + %endrep +%endmacro +%macro POP_EX 1-* + %rep %0 + %rotate -1 + pop %1 + %endrep +%endmacro + +%macro PUSH_GPR 0 + PUSH_EX r15, r14, r13, r12, r11, r10, r9, r8 + PUSH_EX rsi, rdi, rbp, rsp, rbx, rdx, rcx, rax +%endmacro +%macro POP_GPR 0 + POP_EX rsi, rdi, rbp, rsp, rbx, rdx, rcx, rax + POP_EX r15, r14, r13, r12, r11, r10, r9, r8 +%endmacro + +[extern Proc_Scheduler] +SchedulerIRQ: + ; TODO: Find Current CPU + PUSH_GPR + ;PUSH_FPU + ;PUSH_XMM + + xor rsi, rsi + mov rdi, MM_LOCALAPIC+0x20 + mov esi, [rdi] + call Proc_Scheduler + + ;POP_XMM + ;POP_FPU + POP_GPR + iret diff --git a/Kernel/arch/x86_64/include/arch.h b/Kernel/arch/x86_64/include/arch.h index e076b08e..22c551fc 100644 --- a/Kernel/arch/x86_64/include/arch.h +++ b/Kernel/arch/x86_64/include/arch.h @@ -35,12 +35,13 @@ typedef volatile int tSpinlock; #define IS_LOCKED(lockptr) (!!(*(tSpinlock*)lockptr)) #define LOCK(lockptr) do {int v=1;\ while(v)\ - __asm__ __volatile__("lock xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(lockptr));\ + __asm__ __volatile__("lock xchgl %%eax, (%%rdi)":"=a"(v):"a"(1),"D"(lockptr));\ }while(0) -#define RELEASE(lockptr) __asm__ __volatile__("lock andl $0, (%%edi)"::"D"(lockptr)); +#define RELEASE(lockptr) __asm__ __volatile__("lock andl $0, (%%rdi)"::"D"(lockptr)); #define HALT() __asm__ __volatile__ ("hlt") // Systemcall Registers +// TODO: Fix this structure typedef struct sSyscallRegs { Uint Arg4, Arg5; // RDI, RSI diff --git a/Kernel/arch/x86_64/include/desctab.h b/Kernel/arch/x86_64/include/desctab.h new file mode 100644 index 00000000..de3996c6 --- /dev/null +++ b/Kernel/arch/x86_64/include/desctab.h @@ -0,0 +1,57 @@ +/** + */ +#ifndef _DESCTAB_H_ +#define _DESCTAB_H_ + +typedef struct { + union + { + struct + { + Uint16 LimitLow; + Uint16 BaseLow; + Uint8 BaseMid; + Uint8 Access; + struct { + unsigned LimitHi: 4; + unsigned Flags: 4; + } __attribute__ ((packed)); + Uint8 BaseHi; + }; + Uint32 DWord[2]; + }; +} __attribute__ ((packed)) tGDT; + +typedef struct { + Uint16 OffsetLo; + Uint16 CS; + Uint16 Flags; // 0-2: IST, 3-7: 0, 8-11: Type, 12: 0, 13-14: DPL, 15: Present + Uint16 OffsetMid; + Uint32 OffsetHi; + Uint32 Reserved; +} __attribute__ ((packed)) tIDT; + +typedef struct { + Uint32 Rsvd1; + + Uint64 RSP0; + Uint64 RSP1; + Uint64 RSP2; + + Uint32 Rsvd2[2]; + + // Interrupt Stack Table Pointers + Uint64 IST1; + Uint64 IST2; + Uint64 IST3; + Uint64 IST4; + Uint64 IST5; + Uint64 IST6; + Uint64 IST7; + + Uint32 Rsvd3[2]; + Uint16 Rsvd4; + Uint16 IOMapBase; +} __attribute__ ((packed)) tTSS; + +#endif diff --git a/Kernel/arch/x86_64/include/mm_virt.h b/Kernel/arch/x86_64/include/mm_virt.h index 8032cc77..420db1b1 100644 --- a/Kernel/arch/x86_64/include/mm_virt.h +++ b/Kernel/arch/x86_64/include/mm_virt.h @@ -16,22 +16,48 @@ * Userland - Lower Half * Kernel land - Upper Half * - * 0xFFFF8000 00000000 - 0xFFFFFFFF FFFFFFFF 2**47 Kernel Range - * 8000 00000000 - 8000 7FFFFFFF 2 GiB Identity Map - * 8000 80000000 - 8001 00000000 2 GiB Kernel Heap - * 9000 00000000 - 9800 00000000 cbf Module Space - * 9800 00000000 - 9900 00000000 cbf Per-Process Data - * 9900 00000000 - 9A00 00000000 cbf Kernel VFS + * START ADDRESS END ADDRESS BITS SIZE NAME + * 0xFFFF8000 00000000 - 0xFFFFFFFF FFFFFFFF 47 128 TiB Kernel Range + * 8000 00000000 - 8000 7FFFFFFF 31 2 GiB Identity Map + * 8000 80000000 - 9000 00000000 ~44 16 TiB Kernel Heap + * 9000 00000000 - 9800 00000000 43 8 TiB Module Space + * 9800 00000000 - 9900 00000000 40 1 TiB Per-Process Data + * 9900 00000000 - 9A00 00000000 40 1 TiB Kernel VFS + * A000 00000000 - B000 00000000 44 16 TiB Kernel Stacks + * D000 00000000 - E000 00000000 44 16 TiB Hardware Mappings + * FE00 00000000 - FE80 00000000 39 512 GiB Fractal Mapping + * FE80 00000000 - FF00 00000000 39 512 GiB Temp Fractal Mapping */ -#define MM_USER_MIN 0x00008FFF##FFFFF000 +#define MM_USER_MIN 0x00000000##00010000 +#define USER_LIB_MAX 0x00008000##00000000 +#define USER_STACK_SZ 0x00000000##00020000 // 64 KiB +#define USER_STACK_TOP 0x00008FFF##FFFFF000 +#define MM_USER_MAX 0x00008FFF##FFFFF000 //#define KERNEL_BASE 0xFFF8000##00000000 -#define MM_KHEAP_BASE (KERNEL_BASE|(0x0000##80000000)) -#define MM_KHEAP_MAX (KERNEL_BASE|(0x0001##00000000)) -#define MM_MODULE_MIN (KERNEL_BASE|(0x1000##00000000)) -#define MM_MODULE_MAX (KERNEL_BASE|(0x1800##00000000)) -#define MM_PPD_BASE (KERNEL_BASE|(0x1800##00000000)) -#define MM_PPD_VFS (KERNEL_BASE|(0x1880##00000000)) -#define MM_KERNEL_VFS (KERNEL_BASE|(0x1900##00000000)) +#define MM_KHEAP_BASE (KERNEL_BASE|(0x8000##80000000)) +#define MM_KHEAP_MAX (KERNEL_BASE|(0x8001##00000000)) +#define MM_MODULE_MIN (KERNEL_BASE|(0x9000##00000000)) +#define MM_MODULE_MAX (KERNEL_BASE|(0x9800##00000000)) +#define MM_PPD_BASE (KERNEL_BASE|(0x9800##00000000)) +#define MM_PPD_CFG MM_PPD_BASE +#define MM_PPD_VFS (KERNEL_BASE|(0x9880##00000000)) +#define MM_KERNEL_VFS (KERNEL_BASE|(0x9900##00000000)) +#define MM_KSTACK_BASE (KERNEL_BASE|(0xA000##00000000)) +#define MM_KSTACK_TOP (KERNEL_BASE|(0xC000##00000000)) + +#define MM_HWMAP_BASE (KERNEL_BASE|(0xD000##00000000)) +#define MM_HWMAP_TOP (KERNEL_BASE|(0xE000##00000000)) + +#define MM_LOCALAPIC (KERNEL_BASE|(0xFD00##00000000)) +#define MM_FRACTAL_BASE (KERNEL_BASE|(0xFE00##00000000)) +#define MM_TMPFRAC_BASE (KERNEL_BASE|(0xFE80##00000000)) + + +// === FUNCTIONS === +void MM_FinishVirtualInit(void); +tVAddr MM_NewKStack(void); +tVAddr MM_Clone(void); +tVAddr MM_NewWorkerStack(void); #endif diff --git a/Kernel/arch/x86_64/include/proc.h b/Kernel/arch/x86_64/include/proc.h index 016375f6..d78019de 100644 --- a/Kernel/arch/x86_64/include/proc.h +++ b/Kernel/arch/x86_64/include/proc.h @@ -8,11 +8,30 @@ #include +// 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 int_num, err_code; + Uint eip, cs; + Uint eflags, esp, ss; +} tRegs; + +/** + * \brief Memory State for thread handler + */ typedef struct sMemoryState { tPAddr CR3; } tMemoryState; +/** + * \brief Task state for thread handler + */ typedef struct sTaskState { Uint RIP, RSP, RBP; diff --git a/Kernel/arch/x86_64/lib.c b/Kernel/arch/x86_64/lib.c index e3669c04..ba1a618e 100644 --- a/Kernel/arch/x86_64/lib.c +++ b/Kernel/arch/x86_64/lib.c @@ -53,6 +53,65 @@ Uint16 BigEndian16(Uint16 Value) } // === Memory Manipulation === +int memcmp(const void *__dest, const void *__src, size_t __count) +{ + if( ((tVAddr)__dest & 7) != ((tVAddr)__src & 7) ) { + const Uint8 *src = __src, *dst = __dest; + while(__count) + { + if( *src != *dst ) + return *dst - *src; + src ++; dst ++; __count --; + } + return 0; + } + else { + const Uint8 *src = __src; + const Uint8 *dst = __dest; + const Uint64 *src64, *dst64; + + while( (tVAddr)src & 7 && __count ) { + if( *src != *dst ) + return *dst - *src; + dst ++; src ++; __count --; + } + + src64 = (void*)src; + dst64 = (void*)dst; + + while( __count >= 8 ) + { + if( *src64 != *dst64 ) + { + src = (void*)src64; + dst = (void*)dst64; + if(src[0] != dst[0]) return dst[0]-src[0]; + if(src[1] != dst[1]) return dst[1]-src[1]; + if(src[2] != dst[2]) return dst[2]-src[2]; + if(src[3] != dst[3]) return dst[3]-src[3]; + if(src[4] != dst[4]) return dst[4]-src[4]; + if(src[5] != dst[5]) return dst[5]-src[5]; + if(src[6] != dst[6]) return dst[6]-src[6]; + if(src[7] != dst[7]) return dst[7]-src[7]; + return -1; // This should never happen + } + __count -= 8; + src64 ++; + dst64 ++; + } + + src = (void*)src64; + dst = (void*)dst64; + while( __count-- ) + { + if(*dst != *src) return *dst - *src; + dst ++; + src ++; + } + } + return 0; +} + void *memcpy(void *__dest, const void *__src, size_t __count) { if( ((tVAddr)__dest & 7) != ((tVAddr)__src & 7) ) @@ -78,15 +137,15 @@ void *memcpy(void *__dest, const void *__src, size_t __count) void *memset(void *__dest, int __val, size_t __count) { if( __val != 0 || ((tVAddr)__dest & 7) != 0 ) - __asm__ __volatile__ ("rep stosb" : : "D"(__dest),"a"(__val),"c"(__count)); + __asm__ __volatile__ ("rep stosb" : : "D"(__dest),"a"(__val),"c"(__count)); else { - Uint8 *dst = __dest; + Uint8 *dst = __dest; - __asm__ __volatile__ ("rep stosq" : : "D"(dst),"a"(0),"c"(__count/8)); - dst += __count & ~7; - __count = __count & 7; - while( __count-- ) - *dst++ = 0; + __asm__ __volatile__ ("rep stosq" : : "D"(dst),"a"(0),"c"(__count/8)); + dst += __count & ~7; + __count = __count & 7; + while( __count-- ) + *dst++ = 0; } return __dest; } diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c new file mode 100644 index 00000000..5bb66af9 --- /dev/null +++ b/Kernel/arch/x86_64/proc.c @@ -0,0 +1,770 @@ +/* + * AcessOS Microkernel Version + * proc.c + */ +#include +#include +#include +#include +#include +#include +#if USE_MP +# include +#endif + +// === FLAGS === +#define DEBUG_TRACE_SWITCH 0 + +// === CONSTANTS === +#define SWITCH_MAGIC 0x55ECAFFF##FFFACE55 // There is no code in this area +// Base is 1193182 +#define TIMER_DIVISOR 11931 //~100Hz + +// === IMPORTS === +extern tGDT gGDT[]; +extern void APStartup(); // 16-bit AP startup code +extern Uint GetRIP(); // start.asm +extern Uint64 gaInitPML4[512]; // start.asm +extern void Kernel_Stack_Top; +extern tSpinlock glThreadListLock; +extern int giNumCPUs; +extern int giNextTID; +extern int giTotalTickets; +extern int giNumActiveThreads; +extern tThread gThreadZero; +extern tThread *gActiveThreads; +extern tThread *gSleepingThreads; +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(); + +// === PROTOTYPES === +void ArchThreads_Init(); +#if USE_MP +void MP_StartAP(int CPU); +void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode); +#endif +void Proc_Start(); +tThread *Proc_GetCurThread(); +void Proc_ChangeStack(); + int Proc_Clone(Uint *Err, Uint Flags); +void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP); +void Proc_CallFaultHandler(tThread *Thread); +void Proc_Scheduler(); + +// === GLOBALS === +// --- Multiprocessing --- +#if USE_MP +volatile int giNumInitingCPUs = 0; +tMPInfo *gMPFloatPtr = NULL; +tAPIC *gpMP_LocalAPIC = NULL; +Uint8 gaAPIC_to_CPU[256] = {0}; +tCPU gaCPUs[MAX_CPUS]; +#else +tThread *gCurrentThread = NULL; +#endif +tTSS *gTSSs = NULL; +tTSS gTSS0 = {0}; +// --- Error Recovery --- +Uint32 gaDoubleFaultStack[1024]; + +// === CODE === +/** + * \fn void ArchThreads_Init() + * \brief Starts the process scheduler + */ +void ArchThreads_Init() +{ + Uint pos = 0; + + #if USE_MP + tMPTable *mptable; + + // Mark BSP as active + gaCPUs[0].State = 2; + + // -- Initialise Multiprocessing + // Find MP Floating Table + // - EBDA/Last 1Kib (640KiB) + for(pos = KERNEL_BASE|0x9F000; pos < (KERNEL_BASE|0xA0000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; + break; + } + } + // - Last KiB (512KiB base mem) + if(!gMPFloatPtr) { + for(pos = KERNEL_BASE|0x7F000; pos < (KERNEL_BASE|0x80000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; + break; + } + } + } + // - BIOS ROM + if(!gMPFloatPtr) { + for(pos = KERNEL_BASE|0xE0000; pos < (KERNEL_BASE|0x100000); pos += 16) { + if( *(Uint*)(pos) == MPPTR_IDENT ) { + Log("Possible %p", pos); + if( ByteSum((void*)pos, sizeof(tMPInfo)) != 0 ) continue; + gMPFloatPtr = (void*)pos; + break; + } + } + } + + // If the MP Table Exists, parse it + if(gMPFloatPtr) + { + int i; + tMPTable_Ent *ents; + Log("gMPFloatPtr = %p", gMPFloatPtr); + Log("*gMPFloatPtr = {"); + Log("\t.Sig = 0x%08x", gMPFloatPtr->Sig); + Log("\t.MPConfig = 0x%08x", gMPFloatPtr->MPConfig); + Log("\t.Length = 0x%02x", gMPFloatPtr->Length); + Log("\t.Version = 0x%02x", gMPFloatPtr->Version); + Log("\t.Checksum = 0x%02x", gMPFloatPtr->Checksum); + Log("\t.Features = [0x%02x,0x%02x,0x%02x,0x%02x,0x%02x]", + gMPFloatPtr->Features[0], gMPFloatPtr->Features[1], + gMPFloatPtr->Features[2], gMPFloatPtr->Features[3], + gMPFloatPtr->Features[4] + ); + Log("}"); + + mptable = (void*)( KERNEL_BASE|gMPFloatPtr->MPConfig ); + Log("mptable = %p", mptable); + Log("*mptable = {"); + Log("\t.Sig = 0x%08x", mptable->Sig); + Log("\t.BaseTableLength = 0x%04x", mptable->BaseTableLength); + Log("\t.SpecRev = 0x%02x", mptable->SpecRev); + Log("\t.Checksum = 0x%02x", mptable->Checksum); + Log("\t.OEMID = '%8c'", mptable->OemID); + Log("\t.ProductID = '%8c'", mptable->ProductID); + Log("\t.OEMTablePtr = %p'", mptable->OEMTablePtr); + Log("\t.OEMTableSize = 0x%04x", mptable->OEMTableSize); + Log("\t.EntryCount = 0x%04x", mptable->EntryCount); + Log("\t.LocalAPICMemMap = 0x%08x", mptable->LocalAPICMemMap); + Log("\t.ExtendedTableLen = 0x%04x", mptable->ExtendedTableLen); + Log("\t.ExtendedTableChecksum = 0x%02x", mptable->ExtendedTableChecksum); + Log("}"); + + gpMP_LocalAPIC = (void*)MM_MapHWPage(mptable->LocalAPICMemMap, 1); + + ents = mptable->Entries; + giNumCPUs = 0; + + for( i = 0; i < mptable->EntryCount; i ++ ) + { + int entSize = 0; + switch( ents->Type ) + { + case 0: // Processor + entSize = 20; + Log("%i: Processor", i); + Log("\t.APICID = %i", ents->Proc.APICID); + Log("\t.APICVer = 0x%02x", ents->Proc.APICVer); + Log("\t.CPUFlags = 0x%02x", ents->Proc.CPUFlags); + Log("\t.CPUSignature = 0x%08x", ents->Proc.CPUSignature); + Log("\t.FeatureFlags = 0x%08x", ents->Proc.FeatureFlags); + + + if( !(ents->Proc.CPUFlags & 1) ) { + Log("DISABLED"); + break; + } + + // Check if there is too many processors + if(giNumCPUs >= MAX_CPUS) { + giNumCPUs ++; // If `giNumCPUs` > MAX_CPUS later, it will be clipped + break; + } + + // Initialise CPU Info + gaAPIC_to_CPU[ents->Proc.APICID] = giNumCPUs; + gaCPUs[giNumCPUs].APICID = ents->Proc.APICID; + gaCPUs[giNumCPUs].State = 0; + giNumCPUs ++; + + // Send IPI + if( !(ents->Proc.CPUFlags & 2) ) + { + MP_StartAP( giNumCPUs-1 ); + } + + break; + case 1: // Bus + entSize = 8; + Log("%i: Bus", i); + Log("\t.ID = %i", ents->Bus.ID); + Log("\t.TypeString = '%6c'", ents->Bus.TypeString); + break; + case 2: // I/O APIC + entSize = 8; + Log("%i: I/O APIC", i); + Log("\t.ID = %i", ents->IOAPIC.ID); + Log("\t.Version = 0x%02x", ents->IOAPIC.Version); + Log("\t.Flags = 0x%02x", ents->IOAPIC.Flags); + Log("\t.Addr = 0x%08x", ents->IOAPIC.Addr); + break; + case 3: // I/O Interrupt Assignment + entSize = 8; + Log("%i: I/O Interrupt Assignment", i); + Log("\t.IntType = %i", ents->IOInt.IntType); + Log("\t.Flags = 0x%04x", ents->IOInt.Flags); + Log("\t.SourceBusID = 0x%02x", ents->IOInt.SourceBusID); + Log("\t.SourceBusIRQ = 0x%02x", ents->IOInt.SourceBusIRQ); + Log("\t.DestAPICID = 0x%02x", ents->IOInt.DestAPICID); + Log("\t.DestAPICIRQ = 0x%02x", ents->IOInt.DestAPICIRQ); + break; + case 4: // Local Interrupt Assignment + entSize = 8; + Log("%i: Local Interrupt Assignment", i); + Log("\t.IntType = %i", ents->LocalInt.IntType); + Log("\t.Flags = 0x%04x", ents->LocalInt.Flags); + Log("\t.SourceBusID = 0x%02x", ents->LocalInt.SourceBusID); + Log("\t.SourceBusIRQ = 0x%02x", ents->LocalInt.SourceBusIRQ); + Log("\t.DestLocalAPICID = 0x%02x", ents->LocalInt.DestLocalAPICID); + Log("\t.DestLocalAPICIRQ = 0x%02x", ents->LocalInt.DestLocalAPICIRQ); + break; + default: + Log("%i: Unknown (%i)", i, ents->Type); + break; + } + ents = (void*)( (Uint)ents + entSize ); + } + + if( giNumCPUs > MAX_CPUS ) { + Warning("Too many CPUs detected (%i), only using %i of them", giNumCPUs, MAX_CPUS); + giNumCPUs = MAX_CPUS; + } + + while( giNumInitingCPUs ) + MM_FinishVirtualInit(); + + Panic("Uh oh... MP Table Parsing is unimplemented\n"); + } + else { + Log("No MP Table was found, assuming uniprocessor\n"); + giNumCPUs = 1; + gTSSs = &gTSS0; + } + #else + giNumCPUs = 1; + gTSSs = &gTSS0; + MM_FinishVirtualInit(); + #endif + + #if USE_MP + // Initialise Normal TSS(s) + for(pos=0;pos> 16; + gGDT[6+pos*2].BaseHi = ((Uint)(&gTSSs[pos])) >> 24; + gGDT[6+pos*2+1].DWord[0] = ((Uint)(&gTSSs[pos])) >> 32; + #if USE_MP + } + for(pos=0;pos>8)&0xFF); // High Byte + + // Create Per-Process Data Block + MM_Allocate(MM_PPD_CFG); + + // Change Stacks + Proc_ChangeStack(); +} + +#if USE_MP +void MP_StartAP(int CPU) +{ + Log("Starting AP %i (APIC %i)", CPU, gaCPUs[CPU].APICID); + // Set location of AP startup code and mark for a warm restart + *(Uint16*)(KERNEL_BASE|0x467) = (Uint)&APStartup - (KERNEL_BASE|0xFFFF0); + *(Uint16*)(KERNEL_BASE|0x469) = 0xFFFF; + outb(0x70, 0x0F); outb(0x71, 0x0A); // Warm Reset + MP_SendIPI(gaCPUs[CPU].APICID, 0, 5); + giNumInitingCPUs ++; +} + +void MP_SendIPI(Uint8 APICID, int Vector, int DeliveryMode) +{ + Uint32 addr = (Uint)gpMP_LocalAPIC + 0x300; + Uint32 val; + + // High + val = (Uint)APICID << 24; + Log("*%p = 0x%08x", addr+0x10, val); + *(Uint32*)(addr+0x10) = val; + // Low (and send) + val = ((DeliveryMode & 7) << 8) | (Vector & 0xFF); + Log("*%p = 0x%08x", addr, val); + *(Uint32*)addr = val; +} +#endif + +/** + * \fn void Proc_Start() + * \brief Start process scheduler + */ +void Proc_Start() +{ + // Start Interrupts (and hence scheduler) + __asm__ __volatile__("sti"); +} + +/** + * \fn tThread *Proc_GetCurThread() + * \brief Gets the current thread + */ +tThread *Proc_GetCurThread() +{ + #if USE_MP + return gaCPUs[ gaAPIC_to_CPU[gpMP_LocalAPIC->ID.Val&0xFF] ].Current; + #else + return gCurrentThread; + #endif +} + +/** + * \fn void Proc_ChangeStack() + * \brief Swaps the current stack for a new one (in the proper stack reigon) + */ +void Proc_ChangeStack() +{ + Uint rsp, rbp; + Uint tmp_rbp, old_rsp; + Uint curBase, newBase; + + __asm__ __volatile__ ("mov %%rsp, %0":"=r"(rsp)); + __asm__ __volatile__ ("mov %%rbp, %0":"=r"(rbp)); + + old_rsp = rsp; + + // Create new KStack + newBase = MM_NewKStack(); + // Check for errors + if(newBase == 0) { + Panic("What the?? Unable to allocate space for initial kernel stack"); + return; + } + + curBase = (Uint)&Kernel_Stack_Top; + + LOG("curBase = 0x%x, newBase = 0x%x", curBase, newBase); + + // Get ESP as a used size + rsp = curBase - rsp; + LOG("memcpy( %p, %p, 0x%x )", (void*)(newBase - rsp), (void*)(curBase - rsp), rsp ); + // Copy used stack + memcpy( (void*)(newBase - rsp), (void*)(curBase - rsp), rsp ); + // Get ESP as an offset in the new stack + rsp = newBase - rsp; + // Adjust EBP + rbp = newBase - (curBase - rbp); + + // Repair EBPs & Stack Addresses + // Catches arguments also, but may trash stack-address-like values + for(tmp_rbp = rsp; tmp_rbp < newBase; tmp_rbp += 4) + { + if(old_rsp < *(Uint*)tmp_rbp && *(Uint*)tmp_rbp < curBase) + *(Uint*)tmp_rbp += newBase - curBase; + } + + Proc_GetCurThread()->KernelStack = newBase; + + __asm__ __volatile__ ("mov %0, %%rsp"::"r"(rsp)); + __asm__ __volatile__ ("mov %0, %%rbp"::"r"(rbp)); +} + +/** + * \fn int Proc_Clone(Uint *Err, Uint Flags) + * \brief Clone the current process + */ +int Proc_Clone(Uint *Err, Uint Flags) +{ + tThread *newThread; + tThread *cur = Proc_GetCurThread(); + Uint rip, rsp, rbp; + + __asm__ __volatile__ ("mov %%rsp, %0": "=r"(rsp)); + __asm__ __volatile__ ("mov %%rbp, %0": "=r"(rbp)); + + newThread = Threads_CloneTCB(Err, Flags); + if(!newThread) return -1; + + // Initialise Memory Space (New Addr space or kernel stack) + if(Flags & CLONE_VM) { + newThread->MemState.CR3 = MM_Clone(); + newThread->KernelStack = cur->KernelStack; + } else { + Uint tmp_rbp, old_rsp = rsp; + + // Set CR3 + newThread->MemState.CR3 = cur->MemState.CR3; + + // Create new KStack + newThread->KernelStack = MM_NewKStack(); + // Check for errors + if(newThread->KernelStack == 0) { + free(newThread); + return -1; + } + + // Get ESP as a used size + rsp = cur->KernelStack - rsp; + // Copy used stack + memcpy( + (void*)(newThread->KernelStack - rsp), + (void*)(cur->KernelStack - rsp), + rsp + ); + // Get ESP as an offset in the new stack + rsp = newThread->KernelStack - rsp; + // Adjust EBP + rbp = newThread->KernelStack - (cur->KernelStack - rbp); + + // Repair EBPs & Stack Addresses + // Catches arguments also, but may trash stack-address-like values + for(tmp_rbp = rsp; tmp_rbp < newThread->KernelStack; tmp_rbp += 4) + { + if(old_rsp < *(Uint*)tmp_rbp && *(Uint*)tmp_rbp < cur->KernelStack) + *(Uint*)tmp_rbp += newThread->KernelStack - cur->KernelStack; + } + } + + // Save core machine state + newThread->SavedState.RSP = rsp; + newThread->SavedState.RBP = rbp; + rip = GetRIP(); + if(rip == SWITCH_MAGIC) { + outb(0x20, 0x20); // ACK Timer and return as child + return 0; + } + + // Set EIP as parent + newThread->SavedState.RIP = rip; + + // Lock list and add to active + Threads_AddActive(newThread); + + return newThread->TID; +} + +/** + * \fn int Proc_SpawnWorker() + * \brief Spawns a new worker thread + */ +int Proc_SpawnWorker() +{ + tThread *new, *cur; + Uint rip, rsp, rbp; + + cur = Proc_GetCurThread(); + + // Create new thread + new = malloc( sizeof(tThread) ); + if(!new) { + Warning("Proc_SpawnWorker - Out of heap space!\n"); + return -1; + } + memcpy(new, &gThreadZero, sizeof(tThread)); + // Set Thread ID + new->TID = giNextTID++; + // Create a new worker stack (in PID0's address space) + // The stack is relocated by this code + new->KernelStack = MM_NewWorkerStack(); + + // Get ESP and EBP based in the new stack + __asm__ __volatile__ ("mov %%rsp, %0": "=r"(rsp)); + __asm__ __volatile__ ("mov %%rbp, %0": "=r"(rbp)); + rsp = new->KernelStack - (cur->KernelStack - rsp); + rbp = new->KernelStack - (cur->KernelStack - rbp); + + // Save core machine state + new->SavedState.RSP = rsp; + new->SavedState.RBP = rbp; + rip = GetRIP(); + if(rip == SWITCH_MAGIC) { + outb(0x20, 0x20); // ACK Timer and return as child + return 0; + } + + // Set EIP as parent + new->SavedState.RIP = rip; + // Mark as active + new->Status = THREAD_STAT_ACTIVE; + Threads_AddActive( new ); + + return new->TID; +} + +/** + * \fn Uint Proc_MakeUserStack() + * \brief Creates a new user stack + */ +Uint Proc_MakeUserStack() +{ + int i; + Uint base = USER_STACK_TOP - USER_STACK_SZ; + + // Check Prospective Space + for( i = USER_STACK_SZ >> 12; i--; ) + if( MM_GetPhysAddr( base + (i<<12) ) != 0 ) + break; + + if(i != -1) return 0; + + // Allocate Stack - Allocate incrementally to clean up MM_Dump output + for( i = 0; i < USER_STACK_SZ/4069; i++ ) + MM_Allocate( base + (i<<12) ); + + return base + USER_STACK_SZ; +} + + +/** + * \fn void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) + * \brief Starts a user task + */ +void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize) +{ + Uint *stack = (void*)Proc_MakeUserStack(); + int i; + Uint delta; + Uint16 ss, cs; + + LOG("stack = 0x%x", stack); + + // Copy Arguments + stack = (void*)( (Uint)stack - DataSize ); + memcpy( stack, ArgV, DataSize ); + + // Adjust Arguments and environment + delta = (Uint)stack - (Uint)ArgV; + ArgV = (char**)stack; + for( i = 0; ArgV[i]; i++ ) ArgV[i] += delta; + i ++; + EnvP = &ArgV[i]; + for( i = 0; EnvP[i]; i++ ) EnvP[i] += delta; + + // User Mode Segments + ss = 0x23; cs = 0x1B; + + // Arguments + *--stack = (Uint)EnvP; + *--stack = (Uint)ArgV; + *--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) +{ + Uint *stack = (void*)Stack; + *--stack = SS; //Stack Segment + *--stack = Stack; //Stack Pointer + *--stack = Flags; //EFLAGS (Resvd (0x2) and IF (0x20)) + *--stack = CS; //Code Segment + *--stack = IP; //EIP + //PUSHAD + *--stack = 0xAAAAAAAA; // eax + *--stack = 0xCCCCCCCC; // ecx + *--stack = 0xDDDDDDDD; // edx + *--stack = 0xBBBBBBBB; // ebx + *--stack = 0xD1D1D1D1; // edi + *--stack = 0x54545454; // rsp - NOT POPED + *--stack = 0x51515151; // esi + *--stack = 0xB4B4B4B4; // rbp + //Individual PUSHs + *--stack = SS; // ds + + __asm__ __volatile__ ( + "mov %%rax,%%rsp;\n\t" // Set stack pointer + "iret;\n\t" : : "a" (stack)); + for(;;); +} + +/** + * \fn int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) + * \brief Demotes a process to a lower permission level + * \param Err Pointer to user's errno + * \param Dest New Permission Level + * \param Regs Pointer to user's register structure + */ +int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) +{ + int cpl = Regs->cs & 3; + // Sanity Check + if(Dest > 3 || Dest < 0) { + *Err = -EINVAL; + return -1; + } + + // Permission Check + if(cpl > Dest) { + *Err = -EACCES; + return -1; + } + + // 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; +} + +/** + * \brief Calls a signal handler in user mode + * \note Used for signals + */ +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)); + for(;;); +} + +/** + * \fn void Proc_Scheduler(int CPU) + * \brief Swap current thread and clears dead threads + */ +void Proc_Scheduler(int CPU) +{ + Uint rsp, rbp, rip; + tThread *thread; + + // If the spinlock is set, let it complete + if(IS_LOCKED(&glThreadListLock)) return; + + // Clear Delete Queue + while(gDeleteThreads) + { + thread = gDeleteThreads->Next; + if(gDeleteThreads->IsLocked) { // Only free if structure is unused + gDeleteThreads->Status = THREAD_STAT_NULL; + free( gDeleteThreads ); + } + gDeleteThreads = thread; + } + + // Check if there is any tasks running + if(giNumActiveThreads == 0) { + Log("No Active threads, sleeping"); + __asm__ __volatile__ ("hlt"); + return; + } + + // Get current thread + #if USE_MP + thread = gaCPUs[CPU].Current; + #else + thread = gCurrentThread; + #endif + + // Reduce remaining quantum and continue timeslice if non-zero + if(thread->Remaining--) return; + // Reset quantum for next call + thread->Remaining = thread->Quantum; + + // Get machine state + __asm__ __volatile__ ("mov %%rsp, %0":"=r"(rsp)); + __asm__ __volatile__ ("mov %%rbp, %0":"=r"(rbp)); + rip = GetRIP(); + if(rip == SWITCH_MAGIC) return; // Check if a switch happened + + // Save machine state + thread->SavedState.RSP = rsp; + thread->SavedState.RBP = rbp; + thread->SavedState.RIP = rip; + + // Get next thread + thread = Threads_GetNextToRun(CPU); + + // Error Check + if(thread == NULL) { + Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n"); + return; + } + + #if DEBUG_TRACE_SWITCH + Log("Switching to task %i, CR3 = 0x%x, RIP = %p", + thread->TID, + thread->MemState.CR3, + thread->SavedState.RIP + ); + #endif + + // Set current thread + #if USE_MP + gaCPUs[CPU].Current = thread; + #else + gCurrentThread = thread; + #endif + + // Update Kernel Stack pointer + gTSSs[CPU].RSP0 = thread->KernelStack-4; + + // Set address space + #if USE_PAE + # error "Todo: Implement PAE Address space switching" + #else + __asm__ __volatile__ ("mov %0, %%cr3"::"a"(thread->MemState.CR3)); + #endif + + #if 0 + if(thread->SavedState.RSP > 0xC0000000 + && thread->SavedState.RSP < thread->KernelStack-0x2000) { + Log_Warning("Proc", "Possible bad ESP %p (PID %i)", thread->SavedState.ESP); + } + #endif + + // Switch threads + __asm__ __volatile__ ( + "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) + ); + for(;;); // Shouldn't reach here +} + +// === EXPORTS === +EXPORT(Proc_SpawnWorker); diff --git a/Kernel/arch/x86_64/start32.asm b/Kernel/arch/x86_64/start32.asm index eada7b99..4ac23fe1 100644 --- a/Kernel/arch/x86_64/start32.asm +++ b/Kernel/arch/x86_64/start32.asm @@ -45,29 +45,34 @@ start: [section .data] gGDT: dd 0,0 - dd 0x00000000, 0x00209800 ; 64-bit Code - dd 0x00000000, 0x00009000 ; 64-bit Data + dd 0x00000000, 0x00209800 ; 0x08: 64-bit Code + dd 0x00000000, 0x00009000 ; 0x10: 64-bit Data + dd 0x00000000, 0x00209800 ; 0x18: 64-bit User Code + dd 0x00000000, 0x00209000 ; 0x20: 64-bit User Data + dd 0x00000000, 0x00209800 ; 0x38: 32-bit User Code + dd 0x00000000, 0x00209000 ; 0x30: 32-bit User Data + times MAX_CPUS dd 0, 0, 0, 0 ; 0x38+16*n: TSS 0 gGDTPtr: dw $-gGDT-1 dd gGDT dd 0 [section .padata] -gInitialPML4: ; 256 TiB +gInitialPML4: ; Covers 256 TiB (Full 48-bit Virtual Address Space dd gInitialPDP + 3, 0 ; Identity Map Low 4Mb times 256-1 dq 0 - dd gInitialPDP + 3, 0 ; Identity Map Low 4Mb to kernel base + dd gInitialPDP + 3, 0 ; Map Low 4Mb to kernel base times 256-1 dq 0 -gInitialPDP: ; 512 GiB +gInitialPDP: ; Covers 512 GiB dd gInitialPD + 3, 0 times 511 dq 0 -gInitialPD: ; 1 GiB +gInitialPD: ; Covers 1 GiB dd gInitialPT1 + 3, 0 dd gInitialPT2 + 3, 0 -gInitialPT1: ; 2 MiB +gInitialPT1: ; Covers 2 MiB %assign i 1 %rep 512 dq i*4096+3 diff --git a/Kernel/arch/x86_64/start64.asm b/Kernel/arch/x86_64/start64.asm index e69de29b..67ba23c9 100644 --- a/Kernel/arch/x86_64/start64.asm +++ b/Kernel/arch/x86_64/start64.asm @@ -0,0 +1,7 @@ +; +; Acess2 x86_64 Port +; +[bits 64] + +start64: + jmp $ diff --git a/Kernel/binary.c b/Kernel/binary.c index ffa07304..4feb1d3a 100644 --- a/Kernel/binary.c +++ b/Kernel/binary.c @@ -11,7 +11,7 @@ #define BIN_LOWEST MM_USER_MIN // 1MiB #define BIN_GRANUALITY 0x10000 // 64KiB //! \todo Move 0xBC000000 to mm_virt.h -#define BIN_HIGHEST (0xBC000000-BIN_GRANUALITY) // Just below the kernel +#define BIN_HIGHEST (USER_LIB_MAX-BIN_GRANUALITY) // Just below the kernel #define KLIB_LOWEST MM_MODULE_MIN #define KLIB_GRANUALITY 0x10000 // 32KiB #define KLIB_HIGHEST (MM_MODULE_MAX-KLIB_GRANUALITY) diff --git a/Modules/Display/VESA/main.c b/Modules/Display/VESA/main.c index 43b7147f..0524a35f 100644 --- a/Modules/Display/VESA/main.c +++ b/Modules/Display/VESA/main.c @@ -494,7 +494,7 @@ void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, else { // Normal copy is OK while( H -- ) { - memcpyd((Uint32*)gpVesa_Framebuffer + dst, (Uint32*)gpVesa_Framebuffer + src, W); + memcpy((Uint32*)gpVesa_Framebuffer + dst, (Uint32*)gpVesa_Framebuffer + src, W); dst += scrnwidth; src += scrnwidth; } diff --git a/Modules/Makefile.tpl b/Modules/Makefile.tpl index a1775ddf..b20a731e 100644 --- a/Modules/Makefile.tpl +++ b/Modules/Makefile.tpl @@ -46,7 +46,7 @@ ifeq ($(BUILDTYPE),dynamic) $(BIN): %.kmd.$(ARCH): $(OBJ) @echo --- $(LD) -o $@ # $(LD) -T $(ACESSDIR)/Modules/link.ld --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) - $(LD) --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) + @$(LD) --allow-shlib-undefined -shared -nostdlib -o $@ $(OBJ) @$(OBJDUMP) -d $(BIN) > $(BIN).dsm else $(BIN): %.xo.$(ARCH): $(OBJ) diff --git a/Usermode/Applications/Makefile.tpl b/Usermode/Applications/Makefile.tpl index 8aad2695..530054b4 100644 --- a/Usermode/Applications/Makefile.tpl +++ b/Usermode/Applications/Makefile.tpl @@ -12,7 +12,7 @@ DEPFILES := $(OBJ:%.o=%.d) all: $(BIN) clean: - @$(RM) $(OBJ) $(BIN) $(BIN).dsm Map.txt + @$(RM) $(OBJ) $(DEPFILES) $(BIN) $(BIN).dsm Map.txt install: $(BIN) $(xCP) $(BIN) $(DISTROOT)/$(DIR)/ diff --git a/Usermode/Applications/axwin2_src/WM/interface.c b/Usermode/Applications/axwin2_src/WM/interface.c index 52030f3b..b71d9446 100644 --- a/Usermode/Applications/axwin2_src/WM/interface.c +++ b/Usermode/Applications/axwin2_src/WM/interface.c @@ -39,7 +39,7 @@ void Interface_Init(void) // ---- Plain
style spacer ---- WM_CreateElement(area, ELETYPE_SPACER, 0); - // Windows Go Here + // Open Windows Go Here // --- Bottom Segment --- area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_ALIGN_END); diff --git a/Usermode/Libraries/ld-acess.so_src/loadlib.c b/Usermode/Libraries/ld-acess.so_src/loadlib.c index e0b3b254..e5090ddd 100644 --- a/Usermode/Libraries/ld-acess.so_src/loadlib.c +++ b/Usermode/Libraries/ld-acess.so_src/loadlib.c @@ -1,220 +1,220 @@ -/* - AcessOS 1 - Dynamic Loader - By thePowersGang -*/ -#include "common.h" - -#define DEBUG 0 - -#if DEBUG -# define DEBUGS(v...) SysDebug(v) -#else -# define DEBUGS(v...) -#endif - -// === PROTOTYPES === +/* + AcessOS 1 - Dynamic Loader + By thePowersGang +*/ +#include "common.h" + +#define DEBUG 0 + +#if DEBUG +# define DEBUGS(v...) SysDebug(v) +#else +# define DEBUGS(v...) +#endif + +// === PROTOTYPES === Uint IsFileLoaded(char *file); - int GetSymbolFromBase(Uint base, char *name, Uint *ret); - -// === CONSTANTS === -const struct { - Uint Value; - char *Name; -} caLocalExports[] = { - {gLoadedLibraries, "gLoadedLibraries"} -}; - -// === GLOABLS === -tLoadedLib gLoadedLibraries[MAX_LOADED_LIBRARIES]; -char gsLoadedStrings[MAX_STRINGS_BYTES]; -char *gsNextAvailString = gsLoadedStrings; -//tLoadLib *gpLoadedLibraries = NULL; - -// === CODE === -char *FindLibrary(char *DestBuf, char *SoName, char *ExtraSearchDir) -{ - // -- #1: Executable Specified - if(ExtraSearchDir) - { - strcpy(DestBuf, ExtraSearchDir); - strcat(DestBuf, "/"); - strcat(DestBuf, SoName); - if(file_exists(DestBuf)) return DestBuf; - } - - // -- #2: System - strcpy(DestBuf, SYSTEM_LIB_DIR); - strcat(DestBuf, SoName); - if(file_exists(DestBuf)) return DestBuf; - - // -- #3: Current Directory - if(file_exists(SoName)) return SoName; - - return NULL; -} - -/** - */ -Uint LoadLibrary(char *SoName, char *SearchDir, char **envp) -{ - char sTmpName[1024]; - char *filename; - Uint iArg; - void (*fEntry)(int, int, char *[], char**); - - DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp); - - // Create Temp Name - filename = FindLibrary(sTmpName, SoName, SearchDir); - if(filename == NULL) { - DEBUGS("LoadLibrary: RETURN 0\n"); - return 0; - } - DEBUGS(" LoadLibrary: filename='%s'\n", filename); - - if( (iArg = IsFileLoaded(filename)) ) - return iArg; - - // Load Library - iArg = SysLoadBin(filename, (Uint*)&fEntry); - if(iArg == 0) { - DEBUGS("LoadLibrary: RETURN 0\n"); - return 0; - } - - DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry); - - // Load Symbols - fEntry = (void*)DoRelocate( iArg, envp, filename ); - - // Call Entrypoint - DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", SoName, fEntry); - fEntry(iArg, 0, NULL, envp); - - DEBUGS("LoadLibrary: RETURN 1\n"); - return iArg; + int GetSymbolFromBase(Uint base, char *name, Uint *ret); + +// === CONSTANTS === +const struct { + Uint Value; + char *Name; +} caLocalExports[] = { + {(Uint)gLoadedLibraries, "gLoadedLibraries"} +}; + +// === GLOABLS === +tLoadedLib gLoadedLibraries[MAX_LOADED_LIBRARIES]; +char gsLoadedStrings[MAX_STRINGS_BYTES]; +char *gsNextAvailString = gsLoadedStrings; +//tLoadLib *gpLoadedLibraries = NULL; + +// === CODE === +char *FindLibrary(char *DestBuf, char *SoName, char *ExtraSearchDir) +{ + // -- #1: Executable Specified + if(ExtraSearchDir) + { + strcpy(DestBuf, ExtraSearchDir); + strcat(DestBuf, "/"); + strcat(DestBuf, SoName); + if(file_exists(DestBuf)) return DestBuf; + } + + // -- #2: System + strcpy(DestBuf, SYSTEM_LIB_DIR); + strcat(DestBuf, SoName); + if(file_exists(DestBuf)) return DestBuf; + + // -- #3: Current Directory + if(file_exists(SoName)) return SoName; + + return NULL; } - -/** - * \fn Uint IsFileLoaded(char *file) - * \brief Determine if a file is already loaded - */ -Uint IsFileLoaded(char *file) -{ - int i; - DEBUGS("IsFileLoaded: (file='%s')", file); - for( i = 0; i < MAX_LOADED_LIBRARIES; i++ ) - { - if(gLoadedLibraries[i].Base == 0) break; // Last entry has Base set to NULL - DEBUGS(" strcmp('%s', '%s')", gLoadedLibraries[i].Name, file); - if(strcmp(gLoadedLibraries[i].Name, file) == 0) { - DEBUGS("IsFileLoaded: Found %i (0x%x)", i, gLoadedLibraries[i].Base); - return gLoadedLibraries[i].Base; - } - } - DEBUGS("IsFileLoaded: Not Found"); - return 0; -} - -/** - * \fn void AddLoaded(char *File, Uint base) - * \brief Add a file to the loaded list + +/** + */ +Uint LoadLibrary(char *SoName, char *SearchDir, char **envp) +{ + char sTmpName[1024]; + char *filename; + Uint iArg; + void (*fEntry)(int, int, char *[], char**); + + DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp); + + // Create Temp Name + filename = FindLibrary(sTmpName, SoName, SearchDir); + if(filename == NULL) { + DEBUGS("LoadLibrary: RETURN 0\n"); + return 0; + } + DEBUGS(" LoadLibrary: filename='%s'\n", filename); + + if( (iArg = IsFileLoaded(filename)) ) + return iArg; + + // Load Library + iArg = SysLoadBin(filename, (Uint*)&fEntry); + if(iArg == 0) { + DEBUGS("LoadLibrary: RETURN 0\n"); + return 0; + } + + DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry); + + // Load Symbols + fEntry = (void*)DoRelocate( iArg, envp, filename ); + + // Call Entrypoint + DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", SoName, fEntry); + fEntry(iArg, 0, NULL, envp); + + DEBUGS("LoadLibrary: RETURN 1\n"); + return iArg; +} + +/** + * \fn Uint IsFileLoaded(char *file) + * \brief Determine if a file is already loaded + */ +Uint IsFileLoaded(char *file) +{ + int i; + DEBUGS("IsFileLoaded: (file='%s')", file); + for( i = 0; i < MAX_LOADED_LIBRARIES; i++ ) + { + if(gLoadedLibraries[i].Base == 0) break; // Last entry has Base set to NULL + DEBUGS(" strcmp('%s', '%s')", gLoadedLibraries[i].Name, file); + if(strcmp(gLoadedLibraries[i].Name, file) == 0) { + DEBUGS("IsFileLoaded: Found %i (0x%x)", i, gLoadedLibraries[i].Base); + return gLoadedLibraries[i].Base; + } + } + DEBUGS("IsFileLoaded: Not Found"); + return 0; +} + +/** + * \fn void AddLoaded(char *File, Uint base) + * \brief Add a file to the loaded list */ void AddLoaded(char *File, Uint base) -{ - int i, length; - char *name = gsNextAvailString; - - DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base); - - // Find a free slot - for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ ) - { - if(gLoadedLibraries[i].Base == 0) break; - } - if(i == MAX_LOADED_LIBRARIES) { - SysDebug("ERROR - ld-acess.so has run out of load slots!"); - return; - } - - // Check space in string buffer - length = strlen(File); - if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) { - SysDebug("ERROR - ld-acess.so has run out of string buffer memory!"); - return; - } - - // Set information - gLoadedLibraries[i].Base = base; - strcpy(name, File); - gLoadedLibraries[i].Name = name; - gsNextAvailString = &name[length+1]; - DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i); +{ + int i, length; + char *name = gsNextAvailString; + + DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base); + + // Find a free slot + for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ ) + { + if(gLoadedLibraries[i].Base == 0) break; + } + if(i == MAX_LOADED_LIBRARIES) { + SysDebug("ERROR - ld-acess.so has run out of load slots!"); + return; + } + + // Check space in string buffer + length = strlen(File); + if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) { + SysDebug("ERROR - ld-acess.so has run out of string buffer memory!"); + return; + } + + // Set information + gLoadedLibraries[i].Base = base; + strcpy(name, File); + gLoadedLibraries[i].Name = name; + gsNextAvailString = &name[length+1]; + DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i); return; -} - -/** - * \fn void Unload(Uint Base) - */ -void Unload(Uint Base) -{ - int i, j; - int id; - char *str; - for( id = 0; id < MAX_LOADED_LIBRARIES; id++ ) - { - if(gLoadedLibraries[id].Base == Base) break; - } - if(id == MAX_LOADED_LIBRARIES) return; - - // Unload Binary - SysUnloadBin( Base ); - // Save String Pointer - str = gLoadedLibraries[id].Name; - - // Compact Loaded List - j = id; - for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ ) - { - if(gLoadedLibraries[i].Base == 0) break; - // Compact String - strcpy(str, gLoadedLibraries[i].Name); - str += strlen(str)+1; - // Compact Entry - gLoadedLibraries[j].Base = gLoadedLibraries[i].Base; - gLoadedLibraries[j].Name = str; - } - - // NULL Last Entry - gLoadedLibraries[j].Base = 0; - gLoadedLibraries[j].Name = NULL; - // Save next string - gsNextAvailString = str; -} - +} + +/** + * \fn void Unload(Uint Base) + */ +void Unload(Uint Base) +{ + int i, j; + int id; + char *str; + for( id = 0; id < MAX_LOADED_LIBRARIES; id++ ) + { + if(gLoadedLibraries[id].Base == Base) break; + } + if(id == MAX_LOADED_LIBRARIES) return; + + // Unload Binary + SysUnloadBin( Base ); + // Save String Pointer + str = gLoadedLibraries[id].Name; + + // Compact Loaded List + j = id; + for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ ) + { + if(gLoadedLibraries[i].Base == 0) break; + // Compact String + strcpy(str, gLoadedLibraries[i].Name); + str += strlen(str)+1; + // Compact Entry + gLoadedLibraries[j].Base = gLoadedLibraries[i].Base; + gLoadedLibraries[j].Name = str; + } + + // NULL Last Entry + gLoadedLibraries[j].Base = 0; + gLoadedLibraries[j].Name = NULL; + // Save next string + gsNextAvailString = str; +} + /** \fn Uint GetSymbol(char *name) \brief Gets a symbol value from a loaded library */ Uint GetSymbol(char *name) -{ +{ int i; - Uint ret; - for(i=0;i - -// Strings -extern int strlen(const char *string); -extern int strcmp(const char *str1, const char *str2); -extern int strncmp(const char *str1, const char *str2, size_t len); -extern char *strcpy(char *dst, const char *src); -extern char *strncpy(char *dst, const char *src, size_t num); -extern char *strcat(char *dst, const char *src); -extern char *strdup(const char *src); -extern char *strchr(char *str, int character); -extern char *strrchr(char *str, int character); -extern char *strstr(char *str1, const char *str2); - -// Memory -extern void *memset(void *dest, int val, size_t count); -extern void *memcpy(void *dest, const void *src, size_t count); -extern void *memmove(void *dest, const void *src, size_t count); -extern int memcmp(const void *mem1, const void *mem2, size_t count); -extern void *memchr(void *ptr, int value, size_t num); - -#endif