2 * Copyright (c) 2008 Joshua Phillips. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "interrupt.h"
35 #define PIC1_DATA 0x21
37 #define PIC2_DATA 0xA1
41 #define ICW1_ICW4 0x01
42 #define ICW1_SINGLE 0x02
43 #define ICW1_INTERVAL4 0x04
44 #define ICW1_LEVEL 0x08
45 #define ICW1_INIT 0x10
46 #define ICW4_8086 0x01
47 #define ICW4_AUTO 0x02
48 #define ICW4_BUF_SLAVE 0x08
49 #define ICW4_BUF_MASTER 0x0C
50 #define ICW4_SFNM 0x10
52 isr_t interrupt_handlers
[256];
53 static uint16_t *idt
= NULL
;
58 static void default_interrupt_handler(int vector
, struct interrupt_stack
*is
)
60 console_printf(&tty1
, "Interrupt 0x%X fired (not handled) (eip=%.8X).\n", vector
, is
->eip
);
61 if (vector
>= 0x20 && vector
< 0x30)
62 ack_irq(vector
- 0x20);
65 static void load_idt_addr(unsigned short *idt
)
69 "movw %%cx,(%%esp) \n"
70 "movl %%eax,2(%%esp) \n"
73 :: "c" (256 * 8), "a" (idt
)
77 static void io_wait(void)
84 static void remap_pics(void)
86 int pic1_offset
= 0x20;
87 int pic2_offset
= 0x28;
90 //a1 = inb(PIC1_DATA);
91 //a2 = inb(PIC2_DATA);
95 outb(PIC1_CMD
, ICW1_INIT
+ ICW1_ICW4
);
97 outb(PIC2_CMD
, ICW1_INIT
+ ICW1_ICW4
);
99 outb(PIC1_DATA
, pic1_offset
);
101 outb(PIC2_DATA
, pic2_offset
);
107 outb(PIC1_DATA
, ICW4_8086
);
109 outb(PIC2_DATA
, ICW4_8086
);
115 void interrupt_init(void **p_idt
)
119 idt
= (uint16_t *) *p_idt
;
120 *p_idt
= idt
+ (256 * 4);
122 isr_size
= (unsigned long) isr1
- (unsigned long) isr0
;
123 p
= (unsigned long) isr0
;
126 for (i
=0; i
<256; i
++){
128 idt
[i
* 4 + 1] = SEG_DPL0_CODE
;
129 idt
[i
* 4 + 2] = 0x8E00;
130 idt
[i
* 4 + 3] = p
>> 16;
133 // set the default interrupt handler, too
134 interrupt_handlers
[i
] = default_interrupt_handler
;
137 // load the IDT address
143 // Enable the cascade irq (so that the slave PIC can work)
147 void enable_interrupts(void)
149 asm volatile ("sti");
152 void disable_interrupts(void)
154 asm volatile ("cli");
157 void set_interrupt(int vector
, isr_t handler
)
159 interrupt_handlers
[vector
] = handler
;
162 void clear_interrupt(int vector
)
164 interrupt_handlers
[vector
] = default_interrupt_handler
;
167 void interrupt_flags(int vector
, unsigned int flags
)
169 if (flags
& INTR_USER
){
170 idt
[vector
* 4 + 2] = 0xEE00;
172 idt
[vector
* 4 + 2] = 0x8E00;
176 int irq_to_int(int irq
)
181 int int_to_irq(int intn
)
186 void unmask_irq(int n
)
197 a
&= ~(1 << (n
- 8));
221 outb(PIC2_CMD
, PIC_ACK
);
222 outb(PIC1_CMD
, PIC_ACK
);