8259A中斷控制器

8259A中斷控制器

8259A晶片是一個中斷管理晶片,中斷的來源除了來自於硬體自身的NMI中斷和來自於軟體的INT n指令造成的軟體中斷之外,還有來自於外部硬體設備的中斷,這些中斷是可禁止的。這些中斷也都通過可程式中斷控制器進行控制,並傳遞給CPU。

總述

前言

8259A晶片是一個中斷管理晶片,中斷的來源除了來自於硬體自身的NMI中斷和來自於軟體的INT n指令造成的軟體中斷之外,還有來自於外部硬體設備的中斷,這些中斷是可禁止的。這些中斷也都通過 PIC(Programmable Interrupt Controller)進行控制,並傳遞給CPU。

一個8259A晶片的可以接最多8箇中斷源,但由於可以將2個或多個8259A晶片級連(cascade),並且最多可以級連到9個,所以最多可以接64箇中斷源。如今絕大多數的PC都擁有兩個8259A,這樣 最多可以接收15箇中斷源。

通過8259A可以對單箇中斷源進行禁止。

在一個8259A晶片有如下幾個內部暫存器

Interrupt Mask Register (IMR)。

Interrupt Request Register (IRR)。

In Service Register (ISR)。

IMR被用作過濾被禁止的中斷,IRR被用作暫時放置未被進一步處理的Interrupt,當一個Interrupt正在被CPU處理時,此中斷被放置在ISR中。

除了這幾個暫存器之外,8259A還有一個單元叫做Priority Resolver,當多箇中斷同時發生時,Priority Resolver根據它們的優先權,將高優先權者優先傳遞給CPU。

8259A工作原理

8259A中斷控制器 8259A中斷控制器

當一個中斷請求從IR0到IR7中的某根線到達IMR時,IMR首先判斷此IR是否被禁止,如果被禁止,則此中斷請求被丟棄;否則,則將其放入IRR中。

在此中斷請求不能進行下一步處理之前,它一直被放在IRR中。一旦發現處理中斷的時機已到,Priority Resolver將從所有被放置於IRR中的中斷中挑選出一個優先權最高的中斷,將其傳遞給CPU去處理。IR號越低的中斷優先權別越高,比如IR0的優先權別是最高的。

8259A通過傳送一個INTR(Interrupt Request)信號給CPU,通知CPU有一個中斷到達。CPU收到這個信號後,會暫停執行下一條指令,然後傳送一個INTA(Interrupt Acknowledge)信號給8259A。8259A收到這個信號之後,馬上將ISR中對應此中斷請求的Bit設定,同時IRR中相應的bit會被reset。比如,如果當前的中斷請求是IR3的話,那么ISR中的bit-3就會被設定,IRR中IR3對應的bit就會被reset。這表示此中斷請求正在被CPU處理,而不是正在等待CPU處理。

隨後,CPU會再次傳送一個INTA信號給8259A,要求它告訴CPU此中斷請求的中斷向量是什麼,這是一個從0到255的一個數。8259A根據被設定的起始向量號(起始向量號通過中斷控制字ICW2被初始化)加上中斷請求號計算出中斷向量號,並將其放置在Data Bus上。比如被初始化的起始向量號為8,當前的中斷請求為IR3,則計算出的中斷向量為8+3=11。

CPU從Data Bus上得到這箇中斷向量之後,就去IDT中找到相應的中斷服務程式ISR,並調用它。如果8259A的End of Interrupt (EOI)通知被設定位人工模式,那么當ISR處理完該處理的事情之後,應該傳送一個EOI給8259A。

8259A得到EOI通知之後,ISR暫存器中對應於此中斷請求的Bit會被Reset。

如果8259A的End of Interrupt (EOI)通知被設定位自動模式,那么在第2個INTA信號收到後,8259A ISR暫存器中對應於此中斷請求的Bit就會被Reset。

在此期間,如果又有新的中斷請求到達,並被放置於IRR中,如果這些新的中斷請求中有比在ISR暫存中放置的所有中斷優先權別還高的話,那么這些高優先權別的中斷請求將會被馬上按照上述過程進行處理;否則,這些中斷將會被放在IRR中,直到ISR中高優先權別的中斷被處理結束,也就是說知道ISR暫存器中高優先權別的bit被Reset為止。

