Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

Interrupt Manager
[Kernel]


Functions

void disable_IRQ (uint8_t IRQ)
 Disable an IRQ line.
Parameters:
IRQ  The IRQ line to disable.


void enable_IRQ (uint8_t IRQ)
 Enable an IRQ line.
Parameters:
IRQ  The IRQ line to enable.


void reprogram_PIC ()
 Initialize the Programmable Interrupt Controllers (PICs).
Note:
The AT and PS/2 have 2 interrupt controllers to issue the IRQs, one master and one slaved at IRQ2. This routine initialize the 8259 interrupt controllers, using vector [0x20..0x2F] for [IRQ0..IRQ15] (0x20..0x27 for master and 0x28..0x2F for slave).


void install_IDT ()
 Initialize the IDT (Interrupt Descriptor Table).

void install_irq_handler (uint8_t irq, void *handler)
 Install an IRQ handler routine.
Parameters:
irq  The interrupt number.
handler  A pointer to the handler routine.
Note:
This is valid only for hardware interrupts. You cannot install a software interrupt handler in this way.


void default_handler (irq_context_t *c)
 This is the default interrupt handler. It is invoked every time an interrupt occurs.
Parameters:
c  The context of the current task after the interrupt.
Note:
Only hardware interrupts and MINIRIGHI_INT are accepted. In the other cases we assume the interrupt is unhandled!



Detailed Description

The interrupt manager.

Function Documentation

void default_handler irq_context_t   c
 

This is the default interrupt handler. It is invoked every time an interrupt occurs.

Parameters:
c  The context of the current task after the interrupt.
Note:
Only hardware interrupts and MINIRIGHI_INT are accepted. In the other cases we assume the interrupt is unhandled!

Definition at line 216 of file interrupt.c.

00217 {
00218         if ( c->IRQ < sizeof(irq_handler) )
00219         {
00220                 // An hardware interrupt occurs                         //
00221                 // Call the interrupt handler if exists                 //
00222                 if ( irq_handler[c->IRQ].handler != NULL )
00223                 {
00224                         // Pointer to the handler function              //
00225                         int (*p)()=(void *)irq_handler[c->IRQ].handler;
00226                         (*p)();
00227                 }
00228                 else
00229                 {
00230                         // Unhandled interrupt!                         //
00231                         unhandled_interrupt(c->IRQ);
00232                 }
00233         }
00234         else
00235         {
00236                 // Software interrupt occurs                            //
00237                 // (only MINIRIGHI INT is accepted)                     //
00238                 switch ( c->IRQ )
00239                 {
00240                         case MINIRIGHI_INT:
00241                                 syscall_handler(&(c->eax), &(c->ebp));
00242                         break;
00243 
00244                         default:
00245                                 unhandled_interrupt(c->IRQ);
00246                         break;
00247                 }
00248                 return;
00249         }
00250         // Re-enable the IRQ line (master channel)                      //
00251         outportb(PORT_8259_M, EOI);
00252         if ( c->IRQ >= 8 )
00253                 // Re-enable also the IRQ slave channel                 //
00254                 outportb(PORT_8259_S, EOI);
00255 }

void disable_IRQ uint8_t    IRQ
 

Disable an IRQ line.

Parameters:
IRQ  The IRQ line to disable.

Definition at line 60 of file interrupt.c.

00061 {
00062         uint8_t mask;
00063 
00064         if (IRQ > 15) return;
00065 
00066         if (IRQ < 8)
00067         {
00068                 // Master                                               //
00069                 mask = inportb(PORT_INT_MASK_M);
00070                 mask |= 1 << IRQ;
00071                 outportb(PORT_INT_MASK_M, mask);
00072         }
00073         else
00074         {
00075                 // Slave                                                //
00076                 mask = inportb(PORT_INT_MASK_S);
00077                 mask |= 1 << (IRQ-8);
00078                 outportb(PORT_INT_MASK_S, mask);
00079         }
00080 }

void enable_IRQ uint8_t    IRQ
 

Enable an IRQ line.

Parameters:
IRQ  The IRQ line to enable.

Definition at line 84 of file interrupt.c.

