找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 30119|回复: 9

[转载资料]PCI IRQ Routing Table Specification与相关资料

[复制链接]
发表于 2008-2-27 14:24:22 | 显示全部楼层 |阅读模式
自己比较懒,网络上的文章和资料有:. \) a/ R5 H, k
1、PCI IRQ Routing Table Specification (中文请参照《BIOS研发技术剖析》中的描述)
" _% U. m( x9 lmicrosoft: http://www.microsoft.com/whdc/archive/pciirq.mspx% u; `1 a0 u7 f8 n4 \8 i9 H1 ^

9 V: V" y0 ^5 ~* `8 [. f( ^2、PCI IRQ Routing on a Multiprocessor ACPI System
; H; r3 p6 g; `  M& c% amicrosoft: http://www.microsoft.com/taiwan/whdc/system/CEC/ACPI-MP.mspx
 楼主| 发表于 2008-2-27 14:27:02 | 显示全部楼层

I/O APIC演進

来自:http://www.four-stock.com/forum/ ... d=32&sid=JZS6Kb
  u; q+ j) g) G# F7 C' {% m1 y / g5 [$ l+ ~# z) w
作者: Titan    時間: 2007-10-26 17:51     標題: I/O APIC演進~~~~~~~ - n) ~8 d8 O2 [' V& s9 X
此作者为转载作者,见下面网友的更正。
0 c) q* z0 [& U: M: s, e7 r9 R1 s) x+ G. P
在x86歷史的演進中,有很多的BIOS工程師對於PCI IRQ Routing Table還是搞不清楚,我剛入行的時候也是一樣,對於這個東西一點概念都沒有,只知道是因為IRQ#不夠用,所以才需要去繞線(Routing)。
9 Y# c) W  X0 J; {! T3 [7 Z2 B& W6 c( o$ u7 v7 x
[為何要繞? 背景是什麼?], ^* `) {& ~. I' O/ w7 _6 }' v9 \. ~
依照我自己研究出來的歷史,我發現可能的原因是因為PCI設備越來越多,然後當時的中斷控制器是串聯的8259A,所以只有IRQ0~IRQ15可以用,且IRQ2已經連接 "僕8259" (第二顆中斷控制器),所以剩下來15支IRQ#可以用,但是又因為x86系統在早期的設計中,有些IRQ#已經分配給固定的設備使用,所以剩下來沒幾支可以用,可是設備又那麼多,所以如何去分配剩下來的IRQ就是大家討論的話題。) A4 X. F1 S+ O5 s0 k

  ]6 L  i9 J" V: ^$ w4 V[IRQ繞線的歷史發展]% E: ?  w8 P/ N' w: z
依照我查到的資料,早期的作業系統Windows 95年代左右,PCI設備要使用哪一支IRQ中斷線是靠PCI卡上面的"跳線"去控制,所以有可能會因為兩個PCI設備跳同一支"IRQ#"而造成衝突導致當機或是藍底白字。
* e0 t- ]+ g6 E2 b/ L- h後來改用BIOS Setup Menu內去控制,也就是可以進去BIOS設定畫面去設定IRQ分配。
8 }4 _1 O* r  X2 F3 @
4 y, |* h; X# D! h0 N1 ~$ A/ ^因此為了解決PCI設備越來越多,但是IRQ不夠用的情況,所以微軟找上的晶片廠商也就是Intel合作開發PIRQ Route Controller,簡單說就是微軟想在他的作業系統上面支援"共享IRQ中斷架構"的驅動程式,但是需要硬體配合,因此定義了PCI IRQ Routing Table來規範硬體線路要怎樣繞線,且需要BIOS支援哪些資訊。  {2 M1 Y7 l0 D% x( v
; [6 X  H! ?2 f* s: |
[為什麼是PCI設備而不是ISA設備?]. E7 q" |% |- Z+ n8 n
因為當時PCI Bus取代了傳統的周邊匯流排,所以PCI設備橫行,且設備需要服務就是透過中斷請求線IRQ#請求服務,對於OS端來說,這個服務就是驅動程式,至於CPU如何把控制權交給OS,則是靠IDT (interrupt Description Table),相關詳細資料請看Windows核心說明。
, o8 L8 x* H( d7 }- a# N* ]) N6 F: u: y- v9 j* ~5 R, K) I( |
[跟DOS有關嗎?]2 T6 A1 G4 w: z$ I- o
應該是無關,除非你在DOS下替你的PCI設備寫了一個驅動程式,或是你的PCI設備在DOS模式下要工作,不過應該也是沒啥機會這樣做吧,所以PIRQ Routing都是針對Windows作業系統而言,因為與設備驅動程式管理有關。: s+ W* ]1 h0 Z- e2 x# o

