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. :-k

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.

:oops: