i8259.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <arch/drivers/i8259.h>
00036 #include <cpu.h>
00037 #include <arch/types.h>
00038 #include <arch/asm.h>
00039 #include <arch.h>
00040 #include <print.h>
00041 #include <interrupt.h>
00042 
00043 /*
00044  * This is the PIC driver.
00045  * Programmable Interrupt Controller for UP systems.
00046  */
00047 
00048 static void pic_spurious(int n, istate_t *istate);
00049 
00050 void i8259_init(void)
00051 {
00052         /* ICW1: this is ICW1, ICW4 to follow */
00053         outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4);
00054 
00055         /* ICW2: IRQ 0 maps to INT IRQBASE */
00056         outb(PIC_PIC0PORT2, IVT_IRQBASE);
00057 
00058         /* ICW3: pic1 using IRQ IRQ_PIC1 */
00059         outb(PIC_PIC0PORT2, 1 << IRQ_PIC1);
00060 
00061         /* ICW4: i8086 mode */
00062         outb(PIC_PIC0PORT2, 1);
00063 
00064         /* ICW1: ICW1, ICW4 to follow */
00065         outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4);
00066 
00067         /* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */
00068         outb(PIC_PIC1PORT2, IVT_IRQBASE + 8);
00069 
00070         /* ICW3: pic1 is known as IRQ_PIC1 */
00071         outb(PIC_PIC1PORT2, IRQ_PIC1);
00072 
00073         /* ICW4: i8086 mode */
00074         outb(PIC_PIC1PORT2, 1);
00075 
00076         /*
00077          * Register interrupt handler for the PIC spurious interrupt.
00078          */
00079         exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious); 
00080 
00081         /*
00082          * Set the enable/disable IRQs handlers.
00083          * Set the End-of-Interrupt handler.
00084          */
00085         enable_irqs_function = pic_enable_irqs;
00086         disable_irqs_function = pic_disable_irqs;
00087         eoi_function = pic_eoi;
00088 
00089         pic_disable_irqs(0xffff);               /* disable all irq's */
00090         pic_enable_irqs(1<<IRQ_PIC1);           /* but enable pic1 */
00091 }
00092 
00093 void pic_enable_irqs(__u16 irqmask)
00094 {
00095         __u8 x;
00096 
00097         if (irqmask & 0xff) {
00098                 x = inb(PIC_PIC0PORT2);
00099                 outb(PIC_PIC0PORT2, x & (~(irqmask & 0xff)));
00100         }
00101         if (irqmask >> 8) {
00102                 x = inb(PIC_PIC1PORT2);
00103                 outb(PIC_PIC1PORT2, x & (~(irqmask >> 8)));
00104         }
00105 }
00106 
00107 void pic_disable_irqs(__u16 irqmask)
00108 {
00109         __u8 x;
00110 
00111         if (irqmask & 0xff) {
00112                 x = inb(PIC_PIC0PORT2);
00113                 outb(PIC_PIC0PORT2, x | (irqmask & 0xff));
00114         }
00115         if (irqmask >> 8) {
00116                 x = inb(PIC_PIC1PORT2);
00117                 outb(PIC_PIC1PORT2, x | (irqmask >> 8));
00118         }
00119 }
00120 
00121 void pic_eoi(void)
00122 {
00123         outb(0x20,0x20);
00124         outb(0xa0,0x20);
00125 }
00126 
00127 void pic_spurious(int n, istate_t *istate)
00128 {
00129 #ifdef CONFIG_DEBUG
00130         printf("cpu%d: PIC spurious interrupt\n", CPU->id);
00131 #endif
00132 }
00133 

Generated on Sun Jun 18 16:38:50 2006 for HelenOS Kernel (ia32) by  doxygen 1.4.6