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

interrupt.c File Reference

Interrupt manager. More...

#include <const.h>
#include <arch/exception.h>
#include <arch/i386.h>
#include <arch/mem.h>
#include <arch/paging.h>
#include <kernel/clock.h>
#include <kernel/console.h>
#include <kernel/floppy.h>
#include <kernel/keyboard.h>
#include <kernel/serial.h>
#include <kernel/speaker.h>
#include <kernel/syscall.h>
#include <kernel/task.h>
#include <net/rtl8139.h>
#include <arch/interrupt.h>

Go to the source code of this file.

Data Structures

struct  irq_desc
 An IRQ handler pointer. More...


Defines

#define TOT_IRQ   ( sizeof(irq_handler) / sizeof(irq_desc_t) )
 Total number of hardware interrupts.


Typedefs

typedef irq_desc irq_desc_t
 An IRQ handler pointer.


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_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 unhandled_interrupt (uint8_t irq)
 Manage an unhandled interrupt.
Parameters:
irq  The interrupt number.


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!


void setup_IDT_entry (byte i, word selector, dword offset, byte attribs, byte paramcnt)
 Set up an IDT entry.
Parameters:
i  The index of the entry.
selector  The selector for the interrupt handler.
offset  The entry point of the handler.
attribs  The descriptor attributes.
paramcnt  How many items must be copied from the previous stack to the new privileged stack.


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


Variables

volatile idt_entry_t idt [IDT_DIM]
 Interrupt Descriptor Table (IDT).

idt_reg_t idt_ptr
 Value of Interrupt Descriptor Table Register.

void _irq_00
void _irq_01
void _irq_02
void _irq_03
void _irq_04
void _irq_05
void _irq_06
void _irq_07
void _irq_08
void _irq_09
void _irq_0A
void _irq_0B
void _irq_0C
void _irq_0D
void _irq_0E
void _irq_0F
void _irq_80
void _irq_unhand
void _exc_00
void _exc_01
void _exc_02
void _exc_03
void _exc_04
void _exc_05
void _exc_06
void _exc_07
void _exc_08
void _exc_09
void _exc_0A
void _exc_0B
void _exc_0C
void _exc_0D
void _exc_0E
void _exc_0F
void _exc_unhand
irq_desc_t irq_handler []
 A table for hardware interrupt handlers only.


Detailed Description

Interrupt manager.

Author:
Andrea Righi <drizzt@inwind.it>
Date:
Last update: 2004-01-24
Note:
Copyright (©) 2003 Andrea Righi
Todo:
Stack fault exception in kernel mode must be managed by a task-gate in the IDT. We have to define a TSS for the double fault exception. When the double fault task will be called we'll have a stack fault exception in kernel-mode. In user-mode there are no problems, because there is also the privileged stack. In this case a stack fault is managed like a normal page fault.

Definition in file interrupt.c.


Define Documentation

#define TOT_IRQ   ( sizeof(irq_handler) / sizeof(irq_desc_t) )
 

Total number of hardware interrupts.

Definition at line 164 of file interrupt.c.


Typedef Documentation

typedef struct irq_desc irq_desc_t
 

An IRQ handler pointer.


Function Documentation

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 }

void setup_IDT_entry byte    i,
word    selector,
dword    offset,
byte    attribs,
byte    paramcnt
 

Set up an IDT entry.

Parameters:
i  The index of the entry.
selector  The selector for the interrupt handler.
offset  The entry point of the handler.
attribs  The descriptor attributes.
paramcnt  How many items must be copied from the previous stack to the new privileged stack.

Definition at line 265 of file interrupt.c.

00266 {
00267         dword IF = GET_IF();
00268 
00269         disable();
00270 
00271         idt[i].offset0_15 =  offset & 0xFFFF;
00272         idt[i].offset16_31 = offset >> 16;
00273         idt[i].selector = selector;
00274         idt[i].attribs = attribs;
00275         idt[i].paramcnt = paramcnt;
00276 
00277         SET_IF(IF);
00278 }

