免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1813 | 回复: 0
打印 上一主题 下一主题

IRQ's and Exceptions, PIC, NMI, APIC, OPIC [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-01-06 17:10 |只看该作者 |倒序浏览
How do I know if an IRQ or Exception is firing?
When the PC boots up, the PIC IRQ's are mapped to interrupts 8 to 15 and 70 to 77.
So when your kernel boots up and you switch into protected mode, the PIC's remain unchanged, and the low 8 IRQ's end up corresponding to the same interrupt as CPU exceptions 8 to 15.

If one of these fire off, you can test if its an CPU exception or IRQ by testing some bits in the PIC status register but there is a much easier way, remap the PIC to use different interrupts than the CPU exceptions!




What is the PIC?
The PIC is a "rogrammable Interrupt Controler" and is one of THE important chips, without it, x86 would not be an interrupt driven architecture.
There needs to be a way for perhiperals and other devices external of the CPU to tell the system than an event has happened or needs to happen. exampels of this; hard disk IO, modem/serial ports, keyboard.

Without the PIC interface, you would have to poll all the devices in the system to see if they want to do anything (signal an event), but with the PIC, your system can run along nicely until such time that a device wants to signal an event, which means you dont waste time going to the devices, you let the devices come to you when they are ready.

In the begining, the age of the IBM XT, we had only 1 PIC chip giving us 8 hardware interrupt lines, but the 8259A PIC chip has a neat abality, it can cascade!

Cascading means you can daisy chain PIC chips together. This is what happened with the introduction of the IBM AT, we had a second PIC chip cascaded onto the first, giving us a total of 15 hardware lines... Why 15 and not 16? Thats because when you cascade chips, the PIC needs to use one of the int lines to signal to the other chip.

Thus, in an AT, IRQ line 2 is used to signal the second chip... But to confuse things more, IRQ 9 is redirectd to IRQ 2. So when you get an IRQ 9, the signal is redirected to IRQ 2.




So can I remap the PIC?
The PIC has the ability to be re-programmed to use a different set of interrupt values than the default ones. The default PIC values are; PIC   IRQ   INT
0  0  8
0  1  9
0  2  A
0  3  B
0  4  C
0  5  D
0  6  E
0  7  F
1  8  70
1  9  71
1  A  72
1  B  73
1  C  74
1  D  75
1  E  76
1  F  77

The PIC is programmable, and can be remapped quite easily, but each PIC vector must be divisable by 8, as the 8259A discards the lower 3 bits.

In x86 protected mode, it is good to remap the PICs beyond 32 as Intel have designated the first 32 interrupts as "reserved" for cpu exceptions. eg:

remap_pics(0x20, 0x2;
will remap the pics using 16 linear interrupts from 32 to 48 (0x20-0x2F).

/* remap the PIC controller interrupts to our vectors
   rather than the 8 + 70 as mapped by default */

#define        PIC1                0x20
#define        PIC2                0xA0
#define        PIC1_COMMAND        PIC1
#define        PIC1_DATA        (PIC1+1)
#define        PIC2_COMMAND        PIC2
#define        PIC2_DATA        (PIC2+1)
#define        PIC_EOI                0x20

#define        ICW1_ICW4        0x01                /* ICW4 (not) needed */
#define        ICW1_SINGLE        0x02                /* Single (cascade) mode */
#define        ICW1_INTERVAL4        0x04                /* Call address interval 4 ( */
#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 remap_pics(int pic1, int pic2)
{
        UCHAR        a1, a2;

        a1=inb(PIC1_DATA);
        a2=inb(PIC2_DATA);

        outb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4);
        io_wait();
        outb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4);
        io_wait();
        outb(PIC1_DATA, pic1);
        io_wait();
        outb(PIC2_DATA, pic2);
        io_wait();
        outb(PIC1_DATA, 4);
        io_wait();
        outb(PIC2_DATA, 2);
        io_wait();

        outb(PIC1_DATA, ICW4_8086);
        io_wait();
        outb(PIC2_DATA, ICW4_8086);
        io_wait();

        outb(PIC1_DATA, a1);
        outb(PIC2_DATA, a2);
}
               




So whats this NMI then?
The NMI (&Non Maskable Interrupt" is a hardware driven interrupt much like the PIC interrupts but the NMI goes diretcly the cpu, and not via the PIC controller.
Luckily you CAN have control over the NMI, otherwise you could be in deep trouble.

The NMI is turned "on"e; (set high) by the memory module when a memory parity error occurs.

You have to be carefull about disabling the NMI and the PIC for extended periods of time, your system will hang unless it has a failsafe timer! (Which you do have.. just down kill the PIT timer


/* enable the NMI */
void NMI_enable(void)
{
        outb(0x70, inb(0x70)&0x7F);
}

/* disable the NMI */
void NMI_disable(void)
{
        outb(0x70, inb(0x70)|=0x80);
}

               





APIC? Advanced Programmable Interrupt Controller
APIC is the Intel standard for the "new" PIC. Its used in multiprocessor systems.
I have no more info at this time.




OPIC? Open Programmable Interrupt Controller
I have no info on OPIC currently... Other than its a non-intel standard.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP