Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
static unsigned int cached_irq_mask;
#define __byte(x,y) (((unsigned char *)&(y))[[x]])
#define cached_21 (__byte(0,cached_irq_mask))
#define cached_A1 (__byte(1,cached_irq_mask))
static void irq_delay(unsigned long loops)
{
unsigned long i, j;
for (i = 0; i < loops; i++)
for (j = 0; j < loops; j++)
do {
} while (0);
}
void disable_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
cached_irq_mask |= mask;
if (irq & 8)
outb(cached_A1, 0xA1);
else
outb(cached_21, 0x21);
}
void enable_irq(unsigned int irq)
{
unsigned int mask = ~(1 << irq);
cached_irq_mask &= mask;
if (irq & 8)
outb(cached_A1, 0xA1);
else
outb(cached_21, 0x21);
}
void init_irq(void)
{
cached_irq_mask = 0xffff;
outb(0xff, 0x21); /* mask all of 8259A-1 */
outb(0xff, 0xA1); /* mask all of 8259A-2 */
outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
outb_p(0x03, 0x21); /* master does Auto EOI */
outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
outb_p(0x01, 0xA1); /* slave doesn't Auto EOI */
irq_delay(5000); /* wait for 8259A to initialize */
outb(cached_21, 0x21); /* restore master IRQ mask */
outb(cached_A1, 0xA1); /* restore slave IRQ mask */
}
i can understand the basic working like cascading of irq's and mapping of irq' s and all that stuff. can somebody explain me how this code is actually enabling interrupts for hardware requets bacause it is tough for me to figure out seeing the bkerndev code for irq.
i know i may be stupid asking this but i am new to operating system. also after using this code the irq's are not working.
thanks in advance for anay help
An IRQ goes thru the following path (very simplified):
Source ---> PIC ---> CPU
The IRQ can be blocked at the PIC and/or the CPU. enable_irq and disable_irq handler masking and unmasking interrupts on the PIC. For the CPU, the cli and sti instructions are used.
You need to give an sti after calling init_irq, and once all other IRQ handling is ready (like the IDT). Are you doing this?
You also need to call enable_irq with the appropriate arguments to enable a particular IRQ. At least enable IRQ 2, so that the slave PIC can cascade its IRQs to the master.
A more full diagram would be:
Source for IRQ 0-7 -------------------------> MASTER PIC ---> CPU
|
Source for IRQ 8-15 --> SLAVE PIC ---------+
(Please forgive the formatting of the above)
By 'not working' do you mean the interrupts are ignored or causing crashes?
thanks paulbarker... i got your concept.
by not working i mean i have encountered both an ignore and crashes (exceptions - invalid opcode fault). and soon as i comment the enable_irq() lines the opcode exception fault disappears and obviously an ignore occurs.
one more strange thing i have seen is that when a exception occurs the output on the screen says "invalid opcode fault". but bochs says it was bad TSS selector.
I have checked the exceptions correct and are working fine.whts is this ???
static unsigned int cached_irq_mask;
#define __byte(x,y) (((unsigned char *)&(y))[[x]])
#define cached_21 (__byte(0,cached_irq_mask))
#define cached_A1 (__byte(1,cached_irq_mask))
static void irq_delay(unsigned long loops)
{
unsigned long i, j;
for (i = 0; i < loops; i++)
for (j = 0; j < loops; j++)
do {
} while (0);
}
void disable_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
cached_irq_mask |= mask;
if (irq & 8)
outb(cached_A1, 0xA1);
else
outb(cached_21, 0x21);
}
void enable_irq(unsigned int irq)
{
unsigned int mask = ~(1 << irq);
cached_irq_mask &= mask;
if (irq & 8)
outb(cached_A1, 0xA1);
else
outb(cached_21, 0x21);
}
void init_irq(void)
{
cached_irq_mask = 0xffff;
outb(0xff, 0x21); /* mask all of 8259A-1 */
outb(0xff, 0xA1); /* mask all of 8259A-2 */
outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
outb_p(0x03, 0x21); /* master does Auto EOI */
outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
outb_p(0x01, 0xA1); /* slave doesn't Auto EOI */
irq_delay(5000); /* wait for 8259A to initialize */
outb(cached_21, 0x21); /* restore master IRQ mask */
outb(cached_A1, 0xA1); /* restore slave IRQ mask */
}
i can understand the basic working like cascading of irq's and mapping of irq' s and all that stuff. can somebody explain me how this code is actually enabling interrupts for hardware requets bacause it is tough for me to figure out seeing the bkerndev code for irq.
i know i may be stupid asking this but i am new to operating system. also after using this code the irq's are not working.
thanks in advance for anay help
I also learned from the tutorial(but the tutorial has no such codes), but finaly, my experiment is ok.
correct the code above does not belong to the tutorial . i took it from somewhere else just learn how things works the other way. but the irq's are not working now.
moreoever, i am getting following exceptions now...
invalid TSS fault
invalid opcode fault.
i cant see any such fault in the code. please help me .
thanks in advance for any help