IRQ2/IRQ9 重定向

兼容性

為什麼要將IRQ2重定向到IRQ9上?這仍然是由於兼容性問題造成的。

早期的IBM PC/XT只有一個8259A,這樣就只能處理8種IRQ。但很快就發現這根本不能滿足需求。所以到了IBM PC/AT,又以級連的方式增加了一個8259A,這樣就可以多處理7種IRQ。原來的8259A被稱作Master PIC,新增的被稱作Slave PIC。但由於CPU只有1根中斷線,Slave PIC不得不級連在Master PIC上,占用了IRQ2,那么在IBM PC/XT上使用IRQ2的設備將無法再使用它;但新的系統又必須和原有系統保持兼容,怎么辦?

新增特性

由於新增加的Slave PIC在原有系統中不存在,所以,設計者從Slave PIC的IRQ中挑出IRQ9,要求軟體設計者將原來的IRQ2重定向到IRQ9上,也就是說IRQ9的中斷服務程式需要去掉用IRQ2的中斷服務程式。這樣,將原來接在IRQ2上的設備現在接在IRQ9上,在軟體上只需要增加IRQ9的中斷服務程式,由它調用IRQ2的中斷服務程式,就可以和原有系統保持兼容。而在當時,增加的IRQ9中斷服務程式是由PC開發商開發的BIOS提供的,不需要用戶進行另外設定。所以就從根本上保證了兼容。

8259A系列晶片的編程

每一個8259A晶片都有兩個I/O ports,程式設計師可以通過它們對8259A進行編程。

Master 8259A的連線埠地址是0x20,0x21;Slave 8259A的連線埠地址是0xA0,0xA1。

8259As的口令

8259A中斷控制器 8259A中斷控制器

程式設計師可以向8259A寫兩種命令字:

Initialization Command Word (ICW);這種命令字被用作對8259A晶片的初始化。

Operation Command Word (OCW):這種命令被用來向8259A發布命令,以對其進行控制。OCW可以在8259A被初始化之後的任何時候被使用。

8259A主片

下表的內容是Master 8259A的I/O連線埠地址,以及通過它們所能操作的暫存器。

Address Read/Write Function

0x20 Write Initialization Command Word 1 (ICW1)

Write Operation Command Word 2 (OCW2)

Write Operation Command Word 3 (OCW3)

Read Interrupt Request Register (IRR)

Read In-Service Register (ISR)

0x21 Write Initialization Command Word 2 (ICW2)

Write Initialization Command Word 3 (ICW3)

Write Initialization Command Word 4 (ICW4)

Read/Write Interrupt Mask Register (IMR)

Addresses/Registers for Master 8259A

8259A從片

下表的內容是Slave 8259A的I/O連線埠地址,以及通過它們所能操作的暫存器。

Address Read/Write Function

0xA0 Write Initialization Command Word 1 (ICW1)

Write Operation Command Word 2 (OCW2)

Write Operation Command Word 3 (OCW3)

Read Interrupt Request Register (IRR)

Read In-Service Register (ISR)

0xA1 Write Initialization Command Word 2 (ICW2)

Write Initialization Command Word 3 (ICW3)

Write Initialization Command Word 4 (ICW4)

Read/Write Interrupt Mask Register (IMR)

Addresses/Registers for Slave 8259A

由於8259A晶片不僅能夠用於IBM PC/X86,也可以被用作MCS-80/85,對於這兩者,在操作模式上有一些不一樣,對於某些暫存器的設定也有所不同。我們後面僅僅討論X86模式相關的內容。

初始化

初始化

當主機上電或復位之後,必須對兩個8259A都進行初始化。事實上,BIOS已經這么做了。但不幸的是,BIOS對其進行的初始化的結果並非我們所需要。比如,我們要開發保護模式下OS,我們要設定自己的IDT,那么我們就不能使用BIOS設定的IVT,而在對8259A初始化操作中,我們需要告訴8259A,其相關中斷請求的起始向量號,而我們對IDT的中斷向量布局和BIOS設定的IVT的中斷向量布局可以是不一樣的。這樣,我們也需要對兩個8259A進行初始化。

