From 814b2d0009da73b56c6def5d70a9dd97c7b17e2e Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 23 Apr 2010 19:53:02 +0800 Subject: [PATCH] Fixes to VM8086 handler to remove operand size errors. --- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/Makefile | 2 +- Kernel/arch/x86/desctab.asm | 38 +---------- Kernel/arch/x86/kpanic.c | 4 +- Kernel/arch/x86/mm_virt.c | 2 +- Kernel/arch/x86/proc.c | 14 ++++ Kernel/arch/x86/start.asm | 25 ------- Kernel/arch/x86/vm8086.c | 57 ++++++++++++---- Kernel/include/syscalls.h | 4 +- Kernel/include/syscalls.inc.asm | 2 +- Kernel/include/threads.h | 11 ++- Kernel/syscalls.c | 6 ++ Kernel/syscalls.lst | 2 +- Kernel/threads.c | 74 +++++++++------------ Modules/Display/VESA/main.c | 18 +++-- Usermode/Libraries/libacess.so_src/core.asm | 2 +- Usermode/Libraries/libc.so_src/stub.c | 9 +++ Usermode/include/sys/sys.h | 2 + 18 files changed, 141 insertions(+), 133 deletions(-) diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 620c1bbd..ce0a54c7 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1982 +BUILD_NUM = 2027 diff --git a/Kernel/arch/x86/Makefile b/Kernel/arch/x86/Makefile index c52e369b..0c442882 100644 --- a/Kernel/arch/x86/Makefile +++ b/Kernel/arch/x86/Makefile @@ -31,5 +31,5 @@ endif A_OBJ = start.ao main.o lib.o desctab.ao errors.o irq.o A_OBJ += mm_phys.o mm_virt.o -A_OBJ += proc.o time.o vm8086.o +A_OBJ += proc.o proc.ao time.o vm8086.o A_OBJ += kpanic.o diff --git a/Kernel/arch/x86/desctab.asm b/Kernel/arch/x86/desctab.asm index 43bd8e4c..27b7bb1a 100644 --- a/Kernel/arch/x86/desctab.asm +++ b/Kernel/arch/x86/desctab.asm @@ -190,6 +190,7 @@ DEF_SYSCALL 0xAC ; Acess System Call ; IRQs ; - Timer [global Isr240] +[extern SchedulerBase] Isr240: push 0 jmp SchedulerBase @@ -281,40 +282,3 @@ IRQCommon: popa add esp, 8 ; Error Code and ID iret - -; -------------- -; Task Scheduler -; -------------- -[extern Proc_Scheduler] -SchedulerBase: - pusha - push ds - push es - push fs - push gs - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - mov eax, [esp+12*4] ; CPU Number - push eax ; Pus as argument - - call Proc_Scheduler - - add esp, 4 ; Remove Argument - - pop gs - pop fs - pop es - pop ds - - mov dx, 0x20 - mov al, 0x20 - out dx, al ; ACK IRQ - popa - add esp, 4 ; CPU ID - ; No Error code / int num - iret diff --git a/Kernel/arch/x86/kpanic.c b/Kernel/arch/x86/kpanic.c index 1972fd3b..798c5139 100644 --- a/Kernel/arch/x86/kpanic.c +++ b/Kernel/arch/x86/kpanic.c @@ -59,7 +59,9 @@ void KernelPanic_SetMode() { int i; - // Some routines call this function twice, let's avoid that, shall we? + // This function is called by Panic(), but MM_PageFault and the + // CPU exception handers also call it, so let's not clear the screen + // twice if( giKP_Pos ) return ; // Restore VGA 0xB8000 text mode diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index db89cc14..f2be750f 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -1013,7 +1013,7 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number) for( j = 0; j < Number; j++ ) { - MM_DerefPhys( gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] ); + MM_DerefPhys( gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] & ~0xFFF ); gaPageTable[ (HW_MAP_ADDR >> 12) + i + j ] = 0; } diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 62980674..e9884161 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -39,6 +39,7 @@ extern tThread *Threads_GetNextToRun(int CPU); extern void Threads_Dump(); extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags); extern void Isr8(); // Double Fault +extern void Proc_AlterUserReturnAddr(); // === PROTOTYPES === void ArchThreads_Init(); @@ -51,6 +52,7 @@ 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 === @@ -693,6 +695,18 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) 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, %%ebp;\n\tcall Proc_AlterUserReturnAddr" :: "r"(Thread->FaultHandler)); + for(;;); +} + /** * \fn void Proc_Scheduler(int CPU) * \brief Swap current thread and clears dead threads diff --git a/Kernel/arch/x86/start.asm b/Kernel/arch/x86/start.asm index d9a1e500..b98a0165 100644 --- a/Kernel/arch/x86/start.asm +++ b/Kernel/arch/x86/start.asm @@ -168,31 +168,6 @@ CallWithArgArray: pop ebp ret -[extern Proc_Clone] -[extern Threads_Exit] -[global SpawnTask] -SpawnTask: - ; Call Proc_Clone with Flags=0 - xor eax, eax - push eax - push eax - call Proc_Clone - add esp, 8 ; Remove arguments from stack - - test eax, eax - jnz .parent - - ; In child, so now set up stack frame - mov ebx, [esp+4] ; Child Function - mov edx, [esp+8] ; Argument - ; Child - push edx ; Argument - call ebx ; Function - call Threads_Exit ; Kill Thread - -.parent: - ret - [section .initpd] [global gaInitPageDir] [global gaInitPageTable] diff --git a/Kernel/arch/x86/vm8086.c b/Kernel/arch/x86/vm8086.c index 8ef7453e..1816eacf 100644 --- a/Kernel/arch/x86/vm8086.c +++ b/Kernel/arch/x86/vm8086.c @@ -13,12 +13,14 @@ #define VM8086_STACK_OFS 0x0AFE enum eVM8086_Opcodes { - VM8086_OP_PUSHF = 0x9C, - VM8086_OP_POPF = 0x9D, - VM8086_OP_INT_I = 0xCD, - VM8086_OP_IRET = 0xCF, - VM8086_OP_IN_AD = 0xEC, - VM8086_OP_IN_ADX= 0xED + VM8086_OP_PUSHF = 0x9C, + VM8086_OP_POPF = 0x9D, + VM8086_OP_INT_I = 0xCD, + VM8086_OP_IRET = 0xCF, + VM8086_OP_IN_AD = 0xEC, + VM8086_OP_IN_ADX = 0xED, + VM8086_OP_OUT_AD = 0xEE, + VM8086_OP_OUT_ADX = 0xEF }; #define VM8086_PAGES_PER_INST 4 @@ -45,13 +47,16 @@ MODULE_DEFINE(0, 0x100, VM8086, VM8086_Install, NULL, NULL); tSpinlock glVM8086_Process; tPID gVM8086_WorkerPID; tTID gVM8086_CallingThread; -tVM8086 * volatile gpVM8086_State; +tVM8086 * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions // === FUNCTIONS === int VM8086_Install(char **Arguments) { tPID pid; + // Lock to avoid race conditions + LOCK( &glVM8086_Process ); + // Create BIOS Call process pid = Proc_Clone(NULL, CLONE_VM); if(pid == -1) @@ -139,6 +144,11 @@ void VM8086_GPF(tRegs *Regs) if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS && Threads_GetPID() == gVM8086_WorkerPID) { + if( gpVM8086_State == (void*)-1 ) { + Log_Log("VM8086", "Worker thread ready and waiting"); + RELEASE( &glVM8086_Process ); // Release lock obtained in VM8086_Install + gpVM8086_State = NULL; + } if( gpVM8086_State ) { gpVM8086_State->AX = Regs->eax; gpVM8086_State->CX = Regs->ecx; gpVM8086_State->DX = Regs->edx; gpVM8086_State->BX = Regs->ebx; @@ -176,7 +186,7 @@ void VM8086_GPF(tRegs *Regs) return ; } - opcode = *(Uint8*)( KERNEL_BASE + (Regs->cs*16) + (Regs->eip) ); + opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip) ); Regs->eip ++; switch(opcode) { @@ -237,13 +247,13 @@ void VM8086_GPF(tRegs *Regs) #endif break; - case 0xEE: //OUT DX, AL + case VM8086_OP_OUT_AD: //OUT DX, AL outb(Regs->edx&0xFFFF, Regs->eax&0xFF); #if TRACE_EMU Log_Debug("VM8086", "Emulated OUT DX, AL (*0x%04x = 0x%02x)\n", Regs->edx&0xFFFF, Regs->eax&0xFF); #endif break; - case 0xEF: //OUT DX, AX + case VM8086_OP_OUT_ADX: //OUT DX, AX outw(Regs->edx&0xFFFF, Regs->eax&0xFFFF); #if TRACE_EMU Log_Debug("VM8086", "Emulated OUT DX, AX (*0x%04x = 0x%04x)\n", Regs->edx&0xFFFF, Regs->eax&0xFFFF); @@ -257,8 +267,31 @@ void VM8086_GPF(tRegs *Regs) break; case 0x66: - Log_Warning("VM8086", "Code at %04x:%04x attempted to use an operand override, ignored", - Regs->cs, Regs->eip); + opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip&0xFFFF)); + switch( opcode ) + { + case VM8086_OP_IN_ADX: //IN AX, DX + Regs->eax = ind(Regs->edx&0xFFFF); + #if TRACE_EMU + Log_Debug("VM8086", "Emulated IN EAX, DX (Port 0x%x)\n", Regs->edx&0xFFFF); + #endif + break; + case VM8086_OP_OUT_ADX: //OUT DX, AX + outd(Regs->edx&0xFFFF, Regs->eax); + #if TRACE_EMU + Log_Debug("VM8086", "Emulated OUT DX, EAX (*0x%04x = 0x%08x)\n", Regs->edx&0xFFFF, Regs->eax); + #endif + break; + default: + Log_Error("VM8086", "Error - Unknown opcode 66 %02x caused a GPF at %04x:%04x", + Regs->cs, Regs->eip, + opcode + ); + // Force an end to the call + Regs->cs = VM8086_MAGIC_CS; + Regs->eip = VM8086_MAGIC_IP; + break; + } break; default: diff --git a/Kernel/include/syscalls.h b/Kernel/include/syscalls.h index fb9a2ff6..0007dc1c 100644 --- a/Kernel/include/syscalls.h +++ b/Kernel/include/syscalls.h @@ -9,7 +9,7 @@ enum eSyscalls { SYS_EXIT, // 0 - Kill this thread SYS_CLONE, // 1 - Create a new thread SYS_KILL, // 2 - Send a signal - SYS_SIGNAL, // 3 - Set signal Handler + SYS_SETFAULTHANDLER, // 3 - Set signal Handler SYS_YIELD, // 4 - Yield remainder of timestamp SYS_SLEEP, // 5 - Sleep until messaged or signaled SYS_WAIT, // 6 - Wait for a time or a message @@ -63,7 +63,7 @@ enum eSyscalls { }; static const char *cSYSCALL_NAMES[] = { - "SYS_EXIT","SYS_CLONE","SYS_KILL","SYS_SIGNAL","SYS_YIELD","SYS_SLEEP", + "SYS_EXIT","SYS_CLONE","SYS_KILL","SYS_SETFAULTHANDLER","SYS_YIELD","SYS_SLEEP", "SYS_WAIT","SYS_WAITTID","SYS_SETNAME","SYS_GETNAME","SYS_GETTID","SYS_GETPID", "SYS_SETPRI","SYS_SENDMSG","SYS_GETMSG","SYS_GETTIME","SYS_SPAWN","SYS_EXECVE", "SYS_LOADBIN","SYS_UNLOADBIN","SYS_LOADMOD","","","", diff --git a/Kernel/include/syscalls.inc.asm b/Kernel/include/syscalls.inc.asm index a379deb1..bd59af83 100644 --- a/Kernel/include/syscalls.inc.asm +++ b/Kernel/include/syscalls.inc.asm @@ -5,7 +5,7 @@ %define SYS_EXIT 0 ; Kill this thread %define SYS_CLONE 1 ; Create a new thread %define SYS_KILL 2 ; Send a signal -%define SYS_SIGNAL 3 ; Set signal Handler +%define SYS_SETFAULTHANDLER 3 ; Set signal Handler %define SYS_YIELD 4 ; Yield remainder of timestamp %define SYS_SLEEP 5 ; Sleep until messaged or signaled %define SYS_WAIT 6 ; Wait for a time or a message diff --git a/Kernel/include/threads.h b/Kernel/include/threads.h index b55fe0e0..28d669d2 100644 --- a/Kernel/include/threads.h +++ b/Kernel/include/threads.h @@ -17,11 +17,13 @@ typedef struct sMessage typedef struct sThread { // --- threads.c's + // 0 struct sThread *Next; //!< Next thread in list tSpinlock IsLocked; //!< Thread's spinlock volatile int Status; //!< Thread Status int RetStatus; //!< Return Status + // 16 Uint TID; //!< Thread ID Uint TGID; //!< Thread Group (Process) Uint PTID; //!< Parent Thread ID @@ -29,19 +31,22 @@ typedef struct sThread char *ThreadName; //!< Name of thread // --- arch/proc.c's responsibility + // 40 //! Kernel Stack Base tVAddr KernelStack; + // 44 (x86) //! Memory Manager State tMemoryState MemState; + // 48 (x86) //! State on task switch tTaskState SavedState; // --- threads.c's - int CurSignal; //!< Signal currently being handled (0 for none) - tVAddr SignalHandlers[NSIG]; //!< Signal Handler List - tTaskState SignalState; //!< Saved state for signal handler + // 60 + int CurFaultNum; //!< Current fault number, 0: none + tVAddr FaultHandler; //!< Fault Handler tMsg * volatile Messages; //!< Message Queue tMsg *LastMessage; //!< Last Message (speeds up insertion) diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index 34567976..b49b4d6c 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -32,6 +32,7 @@ extern tUID Threads_GetUID(); extern int Threads_SetUID(Uint *errno, tUID ID); extern tGID Threads_GetGID(); extern int Threads_SetGID(Uint *errno, tGID ID); +extern int Threads_SetFaultHandler(Uint Handler); // === PROTOTYPES === int Syscall_ValidString(Uint Addr); @@ -60,6 +61,11 @@ void SyscallHandler(tSyscallRegs *Regs) // -- Yield current timeslice case SYS_YIELD: Threads_Yield(); break; + // -- Set Error Handler + case SYS_SETFAULTHANDLER: + Threads_SetFaultHandler(Regs->Arg1); + break; + // -- Clone the current thread case SYS_CLONE: // Call clone system call diff --git a/Kernel/syscalls.lst b/Kernel/syscalls.lst index c5978bea..dde278cd 100644 --- a/Kernel/syscalls.lst +++ b/Kernel/syscalls.lst @@ -3,7 +3,7 @@ SYS_EXIT Kill this thread SYS_CLONE Create a new thread SYS_KILL Send a signal -SYS_SIGNAL Set signal Handler +SYS_SETFAULTHANDLER Set signal Handler SYS_YIELD Yield remainder of timestamp SYS_SLEEP Sleep until messaged or signaled SYS_WAIT Wait for a time or a message diff --git a/Kernel/threads.c b/Kernel/threads.c index 96a38dac..f726f275 100644 --- a/Kernel/threads.c +++ b/Kernel/threads.c @@ -22,6 +22,7 @@ extern void ArchThreads_Init(); extern void Proc_Start(); extern tThread *Proc_GetCurThread(); extern int Proc_Clone(Uint *Err, Uint Flags); +extern void Proc_CallFaultHandler(tThread *Thread); // === PROTOTYPES === void Threads_Init(); @@ -62,7 +63,7 @@ tThread gThreadZero = { {0}, // Saved State {0}, // VM State - 0, {0}, {0}, // Signal State + 0, 0, // Current Fault, Fault Handler NULL, NULL, // Messages, Last Message DEFAULT_QUANTUM, DEFAULT_QUANTUM, // Quantum, Remaining @@ -201,12 +202,8 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags) new->NumTickets = cur->NumTickets; // Set Signal Handlers - new->CurSignal = 0; - if(Flags & CLONE_VM) - memset(new->SignalHandlers, 0, sizeof(new->SignalHandlers)); - else - memcpy(new->SignalHandlers, cur->SignalHandlers, sizeof(new->SignalHandlers)); - memset(&new->SignalState, 0, sizeof(tTaskState)); + new->CurFaultNum = 0; + new->FaultHandler = cur->FaultHandler; for( i = 0; i < NUM_CFG_ENTRIES; i ++ ) { @@ -566,57 +563,50 @@ void Threads_AddActive(tThread *Thread) RELEASE( &giThreadListLock ); } -#if 0 /** - * \fn void Threads_SetSignalHandler(int Num, void *Handler) + * \fn void Threads_SetSignalHandler(Uint Handler) * \brief Sets the signal handler for a signal */ -void Threads_SetSignalHandler(int Num, void *Handler) -{ - if(Num < 0 || Num >= NSIG) return; - - gCurrentThread->SignalHandlers[Num] = Handler; +void Threads_SetFaultHandler(Uint Handler) +{ + Log_Log("Threads", "Threads_SetFaultHandler: Handler = %p", Handler); + Proc_GetCurThread()->FaultHandler = Handler; } /** - * \fn void Threads_SendSignal(int TID, int Num) - * \brief Send a signal to a thread + * \fn void Threads_Fault(int Num) + * \brief Calls a fault handler */ -void Threads_SendSignal(int TID, int Num) +void Threads_Fault(int Num) { - tThread *thread = Proc_GetThread(TID); - void *handler; + tThread *thread = Proc_GetCurThread(); + + Log_Log("Threads", "Threads_Fault: thread = %p", thread); if(!thread) return ; - handler = thread->SignalHandlers[Num]; + Log_Log("Threads", "Threads_Fault: thread->FaultHandler = %p", thread->FaultHandler); - // Panic? - if(handler == SIG_ERR) { - Proc_Kill(TID); + switch(thread->FaultHandler) + { + case 0: // Panic? + Threads_Kill(thread, -1); + HALT(); return ; - } - // Dump Core? - if(handler == -2) { - Proc_Kill(TID); + case 1: // Dump Core? + Threads_Kill(thread, -1); + HALT(); return ; } - // Ignore? - if(handler == -2) return; - - // Check the type and handle if the thread is already in a signal - if(thread->CurSignal != 0) { - if(Num < _SIGTYPE_FATAL) - Proc_Kill(TID); - } else { - while(thread->CurSignal != 0) - Proc_Yield(); - } + + // Double Fault? Oh, F**k + if(thread->CurFaultNum != 0) { + Threads_Kill(thread, -1); // For now, just kill + HALT(); } - //TODO: + Proc_CallFaultHandler(thread); } -#endif // --- Process Structure Access Functions --- tPID Threads_GetPID() @@ -747,9 +737,9 @@ tThread *Threads_GetNextToRun(int CPU) */ void Threads_SegFault(tVAddr Addr) { - //Threads_SendSignal( Proc_GetCurThread()->TID, SIGSEGV ); Warning("Thread #%i committed a segfault at address %p", Proc_GetCurThread()->TID, Addr); - Threads_Exit( 0, -1 ); + Threads_Fault( 1 ); + //Threads_Exit( 0, -1 ); } // === EXPORTS === diff --git a/Modules/Display/VESA/main.c b/Modules/Display/VESA/main.c index e625c577..c2217e4c 100644 --- a/Modules/Display/VESA/main.c +++ b/Modules/Display/VESA/main.c @@ -68,7 +68,7 @@ int Vesa_Install(char **Arguments) // Call Interrupt VM8086_Int(gpVesa_BiosState, 0x10); if(gpVesa_BiosState->AX != 0x004F) { - Log_Warning("VESA", "Vesa_Install - VESA/VBE Unsupported (AX = 0x%x)\n", gpVesa_BiosState->AX); + Log_Warning("VESA", "Vesa_Install - VESA/VBE Unsupported (AX = 0x%x)", gpVesa_BiosState->AX); return MODULE_ERR_NOTNEEDED; } @@ -211,7 +211,8 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) { tVT_Char *chars = Buffer; int pitch = gVesa_Modes[giVesaCurrentMode].width; - int widthInChars; + int widthInChars = gVesa_Modes[giVesaCurrentMode].width/giVT_CharWidth; + int heightInChars = gVesa_Modes[giVesaCurrentMode].height/giVT_CharHeight; int x, y; Uint32 *dest = (void*)gpVesa_Framebuffer; int i; @@ -220,7 +221,6 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) Offset /= sizeof(tVT_Char); LOG("gVesa_Modes[%i].width = %i", giVesaCurrentMode, gVesa_Modes[giVesaCurrentMode].width); - widthInChars = gVesa_Modes[giVesaCurrentMode].width/giVT_CharWidth; x = Offset % widthInChars; y = Offset / widthInChars; LOG("(x,y) = (%i,%i) = [%i,%i]", x, y, x * giVT_CharWidth, y * giVT_CharHeight * pitch); @@ -232,11 +232,16 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) ); // Sanity Check - if(y > gVesa_Modes[giVesaCurrentMode].height/giVT_CharHeight) { + if(y > heightInChars) { LEAVE('i', 0); return 0; } + if( Offset + Length > heightInChars*widthInChars ) { + Length = heightInChars*widthInChars - Offset; + Log_Notice("VESA", "Clipping write size to %i characters", (int)Length); + } + dest += y * giVT_CharHeight * pitch; dest += x * giVT_CharWidth; @@ -251,7 +256,6 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) VT_Colour12to24(chars->FGCol) ); - chars ++; x ++; if( x >= widthInChars ) { @@ -301,6 +305,7 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data) { int ret; + //Log_Debug("VESA", "Vesa_Ioctl: (Node=%p, ID=%i, Data=%p)", Node, ID, Data); switch(ID) { case DRV_IOCTL_TYPE: return DRV_TYPE_VIDEO; @@ -324,6 +329,9 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data) } return ret; + case VIDEO_IOCTL_SETCURSOR: // Set cursor position + return 0; + case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer return 0; } diff --git a/Usermode/Libraries/libacess.so_src/core.asm b/Usermode/Libraries/libacess.so_src/core.asm index ef5b1233..e097d8c5 100644 --- a/Usermode/Libraries/libacess.so_src/core.asm +++ b/Usermode/Libraries/libacess.so_src/core.asm @@ -18,7 +18,6 @@ SoMain: SYSCALL1 _exit, SYS_EXIT SYSCALL2 clone, SYS_CLONE SYSCALL2 kill, SYS_KILL -SYSCALL2 signal, SYS_SIGNAL SYSCALL0 yield, SYS_YIELD SYSCALL0 sleep, SYS_SLEEP SYSCALL1 wait, SYS_WAIT @@ -44,5 +43,6 @@ SYSCALL3 SysSpawn, SYS_SPAWN SYSCALL3 execve, SYS_EXECVE SYSCALL2 SysLoadBin, SYS_LOADBIN +SYSCALL1 _SysSetFaultHandler, SYS_SETFAULTHANDLER SYSCALL6 _SysDebug, 0x100 diff --git a/Usermode/Libraries/libc.so_src/stub.c b/Usermode/Libraries/libc.so_src/stub.c index 9f629ba4..55f4ca66 100644 --- a/Usermode/Libraries/libc.so_src/stub.c +++ b/Usermode/Libraries/libc.so_src/stub.c @@ -3,6 +3,8 @@ */ #include "stdio_int.h" #include "lib.h" +#include +#include #define USE_CPUID 0 @@ -10,6 +12,7 @@ #if USE_CPUID static void cpuid(uint32_t Num, uint32_t *EAX, uint32_t *EBX, uint32_t *EDX, uint32_t *ECX); #endif +void ErrorHandler(int Fault); // === GLOBALS === extern char **_envp; @@ -53,9 +56,15 @@ int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp) } #endif + _SysSetFaultHandler(ErrorHandler); + return 1; } +void ErrorHandler(int Fault) +{ + fprintf(stderr, "Fault = %i\n", Fault); +} #if USE_CPUID /** diff --git a/Usermode/include/sys/sys.h b/Usermode/include/sys/sys.h index 7ddf5832..105d5737 100644 --- a/Usermode/include/sys/sys.h +++ b/Usermode/include/sys/sys.h @@ -36,3 +36,5 @@ extern int getpid(); // Get Process ID extern int sendmsg(int dest, unsigned int *Data); extern int pollmsg(int *src, unsigned int *Data); extern int getmsg(int *src, unsigned int *Data); + +extern int _SysSetFaultHandler(void (*Handler)(int)); -- 2.20.1