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

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

[复制链接]
发表于 2008-2-27 14:24:22 | 显示全部楼层 |阅读模式
自己比较懒,网络上的文章和资料有:
7 n% F7 x8 z* ]. k1、PCI IRQ Routing Table Specification (中文请参照《BIOS研发技术剖析》中的描述)5 S' N" Z1 w0 I+ U$ a% X/ s
microsoft: http://www.microsoft.com/whdc/archive/pciirq.mspx
$ {5 W/ g) l' F0 A8 @- W/ u  h, l- z* K0 }* p0 v: o
2、PCI IRQ Routing on a Multiprocessor ACPI System# V& K" a5 P- Z" y2 z  Q2 y& x9 s
microsoft: 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
" l* v/ r1 E" B& g- ^9 m) x6 w
) z. n! a2 e1 E4 W4 [0 Z  v作者: Titan    時間: 2007-10-26 17:51     標題: I/O APIC演進~~~~~~~
& f% O; c' q9 [5 w! O: Q- D* f此作者为转载作者,见下面网友的更正。
  d8 d3 i0 B* f4 h; ~/ W3 C1 i: n# X+ v& a( I
在x86歷史的演進中,有很多的BIOS工程師對於PCI IRQ Routing Table還是搞不清楚,我剛入行的時候也是一樣,對於這個東西一點概念都沒有,只知道是因為IRQ#不夠用,所以才需要去繞線(Routing)。
  A0 Q% g' Z$ d, w: ?- N5 m! |
4 G/ z. ~, o4 Z4 r% p5 t[為何要繞? 背景是什麼?]. W$ _) [/ c3 B
依照我自己研究出來的歷史,我發現可能的原因是因為PCI設備越來越多,然後當時的中斷控制器是串聯的8259A,所以只有IRQ0~IRQ15可以用,且IRQ2已經連接 "僕8259" (第二顆中斷控制器),所以剩下來15支IRQ#可以用,但是又因為x86系統在早期的設計中,有些IRQ#已經分配給固定的設備使用,所以剩下來沒幾支可以用,可是設備又那麼多,所以如何去分配剩下來的IRQ就是大家討論的話題。/ J" |' b3 a8 p* m
% p, W. X7 T1 b# |7 ]; c1 P
[IRQ繞線的歷史發展]6 M2 u- D* k, E9 Z2 S
依照我查到的資料,早期的作業系統Windows 95年代左右,PCI設備要使用哪一支IRQ中斷線是靠PCI卡上面的"跳線"去控制,所以有可能會因為兩個PCI設備跳同一支"IRQ#"而造成衝突導致當機或是藍底白字。
5 l! U/ Z  r& n4 ?5 m後來改用BIOS Setup Menu內去控制,也就是可以進去BIOS設定畫面去設定IRQ分配。
$ x$ Y( {  _0 ]# o
, L7 r0 q* G7 Y; R. [% K因此為了解決PCI設備越來越多,但是IRQ不夠用的情況,所以微軟找上的晶片廠商也就是Intel合作開發PIRQ Route Controller,簡單說就是微軟想在他的作業系統上面支援"共享IRQ中斷架構"的驅動程式,但是需要硬體配合,因此定義了PCI IRQ Routing Table來規範硬體線路要怎樣繞線,且需要BIOS支援哪些資訊。) @1 B; C9 V0 [8 [/ H- E: B

8 q3 D" m" k- G* A[為什麼是PCI設備而不是ISA設備?]
6 U8 y  Y- c  g( u; C因為當時PCI Bus取代了傳統的周邊匯流排,所以PCI設備橫行,且設備需要服務就是透過中斷請求線IRQ#請求服務,對於OS端來說,這個服務就是驅動程式,至於CPU如何把控制權交給OS,則是靠IDT (interrupt Description Table),相關詳細資料請看Windows核心說明。  P* [; v) ~3 Z4 l" I4 s" G

9 c) ], D& Z! d8 ?[跟DOS有關嗎?]
! A$ O2 T! ~9 X1 H應該是無關,除非你在DOS下替你的PCI設備寫了一個驅動程式,或是你的PCI設備在DOS模式下要工作,不過應該也是沒啥機會這樣做吧,所以PIRQ Routing都是針對Windows作業系統而言,因為與設備驅動程式管理有關。
9 B2 R( p* ~* N+ f8 K) j+ h- o3 |$ F8 a
[Windows 作業系統的改變]9 H( M* t' p. Q2 e8 B* J$ W
對於微軟自己定義的規範中,他最希望的就是能夠共享IRQ,所以在作業系統的改變就是要能分辨是哪個PCI Device透過IRQ發出請求,這是因為可能有好幾個PCI 設備都用同一支IRQ#中斷請求,所以OS 必須要能夠讓正確的驅動程式去服務發出中斷的設備,因此在撰寫OS 端的 Driver 時有了新的規範(針對共享IRQ的驅動程式有其規範)。
/ z) _* j" W5 {# u4 _8 Z1 s" b+ }. m% s, y
[Chipset的改變]
0 S7 P2 D, M# p$ Y起先為了微軟的規範,Inetl 在南橋ICH上面多了幾支接腳(PIRQA~PIRQD),這幾支接腳又有對應的暫存器可以組態他們,例如下面範例:8 D3 F7 g7 y8 U% o5 E7 n* z

( g( ^% T, {, FPIRQA Register 60h bit3:0 <--PIRQA那隻接腳的設定暫存器在LPC Reg60h,其中bit3:0定義如下1 I7 \3 ^) v; m" e! U- E) `
=================================================================================+ S+ d9 u% ~; \' l
IRQ Routing — R/W. (ISA compatible.)1 b* Q5 L! z( A8 E
Value IRQ ! q6 `, p/ \. P" t* Z% O
0000b Reserved ) j8 X) f2 U! C* S
0001b Reserved $ L2 M9 z7 e) _5 \9 ?& ?
0010b Reserved
0 e8 D& R7 `5 b) I  Z0011b IRQ3
+ H+ o- @: x+ m0100b IRQ4 6 h( s! Y0 d; }3 o% @1 o* P6 w
0101b IRQ5 . p! k+ f% I6 Z5 a" _
0110b IRQ6 3 `5 r5 F3 f" r* E1 w
0111b IRQ7 5 F4 b  }/ D2 s+ N% t! r6 F1 F
...
* R! S/ A2 B+ n由上面範例可以看出每支PIRQ接腳都可以用"軟體"設定的方式橋接到IRQ#的任何一支。
3 G' c9 e1 `1 j9 Y& P也由於上面範例我們可以知道,OS 必須"先知道哪些IRQ可以被使用" 還有"哪些IRQ已經被使用",因為OS本身有自己配置IRQ#的演算方式,因此必須要先知道這些資訊,才有辦法去對PIRQ#繞線。
4 G% T5 z% k. N  Y# {: B3 L+ @0 N+ w8 \+ Q
[BIOS的支援]7 Y% I5 c6 J: [
所以BIOS要提供"PIRQ Routing Table"給作業系統,然後OS就可以得到這些資訊,但是又因為OS版本不同(Win95/Win95/Win2000/WinXp or Acpi OS/non-ACPI OS..等分類),所以透過的傳遞管道也不同。
- [7 `9 V3 H8 Q
3 a! l$ h6 o$ d; F. [[後來的演變]* }$ v0 x7 G+ u4 d
隨著PCI設備越來越多PIRQ只有4支接腳已經不夠用,所以後來擴充到8支,分別是PIRQA~PIRQH。
( l; q7 C: g% D9 i) N
( Z" S3 W) ~! i8 Q- S至今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)。8 E& P. L5 }5 F

( ]. a& n* [' u, O- N" A/ i另外由於南橋ICH有兩種PIC,所以進入ACPI OS時是採用Legacy PIC mode 還是APIC mode 也會影響BIOS提供PIRQ Routing Table的方式,所以在ACPI Mode 底下又分成APIC Mode方式或是Non-APIC Mode(PIC Mode)方式。% }) s5 o- z( z, u2 H
6 A/ G( R8 i2 f) J* b) C
, V7 |4 _' q& V$ I
; G. h- E' k  j0 U! O4 ?
[結論]
& |# U% F; p9 T% d9 d) h6 j( ^  K/ q8 w6 QPIRQ#是南橋上面的接腳,連接到PCI 的INTA#~INTD#,原本INTA#~INTD#應該直接接到PIC上面的IRQ#接腳,但是因為IRQ#不夠用,所以微軟才與Intel合作,多做了幾支接腳出來,然後用軟體方式去配置這些多出來的接腳PIRQ#要繞線到哪個IRQ#,且作業系統的驅動程式可支援共享IRQ中斷,所以在Chipset 端把這種機制稱之為PIRQ Route Controller (具有PIRQ繞線功能的控制器,也就是某某一代的南橋開始把這個功能整合進去南橋晶片內)。) s- K$ e) P/ E  O
8 x" [8 h' F( O6 A
而BIOS所扮演的角色就是提供PIRQ Routing Table,這個Table的結構如同微軟的PCI IRQ Routing Table的規範,而當系統演變到ACPI 後,BIOS也改變了提供Table的方式,也就是改遵循ACPI Spec內的規範去提供這些資訊。
' p7 l2 Y. B' X8 T! N5 a& Z' g- M2 J
上述這些資訊只是我整理的筆記的一部分概要,詳細內容可以參考相關資料說明,畢竟我也是花了一個多星期的時間才整理出整個PIRQ的歷史,是對是錯我也不清楚,畢竟過去的架構我來不及參與,只能就我收集到的資料作一個描述,如有誤請先進指教。
5 E. T" _$ ?# }# [8 m0 X
8 L" K1 Y+ i, i4 D. A$ k9 N* Y) T5 v, D/ l) q, B# a
4 X) m4 ]# p' e2 C. g
[後記]
5 R" ]7 I$ W5 D  }$ A1)當ACPI OS 系統處在APIC Mode的時候,PIRQA~PIRQH會直接對應在APIC 的IRQ16~IRQ23而不需要繞線。% @  \3 G8 P$ R; s( v8 L0 f( |
2)APIC 目前可提供的中斷請求線有 IRQ0~IRQ255 ,目前只使用IRQ0~IRQ23) f9 ^$ w/ S' P8 i9 t
3)APIC 前面的IRQ0#~IRQ15對應到PIC的IRQ0~IRQ152 R, a# R8 Y! Y; c1 H4 I, I
4)PIRQ Routing 是指: IRQ不夠用才需要透過PIRQ Routing Controller繞線,所以只針對PIC,而APIC模式則不需要繞線。
, ]* B: J: c  v0 E; k+ I+ n2 s4)APIC Mode只需要描述哪些PCI Device共用了哪些PIRQ線。
# m7 s1 `1 `7 m! N- z4 k; h5)non-APIC mode則需要描述哪些PIC的IRQ#可以被使用,描述的內容如同PCI IRQ Routing Table,差別在於用ASL Code描述
) e4 m) |1 U7 v; P6)APIC有分成Local APIC與I/O APIC,這邊所提到的都是指I/O APIC。
1 v5 Y; f4 c. g/ J, G
+ @& U  l+ T) Z/ L[Reference]
& J( Z9 `$ C& l9 c1 phttp://www.microsoft.com/whdc/archive/pciirq.mspx. U: k; z7 c% }1 Z7 R: J# w
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
2 m- K7 s  F9 N/ ?% t9 V# N, P
' f7 ^9 O$ x; ]1 [从IRQ到IRQL(APIC版)6 E, A; l; a. ?' \1 c0 L
0 d# U& c9 Q% G, {: B/ y. O0 l
作者:SoBeIt
# W" d4 y( _3 S. S+ ~出处:https://www.xfocus.net/bbs/index.php?act=ST&f=2&t=45502
* ?2 Q8 Y1 f  r日期:2005-02-04' v  Q  `# i9 X, O' T1 w
! ?' ^1 A: y9 H: p( F. d( T1 D
事实上,老久的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那样虚拟一个中断控制器要简单得多了。
/ T, }9 e; C( l( L+ d5 A0 w1 g  T$ t- P
    现在来简单介绍一下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接收处理器间中断消息。
/ k- l5 L1 m! s7 |) F7 j- o% V/ L/ R# A9 T8 q3 ]1 V
    和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个中断向量,可以进一步细粒度地区分中断的优先级。
# w4 m) M' O) P  Y* E
2 t: t" \) P0 D) C' e: M% G6 r) ^    在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提供了一个固定的中断向量:
% h4 _$ H. Y. U7 x2 i; y* W
( s1 k- E! I  J#define ZERO_VECTOR             0x00    // IRQL 00 + @7 {- S9 ^+ U: ^9 u) @+ H9 Y) l  ]
#define APC_VECTOR              0x3D    // IRQL 01
, t- Y' Y: D# }6 P/ d8 r. W+ x& q#define DPC_VECTOR              0x41    // IRQL 02
, U$ ~* \5 c5 a( T#define APIC_GENERIC_VECTOR     0xC1    // IRQL 279 ?; F+ x+ j, j% R( X3 T# X
#define APIC_CLOCK_VECTOR       0xD1    // IRQL 28* n) X: g# v  O0 P* x4 o
#define APIC_SYNCH_VECTOR       0xD1    // IRQL 28. h& k, l% m2 o% Q0 l
#define APIC_IPI_VECTOR         0xE1    // IRQL 29
) e0 I" A2 P' U/ M$ \#define POWERFAIL_VECTOR        0xEF    // IRQL 30
8 v; D* r# P2 g9 _2 y#define APIC_PROFILE_VECTOR     0xFD    // IRQL 31
7 j4 |4 Y3 s2 v1 o5 \! `1 h! I% E6 k' M0 |- p" n0 H. x
7 f9 G& O. ~, L2 G& \9 X( Q) ?
现在看一下一些重要的数据:
; b5 U! H3 e& n; A! O4 O# ]8 O
6 s5 k$ U- g- R2 |5 T这是我写的代码输出的IO APIC重定向表内容:$ h: ^+ _' `9 v. t5 o. O
& Q" o0 B5 ~9 F+ Q4 B" q: n7 C3 }
Redirect Table Index:    0x17. L2 L" o6 o( U" z& K+ Y  h! B
Redirect Table[ 0]:      ff
8 i" s0 n3 I" g( L: r: u! i3 m7 PRedirect Table[ 1]:      b3+ G' U) ?8 G0 F: S/ i: ]
Redirect Table[ 2]:      ff% E7 v2 D9 g' e, E  }5 B) w: n
Redirect Table[ 3]:      51# {0 i( c: @/ `1 ^
Redirect Table[ 4]:      ff7 M1 _7 d! `; {
Redirect Table[ 5]:      ff
( U" W: z8 v+ E  K/ R3 t9 r; iRedirect Table[ 6]:      62% R% {3 ]  q. Y9 r$ c
Redirect Table[ 7]:      ff
( a% M& u8 o% {! JRedirect Table[ 8]:      d13 {9 U) N2 q' P% v
Redirect Table[ 9]:      b1
, l% x# y* ?: u2 ~. D; _- }Redirect Table[ a]:      ff
! c2 e5 W, L, r, j6 K+ U3 gRedirect Table[ b]:      ff
% T- ~/ `$ [' g1 R: y. T4 NRedirect Table[ c]:      52; ]6 X$ l. T' W! E5 Y; @* @
Redirect Table[ d]:      ff6 K2 g3 J  y$ v4 m+ p9 Z
Redirect Table[ e]:      ff
' `0 S& x1 l0 |' B8 C& PRedirect Table[ f]:      92- t5 v( D% V9 A1 m: {, v
Redirect Table[10]:      ff
7 E9 b7 o9 C0 v6 j" O0 iRedirect Table[11]:      a3
# ~& [: n8 e7 t0 {0 KRedirect Table[12]:      83
; H. w6 z+ y/ Y3 G0 B1 Q$ R) {Redirect Table[13]:      93: y/ Q- C8 C' T+ J1 M
Redirect Table[14]:      ff6 o* G, b# ^; V7 u% V
Redirect Table[15]:      ff4 ?4 m$ d4 _; K
Redirect Table[16]:      ff
$ n6 p4 q, X- y1 [7 {% T" q/ w, TRedirect Table[17]:      ff- N, O0 r% R7 A7 l% Y7 u$ H, ?1 Z

4 G1 t7 _- P' G5 l& j这是IDT表中被注册的向量:5 V; s+ J# G- C; `' b
5 |5 K" G& P/ u: H
1f: 80064908 (hal!HalpApicSpuriousService)
* E5 K( f& K$ |. ]& V! |2 D37: 800640b8 (hal!PicSpuriousService37)
- @+ l- [" K/ V3 G3d: 80065254 (hal!HalpApcInterrupt)$ `4 _8 g) a2 z8 z& n7 O% Z
41: 800650c8 (hal!HalpDispatchInterrupt). ~3 Q, {' J) Q
50: 80064190 (hal!HalpApicRebootService)# C4 J$ u" H5 d7 x
51: 817f59e4' a/ N  T& O( k! t/ B5 G
(Vector:51,Irql:4,SyncIrql:4,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:serial!SerialCIsrSw(f3c607c7)): l+ ^: r% I- y2 M: t- O
52: 817f5044 1 `: t& ], i8 g  g7 u
(Vector:52,Irql:4,SyncIrql:a,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:i8042prt!I8042MouseInterruptService(f3c57a2c))
& h# n( E6 V. h% l# E% F. m2 }83: 817d2d44
# V' ?' f. T5 Z(Vector:83,Irql:7,SyncIrql:7,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:NDIS!ndisMIsr(bff1b794))
% s, w$ f" E( z! U7 ]# c$ R92: 81821384 ' n8 \+ w6 h6 t( E
(Vector:92,Irql:8,SyncIrql:8,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:atapi!ScsiPortInterrupt(bff892be))" p. R9 U& C3 v( L5 S8 n5 ~
93: 8185ed64
9 u! K6 m: n1 Y6 x8 ~$ w" E7 j. B(Vector:93,Irql:8,SyncIrql:8,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:uhcd!UHCD_InterruptService(f3f0253e))
) _  M* q# Y$ t; R( Ra3: 8186cdc4 ; L9 M( N3 h4 M/ l
(Vector:a3,Irql:9,SyncIrql:9,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:SCSIPORT!ScsiPortInterrupt(bff719f0))- y) D* U4 D+ m2 C9 D& z
b1: 818902e4
0 J2 x' H* V2 c; o(Vector:b1,Irql:a,SyncIrql:a,Connected:TRUE,No:0,ShareVector:TRUE,Mode:LevelSensitive,ISR:ACPI!ACPIInterruptServiceRoutine(bffe14b4))& X" x1 ~9 e( s. ~* S4 G
b3: 81881664
% r8 o, T# V  ~3 U6 u9 V( q; B0 E(Vector:b3,Irql:a,SyncIrql:a,Connected:TRUE,No:0,ShareVector:FALSE,Mode:Latched,ISR:i8042prt!I8042KeyboardInterruptService(f3c51918))
" P) x% P: l5 U, B0 S2 S! oc1: 800642fc (hal!HalpBroadcastCallService)
' R4 ~% H+ A3 s3 Xd1: 80063964 (hal!HalpClockInterrupt). @7 m, W. K( z) Z4 @1 {2 i
e1: 80064858 (hal!HalpIpiHandler)
/ l6 b6 K0 B4 m& Y4 v5 t9 W2 Ne3: 800645d4 (hal!HalpLocalApicErrorService)8 }; o: e7 I1 x! k2 ^5 N* \
fd: 80064d64 (hal!HalpProfileInterrupt)
$ e' q3 h# J" F) F5 u8 ^fe: 80064eec (hal!HalpPerfInterrupt)1 g1 Y: _$ u! a& R4 h
" R1 S6 @' R7 s
象a3、b1这类输出内容很多的是被硬件注册的中断向量,而象d1、e3这种输出内容少的是注册为了的HAL内部使用的中断向量和本地APIC中断向量: O/ B* ?2 ?" r( n

  B# `2 M6 ]  m. _这是几个重要的数组:5 B/ ^& i, M! S4 L" N9 T

2 s% s+ W- e0 @0 hHalVectorToIrql(这个数组是以向量除于16做索引):
2 T: v& y$ u' N: z' ~8006a304  00 ff ff 01 02 04 05 06-07 08 09 0a 1b 1c 1d 1e5 |: L. z0 Q4 I2 R$ W. s

' P, p* D8 Q1 g* V+ M- AHalpIRQLtoTPR:
+ [# ?0 D4 p! B0 B9 o7 P5 C1 ~8006a1e4  00 3d 41 41 51 61 71 81-91 a1 b1 b1 b1 b1 b1 b1
1 [$ e) a% D; t+ s7 j  {% c8006a1f4  b1 b1 b1 b1 b1 b1 b1 b1-b1 b1 b1 c1 d1 e1 ef ff
. g* C# S6 j2 l; {/ |8 I- n7 P8 q8 ]% c9 b* `( r: H8 }! w- l; y
HalpINTItoVector:
/ s& n2 d/ [% x4 {+ P8006ada0  00 b3 61 51 a2 b2 62 91-a1 b1 71 81 52 82 72 92
! a6 w, s: C4 Y- O0 A6 Z# ^" Y8006adb0  00 a3 83 93 00 00 00 00-00 00 00 00 00 00 00 00
% Q* k% b4 G; Q1 S) [# l' V% g( w( C/ {9 ^5 R8 k+ B7 E* s4 R
HalVectorToINTI:
% Y* `2 }* W9 G1 L" a8006a204  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
! s; m; q4 ~7 ]+ U8006a214  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff+ k+ E' H! ^/ L5 k- e
8006a224  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff( T9 _' s5 o5 q7 L, y
8006a234  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff1 B, x+ p" c* M- ~9 i% l
8006a244  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff# q7 e# n- X3 u8 U. y
8006a254  ff 03 0c ff ff ff ff ff-ff ff ff ff ff ff ff ff
* R1 A! t# u* y6 a8006a264  ff 02 06 ff ff ff ff ff-ff ff ff ff ff ff ff ff0 o4 Z( |+ g5 T  E
8006a274  ff 0a 0e ff ff ff ff ff-ff ff ff ff ff ff ff ff
  Y4 T  i( H: |, V/ K3 V2 A8006a284  ff 0b 0d 12 ff ff ff ff-ff ff ff ff ff ff ff ff3 F, `- y* X' l! k( f+ J  y; S6 t& ]
8006a294  ff 07 0f 13 ff ff ff ff-ff ff ff ff ff ff ff ff
- w$ N8 m! c4 I6 S4 l8006a2a4  ff 08 04 11 ff ff ff ff-ff ff ff ff ff ff ff ff
+ D5 ]% U  ?$ J/ Q! c4 J8006a2b4  ff 09 05 01 ff ff ff ff-ff ff ff ff ff ff ff ff& n6 R( ^3 R* a* Y9 a) L  B, d8 P
8006a2c4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
- i6 ?+ k% }" Y8 s1 X( Z8006a2d4  ff 08 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff
$ s: h+ N: K6 Y6 S0 x. g# f8 Q8006a2e4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff! K5 m# W: l" d) d  g. _. I
8006a2f4  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff   
, Z2 l& z1 I4 C/ |7 M& L: H5 z4 ~# H2 l5 Q% @- t$ P8 t* S
  Q/ q9 W7 z7 D- q& d$ u1 e
vBucket:8 A& N5 ^( @1 C7 M- h9 b
8006ae30  02 02 02 03 03 03 03( M. h) c9 Z$ f$ G; D! n8 |
7 U- h$ x; m- ^) a2 A3 B
    举个例子来说明一下,在我虚拟机里SCSI Controller的IRQ是17(注意,已经大于16了),到重定向表中查找第17项,得到中断向量为0xa3,再看IDT,0xa3对应处理例程是SCSIPORT!ScsiPortInterrupt。, T3 g" e+ U" G" _" A& Z! q+ F& U

& g6 l- Y! m! V' Z  b* q4 }) a    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等向量就没有对应。
) P8 M# M. g* k' l/ T9 ~/ N5 {# I
    IRQL机制为内核同步提供了很大的便利,既对驱动开发者隐藏了底层中断机制,也方便了驱动开发者的内核同步。LINUX从2.5内核开始引进的软中断和任务队列等机制,很大程度上也来自windows这套机制的借鉴。
2 ^$ h# ^0 F9 G) M
: q+ D; O) Q+ t5 t( D2 E4 E/ c$ `7 x    终于考完试,解放了,呵呵。这个东西其实还有很多可写的,只是没空再深入去分析了。在未来的64位系统里,APIC这种基于中断引脚的机制很快也要被SAPIC这种基于消息的更强大的机制所取代
回复

使用道具 举报

发表于 2008-3-13 09:04:14 | 显示全部楼层
I/O APIC演進
. _: u* u4 A2 Y/ b) @; v来自:http://www.four-stock.com/forum/ ... d=32&sid=JZS6Kb
7 t0 b% Q* ~0 s
8 L& y  C; @3 z$ k$ M作者: Titan    時間: 2007-10-26 17:51     標題: I/O APIC演進~~~~~~~
' m; d  N& f9 A$ B1 {. z9 t! q1 C+ M, d$ U
7 {9 i7 l* F, _0 R
訂正一下..作者不是他..是下面的作者...
7 Q0 a% q* |: u8 y2 t& Qhttp://biosengineer.blogspot.com/
回复

使用道具 举报

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

使用道具 举报

发表于 2008-11-25 16:35:44 | 显示全部楼层
LZ很厉害,还帖子!支持。5 k6 Y) e0 O, C8 s
希望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 use7 H1 I) O: q+ l$ s9 w* _
**************************************************
& T' t( c/ v/ d2 IMethod(\_PIC,1)
# {; |! u/ g$ B* B: e  {0 ]) ^+ ^  M7 R/ D
          Store(Arg0,PICM)
) M2 n1 @) A  {! O  }
; N' y0 B2 q4 _( q& O**************************************************6 P6 Q2 P# ~0 E
3 h, ]# p# W' x, z2 Q! x! v
And in _PRT methord , it will return PIC or APIC mode routing table
7 h3 Q7 V, e# l$ ]$ S2 N6 h  [1 L! X+ B" s- q0 d
***********************************************
/ q# }( q) s0 yMethod(_PRT,0) {! s. Q% k/ p: L& d2 _0 r/ E
If(PICM) { Return(AR04) }// APIC mode% y, W8 g7 q/ ~' v# T( \5 W
Return (PR04) // PIC Mode2 `. L: `9 N. _8 Y% E- I  j
} // end _PRT
) I7 M$ |1 u+ H# P/ X  J**********************************************
回复

使用道具 举报

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

回复 7# 的帖子

IRQ0-15就是PIC,15-23就是APIC吗?, k/ x6 Z9 G: Q
不是.
  R4 l& y& N. T1 O' M这个看南桥的做法,Intel上面貌似是这样的,当nVidia就不一定了.
) F$ g# @$ a  ~/ k
' [+ d2 W# }+ R! C我们在设备管理器里看到的IRQ共享,应该如何解释呢?
+ c2 E1 N1 l# \; r4 d7 C2 b. JAPIC里面是可以共享IRQ的,你看到了,说明你的系统是使用APIC在.
回复

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-12 00:50 , Processed in 0.312195 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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