X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fvm8086.c;h=7181351002efccfbab540eb7e9dbb6218789a277;hb=3764c294f21229bdf700f436fa4884f5e76e0d3a;hp=86f440d17c6390b4a2ddd5e3807f06945ba5c0cc;hpb=2d83a99f3202f0e4688b58405f67604a24420861;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/vm8086.c b/Kernel/arch/x86/vm8086.c index 86f440d1..71813510 100644 --- a/Kernel/arch/x86/vm8086.c +++ b/Kernel/arch/x86/vm8086.c @@ -40,11 +40,11 @@ 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); -tSpinlock glVM8086_Process; +tMutex glVM8086_Process; tPID gVM8086_WorkerPID; tTID gVM8086_CallingThread; tVM8086 volatile * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions @@ -55,7 +55,7 @@ int VM8086_Install(char **Arguments) tPID pid; // Lock to avoid race conditions - LOCK( &glVM8086_Process ); + Mutex_Acquire( &glVM8086_Process ); // Create BIOS Call process pid = Proc_Clone(NULL, CLONE_VM); @@ -83,7 +83,12 @@ int VM8086_Install(char **Arguments) MM_Map( i * 0x1000, i * 0x1000 ); MM_DerefPhys( i * 0x1000 ); } 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); + } *(Uint8*)(0x100000) = VM8086_OP_IRET; *(Uint8*)(0x100001) = 0x07; // POP ES @@ -133,6 +138,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,7 +157,7 @@ void VM8086_GPF(tRegs *Regs) { if( gpVM8086_State == (void*)-1 ) { Log_Log("VM8086", "Worker thread ready and waiting"); - RELEASE( &glVM8086_Process ); // Release lock obtained in VM8086_Install + Mutex_Release( &glVM8086_Process ); // Release lock obtained in VM8086_Install gpVM8086_State = NULL; } //Log_Log("VM8086", "gpVM8086_State = %p, gVM8086_CallingThread = %i", @@ -159,9 +169,8 @@ void VM8086_GPF(tRegs *Regs) gpVM8086_State->SI = Regs->esi; gpVM8086_State->DI = Regs->edi; gpVM8086_State->DS = Regs->ds; gpVM8086_State->ES = Regs->es; gpVM8086_State = NULL; - // Ensure the caller wakes - //while(Threads_WakeTID(gVM8086_CallingThread) == -EALREADY) - // Threads_Yield(); + // Wake the caller + Threads_WakeTID(gVM8086_CallingThread); } //Log_Log("VM8086", "Waiting for something to do"); @@ -401,13 +410,13 @@ void VM8086_Int(tVM8086 *State, Uint8 Interrupt) State->IP = *(Uint16*)(KERNEL_BASE+4*Interrupt); State->CS = *(Uint16*)(KERNEL_BASE+4*Interrupt+2); - LOCK( &glVM8086_Process ); + Mutex_Acquire( &glVM8086_Process ); gpVM8086_State = State; gVM8086_CallingThread = Threads_GetTID(); Threads_WakeTID( gVM8086_WorkerPID ); - while( gpVM8086_State != NULL ) - Threads_Yield(); + Threads_Sleep(); + while( gpVM8086_State != NULL ) Threads_Sleep(); - RELEASE( &glVM8086_Process ); + Mutex_Release( &glVM8086_Process ); }