3 M/ \7 f* V. _! ~+ T: k[Windows 作業系統的改變]
8 D0 I! C* C( H8 I: N對於微軟自己定義的規範中,他最希望的就是能夠共享IRQ,所以在作業系統的改變就是要能分辨是哪個PCI Device透過IRQ發出請求,這是因為可能有好幾個PCI 設備都用同一支IRQ#中斷請求,所以OS 必須要能夠讓正確的驅動程式去服務發出中斷的設備,因此在撰寫OS 端的 Driver 時有了新的規範(針對共享IRQ的驅動程式有其規範)。: W& ^1 P2 ~( D/ g
2 K! ]# P1 O1 R; ]
[Chipset的改變], r! @3 T; a9 S, T% o/ h' C
起先為了微軟的規範,Inetl 在南橋ICH上面多了幾支接腳(PIRQA~PIRQD),這幾支接腳又有對應的暫存器可以組態他們,例如下面範例:
: i6 O! G' C) e* P, S, |# \
  j* z: f. O: _PIRQA Register 60h bit3:0 <--PIRQA那隻接腳的設定暫存器在LPC Reg60h,其中bit3:0定義如下
* Y" C4 _( m' q. r. j* v' l/ |+ B=================================================================================
' ]  q& f- V( A+ D5 Z% r0 mIRQ Routing — R/W. (ISA compatible.)4 H. G; k) j7 C) i. d/ t
Value IRQ # n* @$ x) I8 j, g+ X9 T
0000b Reserved
* a5 s/ Z$ I, v+ L2 g. R5 D0001b Reserved
* |+ W, f$ x) O- f: F& [5 s0010b Reserved
5 C  L0 K0 j$ `0 K' S0011b IRQ3
+ t+ P) `! X6 x! G* ]1 u' C' ~4 R2 Y0100b IRQ4
8 c& v. K$ E% o9 ~0101b IRQ5 # U$ Y6 U3 k, C
0110b IRQ6 8 g' n, K+ L# m- Z
0111b IRQ7
# z0 |4 N+ q  Z  {- [$ h$ A9 g...5 u3 O3 @8 f( x0 Y& B0 e8 x
由上面範例可以看出每支PIRQ接腳都可以用"軟體"設定的方式橋接到IRQ#的任何一支。1 q) J3 B! e% y# o2 u
也由於上面範例我們可以知道,OS 必須"先知道哪些IRQ可以被使用" 還有"哪些IRQ已經被使用",因為OS本身有自己配置IRQ#的演算方式,因此必須要先知道這些資訊,才有辦法去對PIRQ#繞線。+ H( K% L' L1 }2 w6 G5 D