void unhandled_interrupt uint8_t    irq
 

Manage an unhandled interrupt.

Parameters:
irq  The interrupt number.

Definition at line 190 of file interrupt.c.

00191 {
00192         set_color(LIGHT_RED);
00193         kprintf("\n\rUnhandled IRQ #%03u from task [%s] (%u)!!!", irq, get_pname(), get_pid());
00194         set_color(DEFAULT_COLOR);
00195         beep();
00196 
00197         // Kill the task                                                //
00198         if ( kill(get_pid()) == TRUE )
00199         {
00200                 kprintf("\n\rTask [%s] (%u) killed!\n\r",
00201                         get_pname(), get_pid()
00202                 );
00203         }
00204         else
00205                 kprintf("\n\rUnable to kill the task [%s] (%u)", get_pname(), get_pid());
00206 }


Variable Documentation

void _exc_00
 

Definition at line 54 of file interrupt.c.

void _exc_01
 

Definition at line 54 of file interrupt.c.

void _exc_02
 

Definition at line 54 of file interrupt.c.

void _exc_03
 

Definition at line 54 of file interrupt.c.

void _exc_04
 

Definition at line 54 of file interrupt.c.

void _exc_05
 

Definition at line 54 of file interrupt.c.

void _exc_06
 

Definition at line 54 of file interrupt.c.

void _exc_07
 

Definition at line 54 of file interrupt.c.

void _exc_08
 

Definition at line 55 of file interrupt.c.

void _exc_09
 

Definition at line 55 of file interrupt.c.

void _exc_0A
 

Definition at line 55 of file interrupt.c.

void _exc_0B
 

Definition at line 55 of file interrupt.c.

void _exc_0C
 

Definition at line 55 of file interrupt.c.

void _exc_0D
 

Definition at line 55 of file interrupt.c.

void _exc_0E
 

Definition at line 55 of file interrupt.c.

void _exc_0F
 

Definition at line 55 of file interrupt.c.

void _exc_unhand
 

Definition at line 56 of file interrupt.c.

void _irq_00
 

Definition at line 47 of file interrupt.c.

void _irq_01
 

Definition at line 47 of file interrupt.c.

void _irq_02
 

Definition at line 47 of file interrupt.c.

void _irq_03
 

Definition at line 47 of file interrupt.c.

void _irq_04
 

Definition at line 47 of file interrupt.c.

void _irq_05
 

Definition at line 47 of file interrupt.c.

void _irq_06
 

Definition at line 47 of file interrupt.c.

void _irq_07
 

Definition at line 47 of file interrupt.c.

void _irq_08
 

Definition at line 48 of file interrupt.c.

void _irq_09
 

Definition at line 48 of file interrupt.c.

void _irq_0A
 

Definition at line 48 of file interrupt.c.

void _irq_0B
 

Definition at line 48 of file interrupt.c.

void _irq_0C
 

Definition at line 48 of file interrupt.c.

void _irq_0D
 

Definition at line 48 of file interrupt.c.

void _irq_0E
 

Definition at line 48 of file interrupt.c.

void _irq_0F
 

Definition at line 48 of file interrupt.c.

void _irq_80
 

Definition at line 49 of file interrupt.c.

void _irq_unhand
 

Definition at line 50 of file interrupt.c.

volatile idt_entry_t idt[IDT_DIM]
 

Interrupt Descriptor Table (IDT).

Definition at line 40 of file interrupt.c.

idt_reg_t idt_ptr
 

Value of Interrupt Descriptor Table Register.

Definition at line 43 of file interrupt.c.

irq_desc_t irq_handler[] [static]
 

Initial value:

{
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },

        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL },
        { NULL }
}
A table for hardware interrupt handlers only.

Definition at line 142 of file interrupt.c.


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