00085 {
00086         uint8_t mask;
00087 
00088         if (IRQ > 15) return;
00089 
00090         if (IRQ < 8)
00091         {
00092                 // Master                                               //
00093                 mask = inportb(PORT_INT_MASK_M);
00094                 mask &= ~(1 << IRQ);
00095                 outportb(PORT_INT_MASK_M, mask);
00096         }
00097         else
00098         {
00099                 // Slave                                                //
00100                 mask = inportb(PORT_INT_MASK_S);
00101                 mask &= ~(1 << (IRQ-8));
00102                 outportb(PORT_INT_MASK_S, mask);
00103         }
00104 }

void install_IDT  
 

Initialize the IDT (Interrupt Descriptor Table).

Definition at line 281 of file interrupt.c.

00282 {
00283         unsigned i;
00284 
00285         // Initialize exception handlers (0x00..0x1F)                   //
00286         for(i=0x00; i<=0x1F; i++)
00287                 setup_IDT_entry(i, KERNEL_CODE, (dword)&_exc_unhand, INT_GATE, 0);
00288 
00289         // Setup the IDT entries for exceptions                         //
00290         setup_IDT_entry(0x00, KERNEL_CODE, (dword)&_exc_00, INT_GATE, 0);
00291         setup_IDT_entry(0x01, KERNEL_CODE, (dword)&_exc_01, INT_GATE, 0);
00292         setup_IDT_entry(0x02, KERNEL_CODE, (dword)&_exc_02, INT_GATE, 0);
00293         setup_IDT_entry(0x03, KERNEL_CODE, (dword)&_exc_03, INT_GATE, 0);
00294         setup_IDT_entry(0x04, KERNEL_CODE, (dword)&_exc_04, INT_GATE, 0);
00295         setup_IDT_entry(0x05, KERNEL_CODE, (dword)&_exc_05, INT_GATE, 0);
00296         setup_IDT_entry(0x06, KERNEL_CODE, (dword)&_exc_06, INT_GATE, 0);
00297         setup_IDT_entry(0x07, KERNEL_CODE, (dword)&_exc_07, INT_GATE, 0);
00298         setup_IDT_entry(0x08, KERNEL_CODE, (dword)&_exc_08, INT_GATE, 0);
00299         setup_IDT_entry(0x09, KERNEL_CODE, (dword)&_exc_09, INT_GATE, 0);
00300         setup_IDT_entry(0x0A, KERNEL_CODE, (dword)&_exc_0A, INT_GATE, 0);
00301         setup_IDT_entry(0x0B, KERNEL_CODE, (dword)&_exc_0B, INT_GATE, 0);
00302         setup_IDT_entry(0x0C, KERNEL_CODE, (dword)&_exc_0C, INT_GATE, 0);
00303         setup_IDT_entry(0x0D, KERNEL_CODE, (dword)&_exc_0D, INT_GATE, 0);
00304         setup_IDT_entry(0x0E, KERNEL_CODE, (dword)&_exc_0E, INT_GATE, 0);
00305         setup_IDT_entry(0x0F, KERNEL_CODE, (dword)&_exc_0F, INT_GATE, 0);
00306 
00307         // Initialize interrupt handlers 0x20..0xFF                     //
00308         for(i=0x20; i<=0xFF; i++)
00309                 setup_IDT_entry(i, KERNEL_CODE, (dword)&_irq_unhand, INT_GATE, 0);
00310 
00311         // Setup the IDT entries for IRQs                               //
00312         setup_IDT_entry(0x20, KERNEL_CODE, (dword)&_irq_00, INT_GATE, 0);
00313         setup_IDT_entry(0x21, KERNEL_CODE, (dword)&_irq_01, INT_GATE, 0);
00314         setup_IDT_entry(0x22, KERNEL_CODE, (dword)&_irq_02, INT_GATE, 0);
00315         setup_IDT_entry(0x23, KERNEL_CODE, (dword)&_irq_03, INT_GATE, 0);
00316         setup_IDT_entry(0x24, KERNEL_CODE, (dword)&_irq_04, INT_GATE, 0);
00317         setup_IDT_entry(0x25, KERNEL_CODE, (dword)&_irq_05, INT_GATE, 0);
00318         setup_IDT_entry(0x26, KERNEL_CODE, (dword)&_irq_06, INT_GATE, 0);
00319         setup_IDT_entry(0x27, KERNEL_CODE, (dword)&_irq_07, INT_GATE, 0);
00320         setup_IDT_entry(0x28, KERNEL_CODE, (dword)&_irq_08, INT_GATE, 0);
00321         setup_IDT_entry(0x29, KERNEL_CODE, (dword)&_irq_09, INT_GATE, 0);
00322         setup_IDT_entry(0x2A, KERNEL_CODE, (dword)&_irq_0A, INT_GATE, 0);
00323         setup_IDT_entry(0x2B, KERNEL_CODE, (dword)&_irq_0B, INT_GATE, 0);
00324         setup_IDT_entry(0x2C, KERNEL_CODE, (dword)&_irq_0C, INT_GATE, 0);
00325         setup_IDT_entry(0x2D, KERNEL_CODE, (dword)&_irq_0D, INT_GATE, 0);
00326         setup_IDT_entry(0x2E, KERNEL_CODE, (dword)&_irq_0E, INT_GATE, 0);
00327         setup_IDT_entry(0x2F, KERNEL_CODE, (dword)&_irq_0F, INT_GATE, 0);
00328 
00329         // Install Minirighi system calls handler                       //
00330         setup_IDT_entry(MINIRIGHI_INT, KERNEL_CODE, (dword)&_irq_80, TRAP_GATE | DPL_3, 0);
00331 
00332         // Set up the IDT pointer                                       //
00333         idt_ptr.limit = (IDT_DIM * sizeof(idt_entry_t) - 1);
00334         * (dword *)idt_ptr.base = ((dword)&idt);
00335 
00336         // Load info into IDTR register                                 //
00337         __asm__("lidtl (%0)" : : "r"((dword)&idt_ptr));
00338 }

