00001 /* ndk - [ pic.c ] 00002 * 00003 * Contains simple routines to enable the PIC 00004 * and remap all IRQs to 0x20 - 0x2F. Also 00005 * contians routines to enable/disable certain 00006 * IRQs. 00007 * 00008 * (c)2002 dcipher / neuraldk 00009 * www.neuraldk.org 00010 */ 00011 00012 #include "pic.h" 00013 #include "io.h" 00014 00015 unsigned short irq_mask = 0xFFFF; // All IRQs disabled initially 00016 00017 /* init8259() initialises the 8259 Programmable Interrupt Controller */ 00018 void picInit(void) { 00019 //message("initializing 8259 PIC...\n"); 00020 00021 /* Initialize the PIC and remap hardware irqs to int 32 and up. 00022 * In other words, irqs 0-7 (from the first PIC) will be int 32-39, 00023 * and irqs 8-15 (from the second PIC) will be int 40-47. 00024 */ 00025 00026 /* initialize the first (master) PIC */ 00027 //outportb(M_PIC, ICW1); /* ICW1: bit 0 - requires ICW4 */ 00028 //outportb(M_PIC + 1, M_VEC); /* the new vector for irq 0 */ 00029 //outportb(M_PIC + 1, 0x80); /* not sure about this (10000000b) */ 00030 //outportb(M_PIC + 1, ICW4); /* ICW4: 8086 mode */ 00031 00032 /* initialize the second (slave) PIC */ 00033 //outportb(S_PIC, ICW1); 00034 //outportb(S_PIC + 1, S_VEC); /* new vector for irq 8 */ 00035 //outportb(S_PIC + 1, 7); /* not sure about this... */ 00036 //outportb(S_PIC + 1, 1); /* or this... */ 00037 00038 outportb (M_PIC, 0x11); /* start 8259 initialization */ 00039 outportb (S_PIC, 0x11); 00040 outportb (M_PIC+1, M_VEC); /* master base interrupt vector */ 00041 outportb (S_PIC+1, S_VEC); /* slave base interrupt vector */ 00042 outportb (M_PIC+1, 1<<2); /* bitmask for cascade on IRQ2 */ 00043 outportb (S_PIC+1, 2); /* cascade on IRQ2 */ 00044 outportb (M_PIC+1, 1); /* finish 8259 initialization */ 00045 outportb (S_PIC+1, 1); 00046 00047 outportb(M_IMR, 0xff); /* Mask all interrupts */ 00048 outportb(S_IMR, 0xff); 00049 00050 asm("sti"); 00051 } 00052 00053 /* This is the old PIC initialization code that I borrowed from 00054 * GazOS because mine wasn't working... this code doesn't work 00055 * either!!! And yet GazOS itself does... I don't get it. 00056 * Anyway, doesn't matter... I got my own code working, but I'll 00057 * leave this here, just in case I forgot something in my code 00058 */ 00059 //outportb(M_PIC, ICW1); /* Start 8259 initialization */ 00060 //outportb(S_PIC, ICW1); 00061 00062 //outportb(M_PIC+1, M_VEC); /* Base interrupt vector */ 00063 //outportb(S_PIC+1, S_VEC); 00064 00065 //outportb(M_PIC+1, 1<<2); /* Bitmask for cascade on IRQ 2 */ 00066 //outportb(S_PIC+1, 2); /* Cascade on IRQ 2 */ 00067 00068 //outportb(M_PIC+1, ICW4); /* Finish 8259 initialization */ 00069 //outportb(S_PIC+1, ICW4); 00070 00071 //outportb(M_IMR, 0xff); /* Mask all interrupts */ 00072 //outportb(S_IMR, 0xff); 00073 00074 /* enables irq irq_no */ 00075 void picEnableIRQ(unsigned short irq_no) { 00076 irq_mask &= ~(1 << irq_no); 00077 if(irq_no >= 8) 00078 irq_mask &= ~(1 << 2); 00079 00080 outportb(M_PIC+1, irq_mask & 0xFF); 00081 outportb(S_PIC+1, (irq_mask >> 8) & 0xFF); 00082 } 00083 00084 /* disables irq irq_no */ 00085 void picDisableIRQ(unsigned short irq_no) { 00086 irq_mask |= (1 << irq_no); 00087 if((irq_mask & 0xFF00)==0xFF00) 00088 irq_mask |= (1 << 2); 00089 00090 outportb(M_PIC+1, irq_mask & 0xFF); 00091 outportb(S_PIC+1, (irq_mask >> 8) & 0xFF); 00092 }