+ _  ~" `0 K8 W  |& R, y+ o[BIOS的支援]! }/ k2 X, _! e& Q" @! n# ]
所以BIOS要提供"PIRQ Routing Table"給作業系統,然後OS就可以得到這些資訊,但是又因為OS版本不同(Win95/Win95/Win2000/WinXp or Acpi OS/non-ACPI OS..等分類),所以透過的傳遞管道也不同。
( d6 H" [! _2 P2 P" D/ `
# f4 Y; d; R' T, t9 |  C  V$ B[後來的演變]" c$ K2 P- ]! h9 K# r2 q' y
隨著PCI設備越來越多PIRQ只有4支接腳已經不夠用,所以後來擴充到8支,分別是PIRQA~PIRQH。
# O: l. U' o, y
; g9 C: ~/ Y- i9 G$ k0 |至今2007,OS 與 Intel 在這部份的演變也越來越複雜,因為後來的Intel 提出了新一代的中斷控制器APIC,所以在南橋ICH內就分成了兩種中斷控制器PIC與I/O APIC兩種,又因為OS演變成ACPI OS,所以原先PCI IRQ Routing Table Spec內所描述的方式就變成了ACPI Spec內的方式,簡單說就是BIOS傳遞PIRQ Routing方式也從Legacy OS方式演變成ACPI Mode方式(原本Table放在記憶體,現在改放在ASL Code)。
" |! M3 y- o& i$ n. l. G1 i; r: K' @& p( H7 w" {4 t
另外由於南橋ICH有兩種PIC,所以進入ACPI OS時是採用Legacy PIC mode 還是APIC mode 也會影響BIOS提供PIRQ Routing Table的方式,所以在ACPI Mode 底下又分成APIC Mode方式或是Non-APIC Mode(PIC Mode)方式。0 u/ Y) E& Y% _' N0 \  X
0 ]0 n. l. U! M. O; T% D8 u4 |, f
! i; H1 v; i& {6 [
% t! e# n" ?, O
[結論]
; q6 `5 \( G; j; OPIRQ#是南橋上面的接腳,連接到PCI 的INTA#~INTD#,原本INTA#~INTD#應該直接接到PIC上面的IRQ#接腳,但是因為IRQ#不夠用,所以微軟才與Intel合作,多做了幾支接腳出來,然後用軟體方式去配置這些多出來的接腳PIRQ#要繞線到哪個IRQ#,且作業系統的驅動程式可支援共享IRQ中斷,所以在Chipset 端把這種機制稱之為PIRQ Route Controller (具有PIRQ繞線功能的控制器,也就是某某一代的南橋開始把這個功能整合進去南橋晶片內)。
/ ^# }5 F/ D7 u- `  o) e! i6 ~  Y" O* M% U- {, b7 A
而BIOS所扮演的角色就是提供PIRQ Routing Table,這個Table的結構如同微軟的PCI IRQ Routing Table的規範,而當系統演變到ACPI 後,BIOS也改變了提供Table的方式,也就是改遵循ACPI Spec內的規範去提供這些資訊。
0 }" n3 Y' T# k- z/ ?1 o7 j( q, `" s
上述這些資訊只是我整理的筆記的一部分概要,詳細內容可以參考相關資料說明,畢竟我也是花了一個多星期的時間才整理出整個PIRQ的歷史,是對是錯我也不清楚,畢竟過去的架構我來不及參與,只能就我收集到的資料作一個描述,如有誤請先進指教。
3 N6 E( K9 F( k; U9 z
! j6 q' H) i( @$ Y& w* C' a$ C4 k* L4 e! c* u$ V4 C; W
6 b& v) n5 d# p% T
[後記]  |' X8 j+ h" H/ p
1)當ACPI OS 系統處在APIC Mode的時候,PIRQA~PIRQH會直接對應在APIC 的IRQ16~IRQ23而不需要繞線。
9 |0 A1 J, T7 b( q1 L4 o  g2)APIC 目前可提供的中斷請求線有 IRQ0~IRQ255 ,目前只使用IRQ0~IRQ23
; X. ~: C% m8 Z4 q2 r6 |7 V3)APIC 前面的IRQ0#~IRQ15對應到PIC的IRQ0~IRQ15# C1 r2 a; Y% {' n& s  \
4)PIRQ Routing 是指: IRQ不夠用才需要透過PIRQ Routing Controller繞線,所以只針對PIC,而APIC模式則不需要繞線。
& p& N' _- Q7 N4)APIC Mode只需要描述哪些PCI Device共用了哪些PIRQ線。
5 D3 W) H9 ?; M% P; J* w9 f, t5)non-APIC mode則需要描述哪些PIC的IRQ#可以被使用,描述的內容如同PCI IRQ Routing Table,差別在於用ASL Code描述
& g3 C( k: L' Y5 Z/ f) |0 `6)APIC有分成Local APIC與I/O APIC,這邊所提到的都是指I/O APIC。' F$ U. u8 _" x

  V) t1 }- \" N[Reference], E  _2 E: }7 H6 x/ b) [, O" Y
http://www.microsoft.com/whdc/archive/pciirq.mspx) w: q3 I6 `; U  O# A
http://www.microsoft.com/taiwan/whdc/system/CEC/ACPI-MP.mspx
回复

使用道具 举报

 楼主| 发表于 2008-2-27 14:35:05 | 显示全部楼层

从IRQ到IRQL(APIC版)

