General Info | |
Interface: IntManager_i386 Files: intmanager_i386.h Last change: 29/06/2003 Author: Luiz Henrique Shigunov |
Description
Structures |
Functions | |
0x00 - Catch - Catch an interrupt 0x04 - CatchException - Catch an exception 0x01 - Free - Frees an interrupt |
0x05 - FreeException - Frees an exception 0x02 - NoInt - Disable all hardware interrupts 0x03 - RestoreInt - Restore hardware interrupts state |
This page describes the IntManager_i386 interface which provides functions to manage system interrupts, exceptions (they are interrupts too) and get informations about used interrupts.
Functions that handle interrupts are called interrupt service routine (ISR).
Software ISR run with interrupts enabled. So, if a hardware interrupt occurs while a software ISR is running, the hardware interrupt is serviced.
Hardware ISR run with interrupts disabled and they must return with interrupts disabled too.
Exception interrupts are handled as software ISR. Except exception number 14 (Page Fault) which is handled as an hardware ISR, that is, it is called with interrupts disabled. This is done because this exception needs to use data from a register which is not saved when a thread switch occurs.
Hardware ISR must always be in physical memory and can only access data that are in physical memory too.
That's because to implement virtual memory a disk is needed and to use disk, interrupts must be enabled.
Hardware ISR must be very careful calling modules functions, because they have these restriction too.
The best way to call functions that don't conform to these restrictions is to use a thread/task to call them. You just have to be careful with the following interrupts. If needed, disable the interrupt while handling it.
These restrictions don't apply to software interrupts.
Many ISRs can handle the same hardware interrupt. When an ISR is registered, you can say to put it in the beginning or in the end of the ISRs list. An ISR that realy handle the interrupt should be put in the end. But an ISR that make statistics should be put in the beginning.
Each hardware ISR is called passing a IntManager_i386_Regs structure. Changing a structure member value will change the register value when the interrupt returns.
Hardware ISRs must return:
Returning E_HANDLED_INT says that others ISRs in the list must not be called, but returning E_UNHANDLED_INT says to call them.
E_INVOKE_SCHEDULER is used, for instance, when a righ priority task is freed by the ISR (the task was waiting a semaphore, for instance). In this case, before the scheduler is called, the interrupt controller will be signaled that the interrupt was handled.
A hardware ISR syntax is:
int function_name(IntManager_i386_Regs *regs);
Software ISRs must save all registers before using them and restore them before returning with iret.
All interrupts that aren't used point to a standard ISR.
Exceptions and hardware interrupts have a privileged descriptor. Software interrupts can choose a privileged or not privileged one.
Many ISRs can handle the same exception and an ISR is chosen based on the address where the exception occured.
Each exception ISR is called passing a IntManager_i386_ExRegs structure. Changing a structure member value will change the register value when the exception returns.
Exception ISRs must return:
Returning E_HANDLED_INT says that others ISRs in the list must not be called, but returning E_UNHANDLED_INT says to call them.
So, an exception ISR syntax is:
int function_name(IntManager_i386_ExRegs *regs);
Exceptions can be of three types: fault, trap or abort.
A fault exception normally permits that the instruction that caused the fault be restarted. The return address points to the instruction that caused the fault.
A trap exception is signaled after the instruction that caused it has finished. The return address points to the instruction just after the one that caused the trap.
An abort exception doesn't say with precision where the error occured and normally execution can't continue. It's caused by hardware problems and errors in system tables.
Common exceptions:
typedef struct { unsigned int EBP; unsigned int ESI; unsigned int EDI; unsigned int EDX; unsigned int ECX; unsigned int EBX; unsigned int EAX; unsigned int EIP; unsigned int ErrorCode; unsigned int CS; unsigned int EFLAGS; unsigned int ESP; unsigned int SS; } IntManager_i386_ExRegs;
When an exception doesn't has error code, ErrorCode member is undefined.
ESP and SS only exist if the code privilege level was different than 0. So, be careful passing this structure to other functions - it can be smaller!
typedef struct { unsigned int EBP; unsigned int ESI; unsigned int EDI; unsigned int EDX; unsigned int ECX; unsigned int EBX; unsigned int EAX; unsigned int EIP; unsigned int CS; unsigned int EFLAGS; unsigned int ESP; unsigned int SS; } IntManager_i386_Regs;
ESP and SS only exist if the code privilege level was different than 0. So, be careful passing this structure to other functions - it can be smaller!
int IntManager_i386_Catch(SysModManager_Module *modID, unsigned int interrupt, int (*function)(IntManager_i386_Regs*), int prop);
This function registers that modID is using interrupt and binds this interrupt with function.
The thread that executes function may be destroyable. If this is a problem functions Undestroyable and Destroyable from the TaskManager interface must be used.
prop must be 0 or:
The descriptor privilege for software interrupts can be 0 or 3. If it's 0 only system modules can call them.
Exception and hardware interrupts if called by the processor are always executed. But if they are called by running code, through INT instruction, the processor checks the privilege level.
If interrupt is a hardware interrupt, interrupt controller module is called to enable the IRQ.
int IntManager_i386_CatchException(unsigned int exception, int (*function)(IntManager_i386_ExRegs*), void *start, void *end);
This function registers function to handle exception when it occurs between start-end, including.
The thread that executes function may be destroyable. If this is a problem functions Undestroyable and Destroyable from the TaskManager interface must be used.
Interrupts with number below 32 are exceptions.
int IntManager_i386_Free(SysModManager_Module *modID, unsigned int interrupt, int prop);
This function unregisters that modID is using interrupt.
prop must be 0 or:
If it's a hardware interrupt, interrupt controller module is called to disable the IRQ.
int IntManager_i386_FreeException(unsigned int exception, int (*function)(IntManager_i386_ExRegs*), void *start);
This function unregisters function to handle exception when it occurs in start.
Interrupts with number below 32 are exceptions.
int IntManager_i386_NoInt(void);
This function disables the hardware interrupts.
void IntManager_i386_RestoreInt(int flags);
This function restores the processor flags from flags.
Nothing.