ASM source:
Code: Select all
.global isr0
#...
.global isr31
.type isr0, @function
isr0:
cli
push $0
push $0
jmp isr_common_stub
#...
.type isr31, @function
isr31:
cli
push $0
push $31
jmp isr_common_stub
#extern fault_handler
isr_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movl %esp, %eax
push %eax
call fault_handler
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret
.global irq0
#...
.global irq15
.type irq0, @function
irq0:
cli
push $0
push $32
jmp irq_common_stub
#...
.type irq15, @function
irq15:
cli
push $0
push $47
jmp irq_common_stub
irq_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movl %esp, %eax
push %eax
call irq_handler
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
call debug_donehandling
iret
Code: Select all
void irq_handler(struct regs *r)
{
if(r->int_no == 32)
{
printf("-h: timer!\n");
}
/* This is a blank function pointer */
void (*handler)(struct regs *r);
/* Find out if we have a custom handler to run for this
* IRQ, and then finally, run it */
handler = irq_routines[r->int_no - 32];
if (handler)
{
printf("-h: handler!\n");
handler(r);
}
/* If the IDT entry that was invoked was greater than 40
* (meaning IRQ8 - 15), then we need to send an EOI to
* the slave controller */
if (r->int_no >= 40)
{
printf("-h: EOI Slave!\n");
outportb(0xA0, 0x20);
}
/* In either case, we need to send an EOI to the master
* interrupt controller too */
printf("-h: EOI Master!\n");
outportb(0x20, 0x20);
}
void fault_handler(struct regs *r)
{
//printf("fault handler activated");
/* Is this a fault whose number is from 0 to 31? */
if (r->int_no < 32)
{
/* Display the description for the Exception that occurred.
* In this tutorial, we will simply halt the system using an
* infinite loop */
printf(exception_messages[r->int_no]);
printf(" Exception. System halted.");
for (;;);
}
else
{
irq_handler(r);
}
}