来自:http://www.nsfocus.net/index.php ... o=view&mid=2534) v% q+ t5 k2 v7 Z2 J$ y
8 U0 {( i# S5 y2 P$ A4 U6 \  P
从IRQ到IRQL(APIC版)/ f$ i. I# O' q3 U& T6 s  u; d  p
1 g  l( S" U) |$ }, H
作者:SoBeIt- f" ?* W! [3 R7 d
出处:https://www.xfocus.net/bbs/index.php?act=ST&f=2&t=45502- L1 Y! f! }# {3 b/ N. `* p* }, Y
日期:2005-02-04
9 ]9 v: \' K# T7 v, [) x8 Y$ x2 S( M8 E+ x; q
事实上,老久的PIC在很早以前就被淘汰了,取而代之的是APIC。由于APIC可以兼容PIC,所以在很多单处理器系统上我们看到的PIC实际是APIC的兼容PIC模式。APIC主要应用于多处理器操作系统,是为了解决IRQ太少和处理器间中断而产生的,当然,单处理器操作系统也可以使用APIC(不是模拟PIC)。APIC的HAL和PIC的HAL有很大的不同,很突出的一个特点就是APIC的HAL不用再象PIC的HAL那样虚拟一个中断控制器,IRQL的概念已经可以通过中断向量的形式被APIC支持。事实上,因为被APIC所支持,所以在APIC HAL里IRQL的实现比PIC HAL那样虚拟一个中断控制器要简单得多了。
1 f% j# d5 |' |0 ]1 F6 e8 T& S" {- c# H' J9 v& n
    现在来简单介绍一下APIC的结构(关于APIC详细的描述请参考《IA-32 Inel Architecture Software Developer's Manual Volume 3 Chapter 8》)。整个APIC系统由本地APIC、IO APIC和APIC串行总线组成(在Pentium 4和Xeon以后,APIC总线放到了系统总线中)组成。每个处理器中集成了一个本地APIC,而IO APIC是系统芯片组中一部分,APIC总线负责连接IO APIC和各个本地APIC。本地APIC接收该处理器产生的本地中断比如时钟中断,以及由该处理器产生的处理器间中断,并从APIC串行总线接收来自IO APIC的消息;IO APIC负责接收所有外部的硬件中断,并翻译成消息选择发给接收中断的处理器,以及从本地APIC接收处理器间中断消息。% Y' K4 D5 A: U; b
1 U- I& x$ t0 K4 y# p3 @5 I
    和PIC一样,控制本地APIC和IO APIC的方法是通过读写该单元中的相关寄存器。不过和PIC不一样的是,Intel把本地APIC和IO APIC的寄存器都映射到了物理地址空间,本地APIC默认映射到物理地址0xffe00000,IO APIC默认映射到物理地址0xfec00000。windows HAL再进一步把本地APIC映射到虚拟地址0xfffe0000,把IO APIC映射到虚拟地址0xffd06000,也就是说对该地址的读写实际就是对寄存器的读写,本地APIC里几个重要的寄存有EOI寄存器,任务优先级寄存器(TPR),处理器优先级寄存器(PPR),中断命令寄存器(ICR,64位),中断请求寄存器(IRR,256位,对应每个向量一位),中断在服务寄存器(ISR,256位)等。IO APIC里几个重要的寄存器有版本寄存器,I/O寄存器选择寄存器、I/O窗口寄存器(用要访问的I/O APIC寄存器的索引设置地址I/O寄存器选择寄存器,此时访问I/O窗口寄存器就是访问被选定的寄存器)还有很重要的是一个IO重定向表,每一个表项是一个64位寄存器,包括向量和目标模式、传输模式等相关位,每一个表项连接一条IRQ线,表项的数目随处理器的版本而不一样,在Pentium 4上为24个表项。表项的数目保存在IO APIC版本寄存器的[16:23]位。APIC系统支持255个中断向量,但Intel保留了0-15向量,可用的向量是16-255。并引进一个概念叫做任务优先级=中断向量/16,因为保留了16个向量,所以可用的优先级是2-15。当用一个指定的优先级设置本地APIC中的任务优先级寄存器TPR后,所有优先级低于TPR中优先级的中断都被屏蔽,是不是很象IRQL的机制?事实上,APIC HAL里的IRQL机制也就是靠着这个任务优先级寄存器得以实现。同一个任务优先级包括了16个中断向量,可以进一步细粒度地区分中断的优先级。
( Z6 f# a) n' V  ]& f2 ~$ ]
& m# C( M! N; j& b: i8 m    在HAL里虽然HalBeginSystemInterrupt仍然是IRQL机制的发动引擎,但是因为有APIC的支持,它和其它共同实现IRQL的函数要比PIC HAL里对应的函数功能简单得多。HalBeginSystemInterrupt通过用IRQL做索引在HalpIRQLtoTPR数组中获取该IRQL对应的任务优先级,用该优先级设置任务优先级寄存器TPR,并把TPR中原先的任务优先级/16做为索引在HalpVectorToIRQL数组中获取对应的原先的IRQL然后返回。若IRQL是从低于DISPATCH_LEVEL提升到高于DISPATCH_LEVEL,还需要设置KPCR+0x95(0xffdff095)为DISPATCH_LEVEL(0x2),表示是从DISPATCH_LEVEL以下的级别提升IRQL。HalEndSystemInterrupt向本地APIC的EOI寄存发送0,表示中断结束,可以接收新中断。并还要判断要降到的IRQL是否小于DISPATCH_LEVEL,若小于则进一步判断KPCR+0x96(0xffdff096)是否置位,若置位则表示有DPC中断在等待(在IRQL高于DISPATCH_LEVEL被引发,然后等待直到IRQL降到低于DISPATCH_LEVEL),则将KPCR+0x95和KPCR+0x96清0后调用KiDispatchInterrupt响应DPC软中断。否则做的工作就是和HalBeginSystemInterrupt一样的过程:把要降到的IRQL转换成任务优先级设置TRP,并把久的任务优先级转成IRQL返回。KfRaiseIrql、KfLowerIrql之类的函数也是这么一回事,把当前IRQL转成任务优先级修改TPR,并把原先TPR的值转成原先的IRQL并返回。而现在软中断的产生也有了APIC支持,APIC通过产生一个发向自己的处理器间中断,就可以产生一个软中断,因为可以指定该中断的向量,所以软中断就可以区分优先级别,如APC_LEVEL、DISPATCH_LEVEL。产生软中断的函数一样还是HalRequestSoftwareInterrupt,该函数会先判断KPCR+0x95是否和要产生的软中断IRQL一样,若是的话则置位KPCR+0x96并返回,表示现在IRQL大于DISPATCH_LEVEL所以不处理DPC中断。否则以要产生的软中断的IRQL为索引从HalpIRQLtoTPRHAL取出对应任务优先级,并或上0x4000,表示是发向自身的固定处理间中断,并用该值设置中断命令寄存器ICW的低32位,然后读取中断命令寄存器ICW的低32位是否为0x1000,确定中断消息已经发送后就返回,这时候软中断已经产生。值得注意的是APIC HAL里没有HalEndSoftwareInterrupt这个函数。HAL为软中断的IRQL提供了一个固定的中断向量:( D- g! O3 H' h- _
% U" x6 X/ F" U& R
#define ZERO_VECTOR             0x00    // IRQL 00
% h  C' ~2 P) k#define APC_VECTOR              0x3D    // IRQL 01
% G) p5 L7 U/ b9 @  W#define DPC_VECTOR              0x41    // IRQL 02" \: B5 r0 W7 a9 f8 A2 \$ \
#define APIC_GENERIC_VECTOR     0xC1    // IRQL 27
! L/ \5 O3 R: ?#define APIC_CLOCK_VECTOR       0xD1    // IRQL 28; D& y6 W2 c8 C
#define APIC_SYNCH_VECTOR       0xD1    // IRQL 28
' |* b4 p  }! ~3 |1 x  I8 Z! e#define APIC_IPI_VECTOR         0xE1    // IRQL 295 L& t$ X0 p$ ~9 P+ i" k
#define POWERFAIL_VECTOR        0xEF    // IRQL 308 T: w1 V- F+ W9 K/ _8 L
#define APIC_PROFILE_VECTOR     0xFD    // IRQL 316 J& j* g# @. P, g, Z- S( f$ `

! {$ L0 S+ Q8 d; ?: Y1 _4 z, D2 s6 `" j+ y. n; c
现在看一下一些重要的数据:
# s$ ~' E- G. ~1 q7 y" `1 R+ t% _$ C9 i" v" S/ n( ?% H
这是我写的代码输出的IO APIC重定向表内容:
# B& L$ Y; X9 j4 t/ {8 H, S/ m1 \' M! L$ i
Redirect Table Index:    0x17; S/ w( W! W. o# H$ i! o
Redirect Table[ 0]:      ff/ k: S" v! U, {0 x+ ]
Redirect Table[ 1]:      b31 ~- D/ L1 L: A) J( ?2 R
Redirect Table[ 2]:      ff
, l3 {$ ~1 i$ F) y; lRedirect Table[ 3]:      51
# p4 F2 I9 ^& j$ T1 zRedirect Table[ 4]:      ff2 f9 E9 |4 y" j$ x8 x+ s) \, ^  d  M
Redirect Table[ 5]:      ff% I) j3 g, P+ L/ b6 R$ r
Redirect Table[ 6]:      62
3 R( m) j( @/ M6 G/ C5 x; LRedirect Table[ 7]:      ff
$ k( T. f4 o; k" {* P0 y4 C% wRedirect Table[ 8]:      d1: z' J7 U. c1 O2 S; ^
Redirect Table[ 9]:      b1
$ R; {; f* f# n  k+ O" pRedirect Table[ a]:      ff  S9 t. S6 n& o" p$ B4 A" E
Redirect Table[ b]:      ff
) b3 K; f! t! @, K& QRedirect Table[ c]:      52; ~' P+ X+ a( V
Redirect Table[ d]:      ff6 B7 ~# S6 W3 B9 i6 g
Redirect Table[ e]:      ff
! Y; J4 H4 T7 z- E1 |5 J: xRedirect Table[ f]:      92
8 y/ @9 Z# u) JRedirect Table[10]:      ff
# W/ U, q1 ]$ W8 |  [; ^( c5 ?3 MRedirect Table[11]:      a3
# }4 \4 w$ v' Q' U; V: {8 N+ Q: MRedirect Table[12]:      83
5 g( j, g' p/ H2 X8 H' B* dRedirect Table[13]:      93
1 g6 }# f' l+ U3 H5 j; g+ u) ZRedirect Table[14]:      ff3 q7 o; k! {9 `- |* `" k) W: F
Redirect Table[15]:      ff
, u* A% t  B. g6 p1 IRedirect Table[16]:      ff
; B  K" Q" U* q. D/ L9 BRedirect Table[17]:      ff" Q) V4 ]/ ]/ T9 {0 ?

& D+ C. p2 @8 o0 T, D这是IDT表中被注册的向量:
, t* S: M8 h8 a; ?+ E  H1 E/ w$ M/ L7 U5 M& b; ^2 h
1f: 80064908 (hal!HalpApicSpuriousService)
, E. V* N! {  c0 u# h, ]37: 800640b8 (hal!PicSpuriousService37)2 c) p2 y: J) T. D% V6 i3 L
3d: 80065254 (hal!HalpApcInterrupt)
6 d. z. P0 u; ?) G& H( Q" g; ^41: 800650c8 (hal!HalpDispatchInterrupt)
5 R3 R; D1 y4 Y1 u9 }50: 80064190 (hal!HalpApicRebootService)
, p, `8 e: ~8 H' F9 A0 R1 k51: 817f59e4
7 O- P9 k' \, N" H(Vector:51,Irql:4,SyncIrql:4,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:serial!SerialCIsrSw(f3c607c7))! E4 v4 b% G% s$ S% O6 u- O
52: 817f5044 ; t0 r  v0 B! v- O, N
(Vector:52,Irql:4,SyncIrql:a,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:i8042prt!I8042MouseInterruptService(f3c57a2c))
) B# o+ B. P3 O+ s+ S$ y  o83: 817d2d44
! Q& _3 U& E5 @0 U9 F(Vector:83,Irql:7,SyncIrql:7,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:NDIS!ndisMIsr(bff1b794))
) a7 H* u' d! ?8 ~) G: \92: 81821384 + T- r$ ]. o3 p
(Vector:92,Irql:8,SyncIrql:8,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:atapi!ScsiPortInterrupt(bff892be))
4 k8 ^: S( [" u* d  d- z: I93: 8185ed64 ' q2 G* ?3 }; s/ C3 f
(Vector:93,Irql:8,SyncIrql:8,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:uhcd!UHCD_InterruptService(f3f0253e))' ^, T6 [. h( `
a3: 8186cdc4
$ d/ W7 `+ O) _7 d2 O, c" j. V3 U% M(Vector:a3,Irql:9,SyncIrql:9,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:SCSIPORT!ScsiPortInterrupt(bff719f0))" o9 k6 l+ g* x
b1: 818902e4
, H' o) @& Z+ v(Vector:b1,Irql:a,SyncIrql:a,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:ACPI!ACPIInterruptServiceRoutine(bffe14b4))! t8 u( K: g# n
b3: 81881664 # L$ d( t" {% ]" U5 t) t
(Vector:b3,Irql:a,SyncIrql:a,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:i8042prt!I8042KeyboardInterruptService(f3c51918)): g6 p$ \" ^+ O" Y
c1: 800642fc (hal!HalpBroadcastCallService)4 v( ?+ Z. x6 o$ X3 D
d1: 80063964 (hal!HalpClockInterrupt)
3 g1 n0 S# ^( R3 D7 r% re1: 80064858 (hal!HalpIpiHandler)6 m$ A, P; ^" f1 ^- R* ^% M
e3: 800645d4 (hal!HalpLocalApicErrorService)
. p$ u: P# @9 t! B5 m* Jfd: 80064d64 (hal!HalpProfileInterrupt)& c# Z. o/ Y4 Y: a, e
fe: 80064eec (hal!HalpPerfInterrupt)6 m3 c0 G" B& |  ~& f! q6 g, K& \
+ I9 @5 l$ `$ ?/ ?' e: m; ~
象a3、b1这类输出内容很多的是被硬件注册的中断向量,而象d1、e3这种输出内容少的是注册为了的HAL内部使用的中断向量和本地APIC中断向量$ I. `4 R3 ^8 ~% G2 T. C
3 v3 H7 _0 v2 m( b
这是几个重要的数组:( A: q! f$ K, X# Z' ~. o' }

9 D! H9 f9 ~% d; O& G6 WHalVectorToIrql(这个数组是以向量除于16做索引):
: ^! v0 e+ r% J8006a304  00 ff ff 01 02 04 05 06-07 08 09 0a 1b 1c 1d 1e6 |. v9 x1 D2 e$ ?

- n# o; A9 B) m' n5 k# gHalpIRQLtoTPR:+ @" s2 j7 D0 c- P4 ]
8006a1e4  00 3d 41 41 51 61 71 81-91 a1 b1 b1 b1 b1 b1 b1
1 k+ o' [. F& f+ |; c8006a1f4  b1 b1 b1 b1 b1 b1 b1 b1-b1 b1 b1 c1 d1 e1 ef ff
( v* E( c9 v3 z( N
5 D7 i6 ~9 U0 N9 m* i9 PHalpINTItoVector:0 e7 S: W/ e$ S, b) `# V; K' t
8006ada0  00 b3 61 51 a2 b2 62 91-a1 b1 71 81 52 82 72 92
$ D0 g' U" S9 z% u# Z$ k8006adb0  00 a3 83 93 00 00 00 00-00 00 00 00 00 00 00 00
" u8 u! t' W5 c) n) I% j. D
- E8 {9 P- |5 B" q9 ~$ G8 ?' pHalVectorToINTI:
  K* J5 U" \& N) q2 I+ x" C8006a204  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
/ \1 m! ~2 B1 w  q8006a214  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
, D+ I- ]- |/ |: w2 V! F+ S" d8006a224  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff+ a( ^3 l9 S3 U
8006a234  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff" }7 A9 B- E. m2 {  N- _. T2 i
8006a244  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
: k' ?: E/ y9 j1 i% i4 h8006a254  ff 03 0c ff ff ff ff ff-ff ff ff ff ff ff ff ff8 F; V8 z) w/ X( h
8006a264  ff 02 06 ff ff ff ff ff-ff ff ff ff ff ff ff ff
, @: Y0 K" X0 \' K8006a274  ff 0a 0e ff ff ff ff ff-ff ff ff ff ff ff ff ff
6 e0 Y( [3 M% S% N7 v" P8006a284  ff 0b 0d 12 ff ff ff ff-ff ff ff ff ff ff ff ff/ Y1 V. l/ V# o! S5 Q8 H
8006a294  ff 07 0f 13 ff ff ff ff-ff ff ff ff ff ff ff ff
8 x3 e5 U5 q3 o  q- L/ d8006a2a4  ff 08 04 11 ff ff ff ff-ff ff ff ff ff ff ff ff
) O+ _- M4 l% S: x4 X4 B  W8006a2b4  ff 09 05 01 ff ff ff ff-ff ff ff ff ff ff ff ff$ {* K1 D/ V5 ^* v
8006a2c4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
! Z5 w5 l/ h2 n7 G* M2 k" }. [' p$ v8006a2d4  ff 08 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
3 }; p& z( J' f4 q3 K( I5 u$ y/ U# M8006a2e4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff0 N! p% K( P: g" ]$ V5 s
8006a2f4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff   - n' G, i: L  I# b  r0 \

0 d' D6 N7 W1 G0 Z
* W2 j/ i; ~6 w5 K. ~8 R, {vBucket:
/ O% H3 G4 y- r, m. U: O7 ?8006ae30  02 02 02 03 03 03 03
1 k  W: l3 R! N# g
, i; W% f$ ~2 r& e" i' G    举个例子来说明一下,在我虚拟机里SCSI Controller的IRQ是17(注意,已经大于16了),到重定向表中查找第17项,得到中断向量为0xa3,再看IDT,0xa3对应处理例程是SCSIPORT!ScsiPortInterrupt。
  S; u8 {0 E( N* E: J2 }$ U2 ?
$ N# b, F+ }  F4 x6 I( |7 n) x    vBucket数组干啥用的?它就是用来分配新的向量。分配算法很简单,当要分配一个新的向量时,就在vBucket数组从右到左搜索最小的一个数i,该数对应在vBucket中索引为Index,新向量为(0x50+Index*16+i+1),新向量对应的IRQL为(4+i+1),同时会把vBucket中这个i加1,i不等大于16。象给出的这个vBucket,下一次计算时i=2, index=2。不过这些用于硬件的向量在IO系统初始化时调用HalpGetSystemInterruptVector分配好了,然后通过IoConnectInterrupt把IDT中注册的向量位置的例程注册为中断处理程序。这里并不是每个注册的向量都会对应中断处理程序,象上面给出的例子中,0xa1、0xa2、0xb1等向量就没有对应。
( K  r3 {7 U- p
# r7 J. P* `* C$ N. h1 K  J    IRQL机制为内核同步提供了很大的便利,既对驱动开发者隐藏了底层中断机制,也方便了驱动开发者的内核同步。LINUX从2.5内核开始引进的软中断和任务队列等机制,很大程度上也来自windows这套机制的借鉴。, \: J: G2 v$ u

8 T$ N/ W5 Q, w" {. F    终于考完试,解放了,呵呵。这个东西其实还有很多可写的,只是没空再深入去分析了。在未来的64位系统里,APIC这种基于中断引脚的机制很快也要被SAPIC这种基于消息的更强大的机制所取代
回复

使用道具 举报

发表于 2008-3-13 09:04:14 | 显示全部楼层
I/O APIC演進' F+ v/ g4 h+ I! \9 E: Z! i- q# s6 i
来自:http://www.four-stock.com/forum/ ... d=32&sid=JZS6Kb
3 D% K6 d% K( ]1 q8 B% @9 L: s8 q3 u& E( a& k
作者: Titan    時間: 2007-10-26 17:51     標題: I/O APIC演進~~~~~~~
: _! t: E3 }* c. g2 L3 e! E; i8 B( ~6 W' U
8 _  I8 z. ^) m
訂正一下..作者不是他..是下面的作者...
2 V! [% x% k5 F. ghttp://biosengineer.blogspot.com/
回复

使用道具 举报

 楼主| 发表于 2008-3-13 09:07:59 | 显示全部楼层
网上搜集,证明转载过程中,有人不厚道,导致一错百错。
回复

使用道具 举报

发表于 2008-11-25 16:35:44 | 显示全部楼层
LZ很厉害,还帖子!支持。
( L; s4 ^) p( _  q) T希望LZ继续给我们带来有关BIOS的好东西。
回复

使用道具 举报

发表于 2008-11-26 21:16:18 | 显示全部楼层
请问楼主,对于PCI IRQ部分,PIC和APIC是如何判断规范的哦?无论什么情况下(DOS,APM系统,ACPI系统),IRQ0-15就是PIC,15-23就是APIC吗?我们在设备管理器里看到的IRQ共享,应该如何解释呢?
回复

使用道具 举报

发表于 2008-11-27 11:15:34 | 显示全部楼层
PIC or ACPI is decide by OS , OS will use an APCI methord _PIC to inform ASL code which mode it use
7 x! [3 p  @) |5 I) f  W$ R3 q$ t**************************************************
4 w+ J; }) G% N# ~Method(\_PIC,1)# M9 N. i- g3 D% |1 u
  {
) Q) I% W6 H& K6 w# p          Store(Arg0,PICM)0 B  X  R$ [7 C
  }8 i8 r, T% o1 N- C0 W5 l8 V
**************************************************
6 k% h6 S4 v8 ]
! d+ R/ u% b; i( cAnd in _PRT methord , it will return PIC or APIC mode routing table
2 M! j3 q/ g- E. c1 O% {
! B- p" i2 r" n) e- l' L***********************************************2 }8 v3 a& R1 \1 N9 V& p
Method(_PRT,0) {
/ z; J9 g* y) O) vIf(PICM) { Return(AR04) }// APIC mode
% }" N  f$ h: q' [, SReturn (PR04) // PIC Mode; ^3 v, Y! W1 X: m" @/ z) q
} // end _PRT) Z' N- T/ C- W4 |! ^' }; L
**********************************************
回复

使用道具 举报

发表于 2008-12-2 13:28:20 | 显示全部楼层

回复 7# 的帖子

IRQ0-15就是PIC,15-23就是APIC吗?9 F/ ?$ j2 R% p
不是.
3 F# Q: V. ~) Q2 e3 p9 d这个看南桥的做法,Intel上面貌似是这样的,当nVidia就不一定了.4 @6 y4 y/ ]" [$ V3 p$ Y

, a1 V9 F: f$ G% q我们在设备管理器里看到的IRQ共享,应该如何解释呢?
4 |7 `6 \, s+ Y/ G7 JAPIC里面是可以共享IRQ的,你看到了,说明你的系统是使用APIC在.
回复

使用道具 举报

发表于 2010-6-10 13:14:31 | 显示全部楼层
太感谢各位的无私奉献!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2024-5-15 10:24 , Processed in 0.074013 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表