Getting interrupt's number within it's handler
Getting interrupt's number within it's handler
Hi all ! Can I get a current interrupt's number within it's handler ? E.g. I've got the same handler for exceptions (this is just a test version but...) the only difference are the exceptions's numbers printed with this handler. So I wrote about 20 pretty the same handlers for this Is it possible to get this number somehow (e.g. from APIC or what else ?) and write the universal handler for all ints ? Thanks
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Getting interrupt's number within it's handler
no. We've been looking for something alike, but apparently there isn't such solution. What most of us do is to push the INT number on stack and then branch to a generic handler
(did i already mentionned your avatar is kewl ?)
(did i already mentionned your avatar is kewl ?)
Re:Getting interrupt's number within it's handler
The last time this came up I suggest that it was possible to read the return value from the stack and interpret the interrupt value from the calling instruction. I still think that's a perfectly valid way of doing it.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Getting interrupt's number within it's handler
Well, it will certainly be valid for guessing whether the user used "INT 0x30" or "INT 0x31", though i doubt it will actually be efficient. But it certainly won't work for hardware interrupts (which can occur with any instruction) nor for exceptions (the same mov eax,[eax] could raise a page fault or a segmentation fault)Curufir wrote: The last time this came up I suggest that it was possible to read the return value from the stack and interpret the interrupt value from the calling instruction. I still think that's a perfectly valid way of doing it.
Re:Getting interrupt's number within it's handler
Hi,
It'd make much more sense to do something like:
This lets you specify which interrupts get controlled by which default handlers, and they can be handled by special code instead if necessary. The EOI stuff for IRQs is only an example (it'd choke on PCI level triggered interrupts), and the whole idea of using 16 pre-defined IRQs only works with the PIC chips (IO APICs can be used for up to 224 IRQs where the interrupt number determines it's priority - they should be spread throughout the whole IDT).
Cheers,
Brendan
It'd make much more sense to do something like:
Code: Select all
int0x00:
push dword 0 ;Fake error code
push eax
mov eax,0x00
jmp default_exception_handler
int0x01:
push dword 0 ;Fake error code
push eax
mov eax,0x01
jmp default_exception_handler
<-Ints 0x02 to 0x0C skipped->
int0x0D:
<-handle_the_GPF->
iretd
int0x0E:
<-handle_the_PGF->
iretd
<-Ints 0x0F to 0x1F skipped->
int0x20:
<-handle_IRQ0->
iretd
int0x21:
push eax
mov eax,0x01
jmp IRQ_handler
int0x22:
push eax
mov eax,0x02
jmp IRQ_handler
<-Ints 0x23 to 0x27 skipped->
int0x28:
<-handle_IRQ8->
iretd
int0x29:
push eax
mov eax,0x09
jmp IRQ_handler
<-Ints 0x2A to 0x2F skipped->
default_exception_handler:
call critical_error_handler
pop eax
add esp,4
iretd
IRQ_handler:
<-handle the IRQ in EAX->
<-send EOI to master PIC->
cmp eax,0x07
jb .l1
<-send EOI to slave PIC->
.l1:
pop eax
iretd
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Getting interrupt's number within it's handler
Urgh.. I'd still go with the:
Code: Select all
irq<n>_handler:
pushl $<n>
jmp generic_irq_handler
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Getting interrupt's number within it's handler
Code: Select all
%macro exc_noerrcode 1
handler_exc_%1:
push 0 ;; fake errcode
push %1
jmp generic_exc_handler
%endmacro
%macro exc_errcode 1
handler_exc_%1:
push %1
jmp generic_exc_handler
%endmacro
%macro irq 1
handler_irq_%1
push %1
jmp generic_irq_handler
%endmacro
[quote][/quote]
for me ...
Re:Getting interrupt's number within it's handler
You CAN do so for software interrupts.
And then make a C function:
that pretty much does whatever you like it to do.
Note, all untested as usual. If it makes your computer dance around the room, don't blame me.
Code: Select all
interrupt_asm:
; push the registers that will be used as arguments for this call
push eax
push ebx
push ecx
push edx
mov eax, [esp+4]
xor ebx, ebx
mov bl, byte [eax-1]
push ebx
call interrupt_c
pop eax
pop edx
pop ecx
pop ebx
pop eax
iret
Code: Select all
void interrupt_c(int called_interrupt_num, int edx, int ecx, int ebx, int eax) {
}
Note, all untested as usual. If it makes your computer dance around the room, don't blame me.
Re:Getting interrupt's number within it's handler
Hi,
That's be great for performance ;D.
Cheers,
Brendan
Looks good. The next logical step would be:Candy wrote:You CAN do so for software interrupts.
Code: Select all
void interrupt_c(int called_interrupt_num, int edx, int ecx, int ebx, int eax) {
switch(called_interrupt_num) {
case 0x80:
call interrupt_0x80(edx, ecx, ebx, eax);
break;
case 0x81:
call interrupt_0x81(edx, ecx, ebx, eax);
break;
}
}
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Getting interrupt's number within it's handler
Well... that idea has been abandoned by most years ago already. Try this one:Brendan wrote: Hi,
Looks good. The next logical step would be:
That's be great for performance ;D.Code: Select all
void interrupt_c(int called_interrupt_num, int edx, int ecx, int ebx, int eax) { switch(called_interrupt_num) { case 0x80: call interrupt_0x80(edx, ecx, ebx, eax); break; case 0x81: call interrupt_0x81(edx, ecx, ebx, eax); break; } }
Code: Select all
typedef void (*syscall_function)(int, int, int, int);
syscall_function[256] = { NULL, NULL, NULL ... NULL, func_30, func_31, func_32...func_fe, func_ff };
void interrupt(int syscall_id, int eax, int ebx, int ecx, int edx) {
call syscall_function[syscall_id](eax, ebx, ecx, edx);
}
Re:Getting interrupt's number within it's handler
Hi,
The code you posted is a good example - it ends up calling func_30, func_31, etc depending on the software interrupt used, so for performance reasons why not call them directly without the extra overhead?
The only reason I can think of is C's inability to generate interrupt handlers combined with lazy programming (not feeling like writing multiple assembly stubs).
Cheers,
Brendan
The point I was trying to make (albeit far too subtly) is that software interrupts end up being used for one or more specific functions, and that it would be silly to use any form of generic software interrupt handler.Candy wrote:Well... that idea has been abandoned by most years ago already. Try this one:
The code you posted is a good example - it ends up calling func_30, func_31, etc depending on the software interrupt used, so for performance reasons why not call them directly without the extra overhead?
The only reason I can think of is C's inability to generate interrupt handlers combined with lazy programming (not feeling like writing multiple assembly stubs).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Getting interrupt's number within it's handler
I agree. I've never really understood why most OS try to multiplex a single interrupt for all the system calls (Eg Linux int 80h).
On x86 you have over 150 interrupts at your disposal. Since the number of system calls is usually pretty limited why not use the encoding of the interrupt instruction to contain useful data. In other words use a different software interrupt for each system call.
The other methods seem pretty wasteful, and inefficient (Losing a register, looking up address in memory, storing function table in memory etc) compared to using the system call directly.
I guess at some point it made total sense to someone, but I can't see a good reason for it.
On x86 you have over 150 interrupts at your disposal. Since the number of system calls is usually pretty limited why not use the encoding of the interrupt instruction to contain useful data. In other words use a different software interrupt for each system call.
The other methods seem pretty wasteful, and inefficient (Losing a register, looking up address in memory, storing function table in memory etc) compared to using the system call directly.
I guess at some point it made total sense to someone, but I can't see a good reason for it.
Re:Getting interrupt's number within it's handler
I would imagine the best explanation as being longevity, sure you have 150 spare interrupts, but what happens if a new PC model comes out that requires additional IRQ interrupts or if you reach 151 system calls? "Professional" OS' (term used loosely) tend to leave wide spaces open for extending in future. On Windows for example, quite a few structs start with a size field which assumeably allows version control based on the amount of data in the struct.
You could also say it's simple and allows easy behind the scenes replacement with SYSENTER/SYSCALL.
You could also say it's simple and allows easy behind the scenes replacement with SYSENTER/SYSCALL.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re:Getting interrupt's number within it's handler
I think it may have something to do with porting to other architectures, where there may only be one "syscall" instruction. In such a case you have to dispatch through a table lookup anyway...
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Re:Getting interrupt's number within it's handler
I'm guessing the you would be able to get the interrupt's number from the PIC or the APIC.