X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fvm8086.c;h=46daeefd4a7ad23ae4fbaeeed3b98d9cd3bfeaf3;hb=c575e49ea4543b45ccd2a47d57ec590ca995e707;hp=a1c75e2394fb8826d06f34bf9c590430fe27897f;hpb=86f49ede5038704ac4f12eab9794e9a8110a4985;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/vm8086.c b/Kernel/arch/x86/vm8086.c index a1c75e23..46daeefd 100644 --- a/Kernel/arch/x86/vm8086.c +++ b/Kernel/arch/x86/vm8086.c @@ -2,9 +2,11 @@ * Acess2 VM8086 Driver * - By John Hodge (thePowersGang) */ +#define DEBUG 0 #include #include #include +#include // === CONSTANTS === #define VM8086_MAGIC_CS 0xFFFF @@ -24,8 +26,8 @@ enum eVM8086_Opcodes }; #define VM8086_PAGES_PER_INST 4 -// === IMPORTS === - int Proc_Clone(Uint *Err, Uint Flags); +#define VM8086_BLOCKSIZE 128 +#define VM8086_BLOCKCOUNT ((0x9F000-0x10000)/VM8086_BLOCKSIZE) // === TYPES === struct sVM8086_InternalData @@ -40,7 +42,7 @@ struct sVM8086_InternalData // === PROTOTYPES === int VM8086_Install(char **Arguments); void VM8086_GPF(tRegs *Regs); -tVM8086 *VM8086_Init(void); +//tVM8086 *VM8086_Init(void); // === GLOBALS === MODULE_DEFINE(0, 0x100, VM8086, VM8086_Install, NULL, NULL); @@ -48,6 +50,7 @@ tMutex glVM8086_Process; tPID gVM8086_WorkerPID; tTID gVM8086_CallingThread; tVM8086 volatile * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions +Uint32 gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32]; // === FUNCTIONS === int VM8086_Install(char **Arguments) @@ -58,7 +61,7 @@ int VM8086_Install(char **Arguments) Mutex_Acquire( &glVM8086_Process ); // Create BIOS Call process - pid = Proc_Clone(NULL, CLONE_VM); + pid = Proc_Clone(CLONE_VM); if(pid == -1) { Log_Error("VM8086", "Unable to clone kernel into VM8086 worker"); @@ -69,21 +72,34 @@ int VM8086_Install(char **Arguments) Uint * volatile stacksetup; // Initialising Stack Uint16 * volatile rmstack; // Real Mode Stack int i; - + // Set Image Name Threads_SetName("VM8086"); - + + Log_Debug("VM8086", "Mapping memory"); + // Map ROM Area for(i=0xA0;i<0x100;i++) { MM_Map( i * 0x1000, i * 0x1000 ); - //MM_SetFlags( i * 0x1000, MM_PFLAG_RO, MM_PFLAG_RO ); // Set Read Only } + Log_Debug("VM8086", "ROM area mapped"); MM_Map( 0, 0 ); // IVT / BDA - for(i=0x10;i<0x9F;i++) { - MM_Map( i * 0x1000, i * 0x1000 ); MM_DerefPhys( i * 0x1000 ); + // Map (but allow allocation) of 0x1000 - 0x9F000 + // - So much hack, it isn't funny + for(i=1;i<0x9F;i++) { + MM_Map( i * 0x1000, i * 0x1000 ); + MM_DerefPhys( i * 0x1000 ); // Above + while(MM_GetRefCount(i*0x1000)) + MM_DerefPhys( i * 0x1000 ); // Phys setup } MM_Map( 0x9F000, 0x9F000 ); // Stack / EBDA - MM_Allocate( 0x100000 ); // System Stack / Stub + // System Stack / Stub + if( MM_Allocate( 0x100000 ) == 0 ) { + Log_Error("VM8086", "Unable to allocate memory for stack/stub"); + gVM8086_WorkerPID = 0; + Threads_Exit(0, 1); + } + Log_Debug("VM8086", "Mapped low memory"); *(Uint8*)(0x100000) = VM8086_OP_IRET; *(Uint8*)(0x100001) = 0x07; // POP ES @@ -133,6 +149,11 @@ int VM8086_Install(char **Arguments) while( gpVM8086_State != NULL ) Threads_Yield(); // Yield to allow the child to initialise + // Worker killed itself + if( gVM8086_WorkerPID != pid ) { + return MODULE_ERR_MISC; + } + return MODULE_ERR_OK; } @@ -147,8 +168,8 @@ void VM8086_GPF(tRegs *Regs) { if( gpVM8086_State == (void*)-1 ) { Log_Log("VM8086", "Worker thread ready and waiting"); - Mutex_Release( &glVM8086_Process ); // Release lock obtained in VM8086_Install gpVM8086_State = NULL; + Mutex_Release( &glVM8086_Process ); // Release lock obtained in VM8086_Install } //Log_Log("VM8086", "gpVM8086_State = %p, gVM8086_CallingThread = %i", // gpVM8086_State, gVM8086_CallingThread); @@ -349,20 +370,20 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset) // Scan the bitmap for a free block for( j = 0; j < 32; j++ ) { if( State->Internal->AllocatedPages[i].Bitmap & (1 << j) ) { - base = j; + base = j+1; rem = nBlocks; } - else { - rem --; - if(rem == 0) // Goodie, there's a gap - { - for( j = 0; j < nBlocks; j++ ) - State->Internal->AllocatedPages[i].Bitmap |= 1 << (base + j); - *Segment = State->Internal->AllocatedPages[i].PhysAddr / 16 + base * 8; - *Offset = 0; - //Log_Debug("VM8086", "Allocated at #%i,%04x", i, base*128); - return (void*)( State->Internal->AllocatedPages[i].VirtBase + base * 128 ); - } + + rem --; + if(rem == 0) // Goodie, there's a gap + { + for( j = 0; j < nBlocks; j++ ) + State->Internal->AllocatedPages[i].Bitmap |= 1 << (base + j); + *Segment = State->Internal->AllocatedPages[i].PhysAddr / 16 + base * 8; + *Offset = 0; + LOG("Allocated at #%i,%04x", i, base*128); + LOG(" - %x:%x", *Segment, *Offset); + return (void*)( State->Internal->AllocatedPages[i].VirtBase + base * 128 ); } } } @@ -384,9 +405,10 @@ void *VM8086_Allocate(tVM8086 *State, int Size, Uint16 *Segment, Uint16 *Offset) for( j = 0; j < nBlocks; j++ ) State->Internal->AllocatedPages[i].Bitmap |= 1 << j; - //Log_Debug("VM8086", "AllocatedPages[%i].Bitmap = 0b%b", i, State->Internal->AllocatedPages[i].Bitmap); + LOG("AllocatedPages[%i].Bitmap = 0b%b", i, State->Internal->AllocatedPages[i].Bitmap); *Segment = State->Internal->AllocatedPages[i].PhysAddr / 16; *Offset = 0; + LOG(" - %x:%x", *Segment, *Offset); return (void*) State->Internal->AllocatedPages[i].VirtBase; } @@ -399,6 +421,8 @@ void VM8086_Int(tVM8086 *State, Uint8 Interrupt) { State->IP = *(Uint16*)(KERNEL_BASE+4*Interrupt); State->CS = *(Uint16*)(KERNEL_BASE+4*Interrupt+2); + +// Log_Debug("VM8086", "Software interrupt %i to %04x:%04x", Interrupt, State->CS, State->IP); Mutex_Acquire( &glVM8086_Process );