任何時候,只要向某一個8259A的第一個連線埠(0x20 for Master,and 0xA0 for Slave)寫入的命令的bit-4(從0算起)為1,那么這個8259A就認為這是一個ICW1;而一旦一個8259A收到一個ICW1,它就認為一個初始化序列開始了。你可以通過對照上邊的表和後面的表,第一連線埠可寫的有ICW1,OCW2和OCW3。而ICW1的bit-4要求必須是1,但OCW2和OCW3的bit-4要求必須是0。

協定

8259A的初始化流程協定如下圖所示,程式設計師對其進行初始化時必須遵守此協定:

ICW1

Bit(s) Function

7:5 Interrupt Vector Addresses for MCS-80/85 Mode.

4 Must be set to 1 for ICW1

3 1 Level Triggered Interrupts

0 Edge Triggered Interrupts

2 1 Call Address Interval of 4

0 Call Address Interval of 8

1 (SINGL) 1 Single PIC

0 Cascaded PICs

0 (IC4) 1 Will be Sending ICW4

0 Don't need ICW4

Initialization Command Word 1 (ICW1)

對於X86,bit-0必須被設定為1;由於當今的IBM PC上都有兩個級連的8259A,所以bit-1應該被設定為0;由於bit-2是為MCS-80/85服務的,我們將其設定為0;bit-3也設定為0;bit-4被要求必須設定為1;bit5:7是為MCS-80/85服務的,對於X86,應將全部將其設為0。

所以,在X86系統上,ICW1應該被設定為二進制00010001 = 0x11。

ICW2

Bit 80x86 Mode

7 I7

6 I6

5 I5

4 I4

3 I3

2 0

1 0

0 0

Initialization Command Word 2 (ICW2)

ICW2被用作指定本8259A中的中斷請求的起始中斷向量,bit0:3必須被設為0;所以,其起始中斷向量必須是8的倍數。比如,我們的OS的設計講來自於Master 8259A的8箇中斷請求放在IDT的第32 (從0開始計)個位置到第39個位置,則我們應該將ICW2設為0x20。

這樣,當將來此8259A上接收到一個IRQ時,其低3位會被自動填充為IRQ號。比如,其收到一個IRQ6,將6自動填充到後3位,則生成的向量號為0x26。8259A會在收到CPU發來的第二個INTA信號之後,將生成的向量號放到Data Bus上。

ICW3

Master 8259A和Slave 8259A有不同的ICW3格式。

Bit Function

7 IR7 is connected to a Slave

6 IR6 is connected to a Slave

5 IR5 is connected to a Slave

4 IR4 is connected to a Slave

3 IR3 is connected to a Slave

2 IR2 is connected to a Slave

1 IR1 is connected to a Slave

0 IR0 is connected to a Slave

Initialization Command Word 3 for Master 8259A (ICW3)

Slave 8259A被接在Master 8259A的那個IRQ上,則相應的位就被設定為1,其餘的位都被設定為0。在IBM PC上,Slave 8259A被接在Master 8259A的IRQ2上,則此ICW3的值應該被設定為二進制00000100 = 0x04。

Bit(s) Function

7 Reserved. Set to 0

6 Reserved. Set to 0

5 Reserved. Set to 0

4 Reserved. Set to 0

3 Reserved. Set to 0

2:0 Slave ID

000 Slave 0

001 Slave 1

010 Slave 2

011 Slave 3

100 Slave 4

101 Slave 5

110 Slave 6

111 Slave 7

Initialization Command Word 3 for Slaves (ICW3)

Slave 8259A的ICW3的bit3:7被保留,必須被設為0;而bit0:2被設定為此Slave 8259A被接在Master 8259A的哪個IRQ上。比如,在IBM PC上,Slave 8259A被接在Master 8259A的IRQ2上,則此ICW3應被設為0x02。

ICW4

Bit(s) Function

