I'm not getting any IRQ's from my PIC
Posted: Sun Jun 09, 2013 2:38 pm
Hey guys. I wrote my own routine to initialize and set up the PIC, and that wasn't working. So i temporarily copied code from the pic article on the osdev wiki, but i'm still not getting any IRQ's
I've zeroed out the interrupt mask register, and i've tested that my software interrupts are working (i put an int3 breakpoint in my code), and i even mapped every interrupt to the same function in my idt to see if the irq's were being sent to the wrong interrupt, but i'm still getting nothing. What am i doing wrong?
I'm testing to see if i get IRQ's by typing on my keyboard.
pic_remap function:
IDT Initialization function:
kernel_main function:
I've zeroed out the interrupt mask register, and i've tested that my software interrupts are working (i put an int3 breakpoint in my code), and i even mapped every interrupt to the same function in my idt to see if the irq's were being sent to the wrong interrupt, but i'm still getting nothing. What am i doing wrong?
I'm testing to see if i get IRQ's by typing on my keyboard.
pic_remap function:
Code: Select all
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
void PIC_remap(unsigned char offset1, unsigned char offset2)
{
// unsigned char a1, a2;
// a1 = inb(PIC1_DATA); // save masks
// a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4);
io_wait();
outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
io_wait();
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
// outb(PIC1_DATA, a1); // restore saved masks.
// outb(PIC2_DATA, a2);
outb(PIC1_DATA, 0); // zero out the pic mask
outb(PIC2_DATA, 0);
}
Code: Select all
void idt_init()
{
idt_location.offset = (unsigned long) &idt;
idt_location.size = (sizeof(struct IDT_ENTRY) * 8) - 1;
unsigned char *zero_idt = (unsigned char*) idt;
for(unsigned long i = 0; i < idt_location.size; i++)
zero_idt[i] = 0;
unsigned char flags = 0x8E; // standard 32 bit interrupt gate
unsigned long offset = 0;
for(int i = 0; i < 256; i++)
{
switch(i)
{
case 0:
{
offset = (unsigned long) isr_divide_by_zero;
}
break;
case 1:
{
offset = (unsigned long) isr_debugger;
}
break;
case 2:
{
offset = (unsigned long) isr_nmi;
}
break;
case 3:
{
offset = (unsigned long) isr_breakpoint;
}
break;
case 4:
{
offset = (unsigned long) isr_overflow;
}
break;
case 5:
{
offset = (unsigned long) isr_bounds;
}
break;
case 6:
{
offset = (unsigned long) isr_invalid_opcode;
}
break;
case 7:
{
offset = (unsigned long) isr_coprocessor_not_avail;
}
break;
case 8:
{
offset = (unsigned long) isr_double_fault;
}
break;
case 9:
{
offset = (unsigned long) isr_coprocessor_segment_overrun;
}
break;
case 10:
{
offset = (unsigned long) isr_invalid_tss;
}
break;
case 11:
{
offset = (unsigned long) isr_segment_not_present;
}
break;
case 12:
{
offset = (unsigned long) isr_stack_fault;
}
break;
case 13:
{
offset = (unsigned long) isr_general_protection_fault;
}
break;
case 14:
{
offset = (unsigned long) isr_page_fault;
}
break;
case 15:
{
offset = (unsigned long) isr_reserved;
}
break;
case 16:
{
offset = (unsigned long) isr_math_fault;
}
break;
case 17:
{
offset = (unsigned long) isr_alignment_check;
}
break;
case 18:
{
offset = (unsigned long) isr_machine_check;
}
break;
case 19:
{
offset = (unsigned long) isr_simd_floating_point_exception;
}
break;
case 0x21: // keyboard
{
offset = (unsigned long) isr_keyboard;
}
break;
default:
continue;
}
idt[i].offset_low = (offset & 0xFFFF);
idt[i].offset_high = ((offset >> 16) & 0xFFFF);
idt[i].selector = 0x08;
idt[i].zero = 0;
idt[i].type_attr = flags;
}
install_idt();
}
Code: Select all
void kernel_main()
{
k_clearscreen(DEFAULT_TEXT);
idt_init(); // install interrupt descriptor table
PIC_remap(0x20, 0x28);
k_putstring("PIC Initialized.\n", DEFAULT_TEXT);
}