Page 1 of 1
PIC masking
Posted: Fri Feb 05, 2010 3:30 am
by jasonc122
Hi,
Does anybody know of a tutorial on PIC masking?
Better still can anybody tell me how to mask/unmask a particular IRQ on a master/slave PIC?
thanks.
Re: PIC masking
Posted: Fri Feb 05, 2010 4:02 am
by Combuster
Did you
RTFM and
STFW yet?
Re: PIC masking
Posted: Fri Feb 05, 2010 4:04 am
by jasonc122
thanks I've never come across these before. Will post back after reading them... thanks
Re: PIC masking
Posted: Fri Feb 05, 2010 4:16 am
by Combuster
That's weird, the latter link is mentioned in the FAQ.
Re: PIC masking
Posted: Fri Feb 05, 2010 4:57 am
by jasonc122
yeah funny that...
Anyway I've RTFM and unmasked all PIC interrupts.
However, I'm not receiving any hardware interrupts and yes I've STFW.
Could this be an emulator issue? (I'm using Qemu and Virtualbox)
Re: PIC masking
Posted: Fri Feb 05, 2010 5:16 am
by sebihepp
Did you set the interrupt flag in the processor (sti)?
Did you set the corresponding bits to zero for enabling? The PIC expects zeroes for enabling and ones for disabling.
Re: PIC masking
Posted: Fri Feb 05, 2010 5:46 am
by jasonc122
yes thanks, all of those have been addressed and still not able to receive hardware interrupts (nothing wrong with IDT as software interrupts are handled fine).
Does anybody have any idea what else needs to be done? Is it a Qemu or VirtualBox issue?
Re: PIC masking
Posted: Fri Feb 05, 2010 6:15 am
by sebihepp
Okay, we need more information. Are you in Realmode or Protectedmode? Wich hardware interrupt you want to recieve? Post the code where you initialize your Interrupts, the ISRs and your IDT.
Re: PIC masking
Posted: Fri Feb 05, 2010 11:57 am
by jasonc122
I'm in protected mode and my interrupts and ISR work fine. I'm able to call software interrupts and have it call an ISR. All interrupts are mapped to a single ISR (interrupts 0-40 and 128 are setup).
Here is how I initialised the PIC:
Code: Select all
#define PIC1_INT_OFFSET 0x20 // Offset for PIC1/Master interrupts
#define PIC2_INT_OFFSET 0x28 // Offset for PIC2/Slave interrupts
#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 PIC_EOI 0x20 /* End-of-interrupt command code */
#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) */
ki_outb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); // starts the initialization sequence
ki_io_wait();
ki_outb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4);
ki_io_wait();
ki_outb(PIC1_DATA, offset1); // define the PIC vectors
ki_io_wait();
ki_outb(PIC2_DATA, offset2);
ki_io_wait();
ki_outb(PIC1_DATA, 4); // continue initialization sequence
ki_io_wait();
ki_outb(PIC2_DATA, 2);
ki_io_wait();
ki_outb(PIC1_DATA, ICW4_8086);
ki_io_wait();
ki_outb(PIC2_DATA, ICW4_8086);
ki_io_wait();
ki_outb(PIC1_DATA, 0x00); // unmask EVERYTHING!!!
ki_outb(PIC2_DATA, 0x00);
Any suggestions as to why hardware interrupts are not working?
thanks.
Re: PIC masking
Posted: Fri Feb 05, 2010 1:19 pm
by sebihepp
Did you enable hardware interrupts? Use the asm mnemonic "sti".
I don't see anything else that can be wrong
Re: PIC masking
Posted: Fri Feb 05, 2010 4:23 pm
by jasonc122
Yes hardware interrupts have been enabled with "sti" and still not working.
My OS is loaded by GRUB which disables interrupts before loading a kernel image. What the heck does GRUB tamper with before loading kernel to disable interrupts?
thanks.
Re: PIC masking
Posted: Sat Feb 06, 2010 9:19 am
by XanClic
jasonc122 wrote:What the heck does GRUB tamper with before loading kernel to disable interrupts?
Afaik just a "cli". But you should know that I (and pretty sure many others, too) just load an IDT, initialize the PIC, unmask all IRQs and do an "sti" for enabling interrupts -- and it works. So it's definitely no problem caused by qemu/bochs or GRUB.
EDIT: Maybe it would be interesting, what you ki_io_wait does. Furthermore, what are offset1 and offset2 in
Code: Select all
ki_outb(PIC1_DATA, offset1); // define the PIC vectors
ki_io_wait();
ki_outb(PIC2_DATA, offset2);
ki_io_wait();
set to? Why don't you just use PIC1_INT_OFFSET and PIC2_INT_OFFSET here?
Re: PIC masking
Posted: Sat Feb 06, 2010 10:31 am
by xenos
When you run bochs, it may help you to log debug information from the PIC:
In bochs, click on "config". Choose "Log options for individual devices" from the appearing menu. Choose "PIC" from the list and set "debug" to "report". Leave the menu and continue the simulation. When your kernel has booted, close bochs and have a look at the generated log file.
Re: PIC masking
Posted: Thu Feb 11, 2010 3:36 am
by jasonc122
Thanks for your help. By insisting that I was probably doing something wrong, I was forced to check my code base in its entirety and found a cli instruction right before my kernel idles.