7 Reserved. Set to 0

6 Reserved. Set to 0

5 Reserved. Set to 0

4 1 Special Fully Nested Mode

0 Not Special Fully Nested Mode

3:2 0x Non - Buffered Mode

10 Buffered Mode - Slave

11 Buffered Mode - Master

1 1 Auto EOI

0 Normal EOI

0 1 8086/8080 Mode

0 MCS-80/85

Initialization Command Word 4 (ICW4)

在80x86模式下,我們不需要使用8259A的特殊功能,因此我們將bit1:4都設為0,這意味使用默認的Full Nested Mode,不使用Buffer,以及手動EOI模式;我們只需要將bit-0設為1,這也正是我們ICW0處提到的我們為什麼必須要ICW4的原因。所以ICW4的值應該被設為0x01。

所以我們可以用下列代碼初始化2個8259A晶片:

inline void init_8259a(void)

{

/* icw1 */

outb( 0x20,0x11 ); /* master port A */

outb( 0xA0,0x11 ); /* slave port A */

/* icw2 */

outb( 0x21,0x20 ); /* master offset of 0x20 in the IDT */

outb( 0xA1,0x28 ); /* slave offset of 0x28 in the IDT */

/* icw3 */

outb( 0x21,0x04 ); /* slaves attached to IR line 2 */

outb( 0xA1,0x02 ); /* this slave in IR line 2 of master */

/* icw4 */

outb( 0x21,0x01 ); /* set as master */

outb( 0xA1,0x01 ); /*set as slave */

}

操作

操作

一旦按照初始化協定初始化完成之後,程式設計師就可以在任何時候,以任何順序向8259A傳送操作控制字OCW了。

OCW1

Bit PIC 2 PIC 1

7 Mask IRQ15 Mask IRQ7

6 Mask IRQ14 Mask IRQ6

5 Mask IRQ13 Mask IRQ5

4 Mask IRQ12 Mask IRQ4

3 Mask IRQ11 Mask IRQ3

2 Mask IRQ10 Mask IRQ2

1 Mask IRQ9 Mask IRQ1

0 Mask IRQ8 Mask IRQ0

Operation Control Word 1 (OCW1)

OCW1是用來做中斷請求禁止用的操作控制字。如果你想禁止那個IRQ,只需要對照上表將相應的Bit置為1,然後傳送給相應的8259A就可以了。比如我想禁止IRQ10,我只需要將0x0A寫到連線埠0xA1。對應代碼如下:

outb(0x0A,0xA1);

OCW2

Bit(s) Function

7:5 000 Rotate in Auto EOI Mode (Clear)

001 Non Specific EOI

010 Reserved

011 Specific EOI

100 Rotate in Auto EOI Mode (Set)

101 Rotate on Non-Specific EOI

110 Set Priority Command (Use Bits 2:0)

111 Rotate on Specific EOI (Use Bits 2:0)

4 Must be set to 0

3 Must be set to 0

2:0 000 Act on IRQ 0 or 8

001 Act on IRQ 1 or 9

010 Act on IRQ 2 or 10

011 Act on IRQ 3 or 11

100 Act on IRQ 4 or 12

101 Act on IRQ 5 or 13

110 Act on IRQ 6 or 14

111 Act on IRQ 7 or 15

Operation Control Word 2 (OCW2)

通過將bit3:4設定為0,以說明這是一個OCW2。如果bit-6被設為1,則bit0:2有效,其操作則是面向某個IRQ的;否則將bit0:2設為0,其操作是面向整個8259A的所有IRQ的。我們一般只會用到No Specific EOI——因為我們在初始化8259A時,制定的EOI Mode為手動模式,所以當每次對應某個8259A晶片的IRQ的中斷服務程式ISR執行結束後,都需要向8259A傳送一個EOI,其對應的OCW2的值為0x20。需要注意的是,由於IBM PC有2個級連的8259A,所以我們每次必須分別給兩個都發一個。

比如下面示例代碼用來向兩個8259A晶片傳送EOI,它需要在針對來自於兩個8259A晶片的中斷的服務程式ISR末尾處被調用:

inline void send_eoi(void)

/* Send EOI to both master and slave */

outb( 0x20,0x20 ); /* master PIC */

outb( 0xA0,0x20 ); /* slave PIC */

OCW3

Bit(s) Function

7 Must be set to 0

6:5 00 Reserved

01 Reserved

10 Reset Special Mask

11 Set Special Mask

4 Must be set to 0

3 Must be set to 1

2 1 Poll Command

0 No Poll Command

1:0 00 Reserved

01 Reserved

10 Next Read Returns Interrupt Request Register

11 Next Read Returns In-Service Register

Operation Control Word 3 (OCW3)

通過將Bit-3設為1,Bit-4設為0,以讓8259A知道這是一個OCW3。OCW3中對我們最有意義的位是bit0:1,我們可以通過將bit-1設為1來通知8259A,下一個讀連線埠的動作將要讀取IRR或ISR暫存器的內容。

比如下面示例C++代碼用來讀取Master 8259A的IRR暫存器內容到__irr變數中:

void read_irr(unsigned char& __irr)

{

outb(0x02,0x20);

inb(&__irr,0x20);

}

Full Nested Mode

為了讓我們更加理解8259A的中斷控制機理,我們需要說明一下Full Nested Mode。在我們初始化時,只需要將ICW4的bit-4設為0,我們就選擇了Full Nested Mode。

Full Nested Mode其實就是實現按照中斷請求的優先權別進行搶斷處理的機制——如果當前一個IRQ正在被CPU處理,也就是說,當前CPU正在調用其中斷服務程式ISR;這時8259A又接到了新的IRQ,如果此IRQ的優先權大於正在處理的IRQ,那么,此IRQ就會被提交給CPU以優先處理;否則此IRQ則被放置在IRR中,直到所有的高優先權中斷被處理結束為止。

處理過程

其處理過程大致如下:

在ISR暫存器中有一個8-bit的位元組,範圍為bit[0,7];每一個bit對應一個IRQ(IRQ0-IRQ7對應bit[0,7])。當一個IRQ被提交給CPU之後(收到來自於CPU的第一個INTA信號之後),其對應的bit會被設定為1。比如IRQ6被提交給CPU之後,IS Register的bit-6會被設定為1。當此8259A收到一個EOI之後(對於手動模式,這意味著一個優先權別最高的中斷請求被處理結束),會將IS Register中被設定的最高優先權IRQ的對應的bit清為0。比如在收到一個EOI時,發現IS Register的bit-3,bit-5,bit-6被設定,那么被清除的則是bit-3(越小優先權別越高)。在清除優先權最高的bit之後,8259A會到IRR中察看是否有優先權別高於當前正在處理的IRQ中優先權別最高的IRQ,如果有,則將此IRQ提交給CPU處理,同時設定相應的bit。還以上面的例子為例,當bit-3被清除之後,如果發現在IRR中有一個IRQ4等待被處理,則將其提交給CPU,在收到來自於CPU的第一個INTA信號之後,則將IS Register的bit-4置為1。

在此過程中,如果8259A接到更高優先權別的IRQ,則將其立即提交給CPU。比如,當前正在處理的IRQ為IRQ3,IRQ5,那么IS Register中被設定的bit為bit-3,bit-5;如果此時接到一個IRQ1,則立即將其提交給CPU,在收到來自於CPU的第一個INTA信號之後,則將IS Register的bit-1置為1。

由此過程我們也可以看出,為了實現這種優先權機制,必須將EOI設為手動模式,也就是說必須將ICW4的bit-1設為0。因為,對於自動EOI模式,8259A會在收到來自於CPU的第2個INTA信號之後,就自動將IS Register中此IRQ對應的bit清0,而事實上,這個時候此IRQ對應的中斷服務程式還沒有被CPU調用,也就是說此IRQ還沒有被處理結束,而由於此IRQ對應的bit已經被清除,如果此IRQ是一個優先權很高的話,那么此IRQ的處理完全可以被一個優先權別更低的IRQ所中斷。這不是我們所需要的。

相關詞條

相關搜尋

熱門詞條

聯絡我們