void install_irq_handler uint8_t    irq,
void *    handler
 

Install an IRQ handler routine.

Parameters:
irq  The interrupt number.
handler  A pointer to the handler routine.
Note:
This is valid only for hardware interrupts. You cannot install a software interrupt handler in this way.

Definition at line 172 of file interrupt.c.

00173 {
00174         dword IF = GET_IF();
00175 
00176         if ( irq > TOT_IRQ )
00177                 return;
00178 
00179         disable();
00180 
00181         irq_handler[irq].handler = handler;
00182         enable_IRQ(irq);
00183 
00184         SET_IF(IF);
00185         return;
00186 }

void reprogram_PIC  
 

Initialize the Programmable Interrupt Controllers (PICs).

Note:
The AT and PS/2 have 2 interrupt controllers to issue the IRQs, one master and one slaved at IRQ2. This routine initialize the 8259 interrupt controllers, using vector [0x20..0x2F] for [IRQ0..IRQ15] (0x20..0x27 for master and 0x28..0x2F for slave).

Definition at line 113 of file interrupt.c.

00114 {
00115         // Start initialization for master & slave                      //
00116         outportb(PORT_8259_M, 0x11);
00117         outportb(PORT_8259_S, 0x11);
00118 
00119         outportb(PORT_INT_MASK_M, 0x20); // master base vector          //
00120         outportb(PORT_INT_MASK_S, 0x28); // slave base vector           //
00121 
00122         outportb(PORT_INT_MASK_M, 1 << 2); // IRQ2 cascade to slave     //
00123         outportb(PORT_INT_MASK_S, 2); // cascade on IRQ2                //
00124 
00125         // Finish 8259 initialization                                   //
00126         outportb(PORT_INT_MASK_M, 1);
00127         outportb(PORT_INT_MASK_S, 1);
00128 
00129         // Disable all IRQs for master, except the IRQ2 cascade line.   //
00130         outportb(PORT_INT_MASK_M, ~(1 << 2));
00131         // Disable all IRQs for slave.                                  //
00132         outportb(PORT_INT_MASK_S, 0xFF);
00133 }


Generated on Fri Feb 20 15:32:21 2004 for Minirighi by doxygen1.2.18