8259A中斷控制器

8259A中斷控制器

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

基本介紹

  • 中文名:8259A中斷控制器
  • 兼容性:PC/XT
  • 工作原理:IMR
  • 傳遞CPU
總述,前言,8259A工作原理,IRQ2/IRQ9 重定向,兼容性,新增特性,8259A系列晶片的編程,8259As的口令,8259A主片,8259A從片,初始化,初始化,協定,操作,操作,Full Nested Mode,處理過程,

總述

前言

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工作原理

當一個中斷請求從IR0到IR7中的某根線到達IMR時,IMR首先判斷此IR是否被禁止,如果被禁止,則此中斷請求被丟棄;否則,則將其放入IRR中。
8259A中斷控制器
在此中斷請求不能進行下一步處理之前,它一直被放在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中斷控制器
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所中斷。這不是我們所需要的。

相關詞條

熱門詞條

聯絡我們