小華的部落格: 2007/9/23 - 2007/9/30

搜尋此網誌

網頁

星期四, 9月 27, 2007

[我所知道的BIOS]->[Chipset Config] 5

一旦正確的頻率供給給system後, BIOS便依據既定的POST table(類似行程表)來做事. 首先,與chipset最為相關的便是 [chipset config stage]. 意即,在此階段BIOS必須對 chipset registers填入正確的值,俾使其正常運作. 一般而言,要config下列的 devices:
- NB(還記得前面有提過北橋內部約可分 4 blocks; "有些" blocks 需要 在此 program...)
- SB(即 PCI-ISA bridge)
- ACPI registers
- USB registers
- SATA registers
- PATA registers
...

* 在此所謂的 registers指的是: PCI config registers(除了ACPI registers以外). PCI spec所定義的 PCI config registers 00~3Fh 為 PCI header part,這個範圍的registers並不是此階段的主要工作(當然還是會touch,只是不多),而是稍後BIOS PCI kernel的事情.此階段將 focus on :offset 40h以後的 registers,因為,這些是 device specific的部分,是 chipset自己加function/feature之處 !!!

* ACPI registers通常透過 IO 來存取
Ex. // assume ACPI Base is 800h,要 access ACPI Reg55h
mov dx, 855h
in al, dx ; <- al = ACPI Reg55h's value

* 上述所列的 devices多為 PCI device,也都有唯一的PFA(PCI Function Address,即 bus#,device#,func#),也因此,只要對 device 下 PCI configuration read/write便可以 config device registers.

Ex. 假設: set SATA register offset 52h bit3 = 1;SATA controller PFA is (0,4,3)
=> 簡單的 assembly can be:

mov eax, 80002750h
mov dx, 0cf8h
out dx, eax

mov dx, 0cfeh
in al, dx
or al, 00001000b
out dx, al

事實上每家BIOS都 maintain many "tables" 來說明: 哪一個 device 中的哪些 registers要填?值.相關的 access routine都已經寫好. Programmer只需更改表裡面的值即可 ^_^

*當有人要求改 register setting時,我們必須知道三件事:
1. why (為什麼要改?)
2. what(改成何值?)
3. when(什麼點改?)

*對於 BIOS kernel與 OEM coding的人言,這部分會是較少碰觸的,因為,這些code會由 chipset porting的人負責撰寫及維護.

[我所知道的BIOS]->[Jumpless] 4

上一篇所提到的是:BIOS entry point. 它是第一個被 CPU 所抓取並執行指令之處.每家BIOS都有其相應的 file,要牢記.

在本文中,要提及: Jumpless ! 在此要先說明Jumpless的意義.它代表:"用 s/w方式來 config clockgen generator,使之產生正確的 頻率s 來供應系統運作". 重要性在於:假如某個 frequency錯了,則將導致 system abnormal or malfunction...

有哪些 frequencies由 clockgen 提供?
- CPU clock (在此指的是 : host clock, Ex. FSB800 CPU 需被 supply 200MHz clock)
- DRAM clock( depends on chipset design; Ex. DDR 533要被 supply 266MHz clock)
更正 : DRAM clock現在都是由NB產生 . 外部的最多是 buffer而已. 並非 clock generator. 原因是為了保持較良好的 host clock & DRAM clock的同步.

補充:我舉的例子是以前的chipset design. 現在我做過的 chipset 其 DRAM clock的確由北橋來推. 北橋中有一會 register定義: CPU-DRAM ratio.
Ex. CPU clock = 100MHz. Ratio = 3:5,則可得 DRAM clock = 166MHz


- AGP clock: 標準 is 66.6MHz (= 1/2 PCI clock)
- PCI clock: 33.3MHz
- SATA clock: 100MHz(see SATA spec,似乎還要更精確...)
- Link clock: 即假如NB/SB中間有 link,亦由clockgen提供
- USB 1.1 clock: 12MHz
更正: USB 的 clock 是 48MHz
補充:我們 chipset的 design是: 由 clockgen提供 12MHz clock(或由 external crystal提供),被 PLL吃進去後,會產生 48MHz給 USB 1.1(你說的應該是這部分). 至於 USB 2.0,則是 supplied other freuencies !

- SIO clock...etc

Clock Generator的架構
=> ClockGen基本組成為 PLL(Phase Looked Loop) + Div. PLL 的輸入為 14.318MHz, 利用 迴授方式產生出 frequency F;之後 經過 Div 除頻,便得到 desired frequency,見下列圖示:

14.318MHz -> PLL -> F -> Div -> f

Ex. F = 400MHz, 為 PLL振出來的;若 Div = 4,則 f = 100MHz

ClockGen的 spec中,會列出許多 registers,好比是 Function 的 "contact window",透過這些 registers可以設定此clockgen !

更正:其實PLL 不是單純一個的 div. 鎖相迴路的參數是兩的divider 組成 M(VCO divider)/N(REF divider)
補充:觀念上來說是 PLL所振出的頻率經 div後可得到 desired frequency. 但在 clockgen中:
1. 有 2 bytes(即所謂的M,N)來決定 VCO
2. 有幾個 bits來決定 div;一些主要的 frequency都有相對應的div
3. VCO / div = frequency


How to access ClockGen
=>現今存取 clockgen的方式,都是透過 SMBUS來達成. SMBUS 有分 1.1 and 2.0,不過大同小異. SMBUS是 2-wire protocol;由 SMBUS master(即內建在南橋內部的 SMBUS controller )來下 command 給 SMBUS device(Ex. Clockgen);Command中常用的有 Block Read/Write & Byte Read/Write

不同家 chipset 的 SMBUS controller implement方式不同,自然下command的方式亦不同;主要的步驟是:
- pre-init( clear status or ...)
- put slave address(要 access 的對象)
- decide Read or Write
- put command(Protocol type, Ex. Block or Byte access)
- put offset(要存取 自 clockgen中的哪一個 Byte開始...)
- put data if (Write device)
- start transaction !!!
(... processing ...)
- get "Complete" status to check if transaction is done successfully
(...wait for system reset...)

* 當 start transaction後, SMBUS controller便會將 programmer所 prepare的資訊將之轉成 SMBUS command打給 device;完成後應該在 controller端有 status register可以檢查,看看是否 transaction ok or failed,或是有其他 error conditions.

透過這樣的方法,programmer便可以 config clockgen使之產生正確的 frequencies.

[2 Programming ways for clockgen]
=> 現今的 ClockGen有提供兩種方式 for S/W config. 一為 table mode,一為linear mode. Table mode指的是: ClockGen spec 中會有一個 table,裡面說明: 要產生 ? frequency 要填 ? 值.因此,這種方式只需program 1 byte to Clockgen就行了. 若是 linear mode,則是坊間所說的無段變頻,即可以微調frequency. Ex. table mode只提供 100/133/166/200MHz,但 linear mode則可以提供類似 102.6/136.3/168.7..等的頻率. 此時,要program的 byte數就很多了.....除此之外, linear mode也可以config 所謂的 spread spectrum(%),板廠測EMI時會用到

【Notes】
1. For NB platform power-on CPU frequency 由 2 pins來決定;DT platform會由 Jumper決定.不管如何,之後做Jumpless都可以 override掉原 clock settings

更正: 不是只有NB如此.不管DT 或server. CPU FSB 也是 pin(由於FSB頻率比NB多.所以是 3 pins )來決定的.不是jumper. 即使要做超頻設計會對這三pin做手腳, 也不會使用jumper


2. 有些 clockgen所提供的 SS 都是 center spread. 若需要 Down spread則可以由 center spread搭配 改變後的 frequency(類似直流準位)來達成

給我正確的頻率,其餘免談 ...^_^...

=====================================================================
Q&A
=====================================================================
>前輩我有幾個問題要發問!
>1. 你這邊說的Table方式頻率是指供應給CPU頻率嗎? Intel網站的CPU說明,他說是固定的不可調的? 所以這不是HW固定住(Latch)設定值了嗎?
>
>2. 可以解釋一下Down Spread/Center Spread /...所代表的意思嗎? 還有用途?
>
>3. 我目前也在嘗試Program ClcokGen(新手上路),很多專有名詞還沒搞懂,另外目前ClockGen不是可以
>輸出不同頻率嗎? 為什麼Table方式只需要Program 1 byte就好 ???還是說各家廠商設定方式不同,有些廠
>商只要利用1 Byte 就已經選擇好所有的頻率了(33MHZ/48MHz/DOT96MHZ/LCD27MHZ...)?

[For #1]
=> 我所謂的 "Table"方式指的是: 為了方便設定,clockgen designer會專門提供一個byte register(8-bit);此 byte的某些 bit fields(Ex. bit[4:0])可以讓programmer填一組值,例如 01001b. 此值 write 至 clockgen成功後, CPU/DRAM/AGP/PCI/...etc 都會是固定的頻率. Ex. 100/133/66/33/...etc. 所以才說只填 1 byte only !

此值一旦填至 clockgen, clockgen便依據該 byte(可參考 spec前幾頁,會有一張表說明: bit[4:0] <-> frequency combinations)來產生出 frequencies.

不管用哪一種方式(table or linear mode),都會 supply CPU frequency !!!不過,此時的 CPU frequency is CPU的外頻 ( CPU 總頻率(core) = (外頻)*(倍頻 <-multiplier) )

Ex. 外頻 200MHz(Merom CPU, FSB 800),倍頻 = 12 -> core freq = 2.4GHz

還有,BIOS可以調整 外頻 & 倍頻 ! 沒問題 ! 不過,若遇到鎖頻的CPU(Ex. 量產版的CPU),倍頻可能無法調整.但外頻還是可以靠 config clockgen來達到 !!!

For #2
=> 假設要達到 100MHz 且 SS = 0.5% center spread.則:
(...想像以前學的直流與交流的訊號...)

100MHz 相當於 直流的部分,其值不隨時間而變; 0.5% center spread好比弦波訊號(振幅是 100M * 0.005 * (1/2);所以,兩者的合成便是: 以 100MHz為中心,其值隨時間而變,振幅 is 100M * 0.005 * (1/2) 的訊號 !!!

我 '猜' 要這樣測試的原因是:所產生的 clock一定不會是 perfect的 100MHz,有可能因為元件或是外部干擾而被 "改變".為了模擬這樣的情況,我們會將 clock的 spread spectrum enable,產生 "隨時間而改變"的頻率,來測試系統的穩定度...等

Down spread 0.5% 指的是:距離 水平 100MHz, 最低的值是 100M-100M*0.005,最高值則是 100M本身( 等同於: 水平值 99.5 + center spread 0.5%, right ? )

For #3
=> 前面提過,只設 1 byte 就可以產生所有頻率是因為: clockgen公司已經把設定各頻率的功能"濃縮"在一個 byte裡面 ; programmer只要 config this byte 就可以了...

* 關於 EMI 測試部分,有錯請指正. ( ...我有用到 "猜" 字眼...^_^ )

[[EMI 測試的知識]]
由於 對clock信號來說. 鋒(peak)值是能量最強的地方. 所以peak的能量就會不斷累積, 發射出來. 因此在頻譜上就會出現能量很強的頻率. EMI 工程師的工作就是要想辦法屏閉這些電磁波的干擾. 

為什麼需要 spread spectrum? 由於PLL 十分精準. 也就是說 100MHz的clock, 其 peak & peak之間的距離一致(波長固定). 所以能量十分驚人. 使用展頻可以使 peak 的距離改變(由於頻率不斷的在一個範圍內改變, 這個可以用示波器累積clock信號來看) 所以累積的能量會比較低. 這樣EMI 可以比較好處理.

至於為什麼會有要求BIOS一開始就把展頻開著, 以確保板子的穩定? 很簡單.不開展頻clock很穩定.自然比較不會有問題. 展頻一開. 由於頻率是浮動的. 很多設計欠佳的板子就會不穩定. 及早發現才能及早修改.

[[補充資料~~運作原理]]
CPU本身有預設值的BSEL[2:0]值,這個值是與Clockgen所產生的BCLK是對應的,CPU本身Spec會有一個Table定義這個值,然後CPU透過BSEL[2:0](輸出pin) 連接到Clockgen與NB(這兩個都是輸入pin),所以當Power on的時候,Clcokgen會依照CPU預設的BSEL[2:0]去產生BCLK給CPU,而FSB 頻率也是經由CPU接到NB的BSEL[2:0] 來同步(一般都是1/4 CLK 提取一次資料,所以假設BCLK=200MHZ ,而Clockgen輸出到NB的Host Clk=200MHz,一般都會同步,所以 FSB=Host clk*4 = 800MHZ)

※ Clockgen 分別透過BCLK與HostClk pins輸出頻率給CPU與NB

然後CPU開始執行BIOS Code,當執行到Program Clockgen時,BIOS可以透過Clockgen內的暫存器的某個Byte 內的FSC/FSB/FSA 這3個bit 來改變BCLK輸出頻率(應該可看作override BSEL[2:0]設定),當CPU接收到新的BCLK頻率後可能的反應有:

1. CPU本身不支援這個BCLK所以系統當機或是Shutdown
2. CPU 可工作在這個BCLK頻率,依照這個頻率對照Table,然後改變BSEL[2:0]的設定

另外CPU 是否能工作在266Mhz or 200Mhz or both,這部份依照每顆CPU不同而有所不同,有些CPU只能工作在266Mhz,所以當BLCK=200Mhz時,CPU就不會工作。

假設CPU可工作在266Mhz與200Mhz,則當BCLK從200MHZ-->266Mhz時,CPU一樣可以工作。

還有CPU內部的調整ratio的MSR暫存器可分成測試版的CPU跟出貨版CPU的不同:
a)測試版CPU的Ratio可調,如何調要看Spec
b)出貨版CPU不可調,也就是鎖倍頻
---------------------------------------------------------------
1. Clockgen 會送兩組 differential-pair clocks給 CPU & NB. 目前這兩組 clocks是相同的頻率.
2. CPU有兩 pins 稱 BCLK[1:0]. Input.
NB HostClk[1:0]. Input
* bit[1:0] 是代表: differential-pair clock都會有 2 clocks,分別是 true clock and complementary clock

3. 開機時的 behavior 是:
1) CPU內部自己會產生一組 default BSEL[2:0] 給 Clockgen的 FSC/B/A (依據經驗,這組 default 值 可以由 CPU MSR 得到 ; 也等於這顆CPU所能支援的最大外頻,BCLK)
2) Clockgen據此 FSC/B/A會產生對應的頻率,送給 CPU 的 pins BCLK[1:0]
Ex. 266MHz
3) 之後,若有需要, BIOS可以透過 config FSC/B/A 或是 M/N programming(透過clockgen內部的暫存器)來 "override"掉原來的 clock setting以達到改變 BCLK的目的.
------------------------------------------------------------------

CPU 工作頻率=外頻 (BCLK)* 倍頻(MSR調整)
FSB 頻寬= CPU Spec說由 BSEL[2:0] "同步決定",但是看Clockgen電路有分成,BCLK與HostClk(兩者應該輸出同樣頻率) 所以應該是北橋拿HostClk當參考,每1/4 Clk提取一次Data,所以應該是HostClk * 4

以前FSB頻寬=FSB工作頻率,所以有人把CPU工作頻率計算方式看作 " FSB頻率 * 倍頻 ",但是由於FSB頻寬目前已經不等於FSB 工作頻率,且Clockgen 分別拉了兩組pins(BCLK與HostClk)給CPU以及北橋,所以計算CPU工作頻率的方式才會變成目前的 "BCLK * 倍頻"

加註:
1. FSB1066指的是: bandwidth ! 不是頻率. 一般不會說 FSB266,而會說 host clock = 266MHz !
2. *4 應該是因為 ( clock的上下緣都可以觸發 ) + ( differential-pair) 的關係


我先解釋一下這三pin,就我印象中除了之前 NV chip + K7 和 SiS的chipset以外.
CPU 的FS0, FS1, FS2會接到clockgen (FSA,B,C)和NB (BSEL0,1,2)的對應pin.
CPU 是負責產生準位, clockgen & NB 會在自己的powerok ready的時候把資料latch進去.
clockgen 除了利用這三pin來產生對應頻率的CPU clock外, 另外也會根據這個頻率來產生合適的PCI-E, PCI clock..., 而北橋則是利用來產生正確的 DRAM clock(host/dram ratio),對intel來說也有PCI-E的同步關係.

至於超頻跟這三pin 的關係, 我稍微解說一下.一般而言要超頻的話, MB 必須把到NB & clockgen的路徑斷開, 由另外設計的線路來取代CPU的FS0,1,2.也就是說NB & clockgen 一開機必須收到一個由這個控制線路決定的FSB. 這樣才能作所謂的 133-> 200 or 200 -> 266的大幅度超頻.因為此時NB 和 clockgen 才會正確的分配. 別忘了NB, SB, PCI-E, PCI, DRAM是沒有CPU這麼強的超頻力. 直接利用軟體改變clockgen會造成很多不該變化的頻率跟著變.

Note:此超頻線路, default是一個所有CPU都能開的安全值, 一但BIOS完成設定, 就會latch住資料
此外還必須配合watchdog 來處理過度超頻不能開機的問題. linear mode只用來處理小超頻的部份

以前遇到的 clockgen 是 CPU & DRAM clocks 由同一個 PLL決定,其餘 clocks由另一個PLL決定. 當時有寫一個OS下的小程式,可以微調 CPU頻率(以1MHz為單位). 不過,微調CPU的同時也會微調到DRAM clock(<-同一個PLL),只是微調值不同(depends on divider).

現在遇到的 clockgen + chipset design 是: CPU由一PLL供給,而DRAM clock由北橋推.同樣的,微調CPU clock一樣牽動DRAM clock.

至於其它 frequencies是否會跟著變, depends on Clockgen design;現在的clockgen幾乎都有 2以上的PLLs;所以類似PCI/AGP/SATA clocks都會有專門的 PLL控制. 而CPU則由另一個PLL控制.

有興趣及時間的人可以試試看 M/N programming(小微調). 看著 (Ex. FSB800 CPU)由200MHz 操到 210MHz,也是一種快樂 ^_^

Q: 這邊剛好有提到watchdog...想請問一下前輩這個東西在PC系統上是何時開始使用? 用途為何或是應用為何? 以前學校沒看到過這個東西,不過我在嵌入式系統常看到一些應用,另外在南橋Spec有看到過,而BIOS端需要如何去應用以及設定它? 另外使用 watchdog 來處理過度超頻不能開機是怎樣的一個方式? 頻率不對,CPU已經無法work,連BIOS code都不能執行了? 所以他是靠HW去處理嗎?

A:我曾用過關於watchdog timer 的經驗是 => 在 config clockgen完後, 需要 system發 PCI reset ! 此時會需要 watchdog timer...

因為, write clockgen完後,有可能系統當掉 !!! (<-frequency settings被改變了...)因此,我知道的作法是: 在 write clockgen之前,先 enable watchdog timer ! (當然,一定會指明要"多少時間後"才發 PCI reset ! ) 一 enable完,便匆匆去 write clockgen(當然,這段時間要夠長,以免 write clockgen沒完成,PCI reset就出來了 >_< ).

一旦 write clockgen完畢,code會寫 "jmp $"...然後等 watchdog timer 時間到,然後PCI reset出來 reset system...

你所說當機時的 watchdog timer,我沒做過 ! 不過,watchdog timer 不一定是要在 SB內啊!(或是即使做在 SB內,也是"獨立的"...)做成外部的電路就不怕 chipset hang時 timer會失效了...^_^

一般我知道的 watchdog timer control 大概有:
- enable/disable ( => 開始記時...)
- time to bomb (=>多少時間後爆炸 ?)
- event routing ( => 時間到要幹嘛 ?)


[[WatchDog]]
watchdog是個硬體機制.
watchdog 在嵌入式應用中主要就是用來做系統自動回復用的.通常用在機器處理很critical 的任務, 不能當機超過一定時間的事務. 一般的用法是, 系統的軟體要固定時間去重設timer. 例如: watchdog timer 設定10秒以後會重置系統, 那麼系統軟體可以每5秒有一個task 去重設timer. 萬一系統當機了. 由於軟體無法重設timer. timer 數完了以後就會發出reset , 讓系統重新恢復狀態. 在MB 中superI/O 有watchdog, clockgen 也有支援watchdog. 以超頻來說, 往往設定完clock generator的瞬間, 系統可能會當機. 這時有兩種狀況. 1. 因為clock 變化造成, 這種狀況只要一個PCI reset. 系統就可以繼續執行. 這時BIOS 可以借用 watchdog來發PCI reset. 只要在定clock之前先設好watchdog timer, 然後在一段時間後關掉watchdog timer. 這樣就可以解決這個問題. 一種是 clock 增加太多造成chip 死當. 這種就需要依靠 clock gen 裡面的watch dog來讓clock 回復成default value(Note:要視clock gen的設計, 有些只是發reset而已).

另外一種我知道的應用是雙 BIOS的主板. 利用watchdog來切換BIOS.

星期三, 9月 26, 2007

[我所知道的BIOS]->[PowerOn Sequence & BIOS Entry] 3

在此將以DeskTop platform來說明(Notebook platform 的 power-on sequence 牽涉到 EC,可參考討論區中 "power on sequence" 文章);還有,所敘為rough flow,詳細的時序圖依據design會有些許不同.

[Power-On sequence]

- AUX power ok
- Main power ok
- PCI reset
- SB state-machine runs...
- NB state-machine runs...
- CPU power-Good ok
- CPU reset
- 1st code-read by CPU ( <- BIOS entry point,即 CPU 會抓取 FFFFFFF0h 處的 BIOS code 來執行)

* 當然CPU一次抓取的BIOS data不僅僅是幾個Byte ! 而是一堆的data(Ex. 64 bytes);之後會從中 extract 出 FFFFFFF0h處的 data,然後來執行.

補充: 為什麼CPU 發的第一個位置不會只有FFFFFFF0h? 而是多抓很多個? 範例中為什麼是64 bytes?
原因在於 cache的支援. cache不是細分為單一byte 的, 而是以block(many bytes)為單位. 這個block的大小的名詞就是 cache line size. 也就是要填入cache一次要寫入的bytes量. 例如 cache line size 為 16 bytes. 那麼一次就要讀16 bytes到cache去.
CPU 一但發生cache miss(第一次開機一定是cache miss)的狀況時.就會通過host bus 對外取得資料. 這時就會產生burst read cycle來達成fill cache line的需求. 所以由CPU 的 cache line size的大小就可以知道CPU一次會抓多少的 bytes. P4以後CPU 的cache line size 為 64 bytes, 所以CPU 就會產生一個 burst length 為8 的 memory read cycle. 所以CPU 發出的位置就需往下減.然後在讀取的資料中可以包含到 FFFFFFF0h以後的資料.


自此,CPU便循著 CPU->NB->SB->ROM 的 path,循序地至BIOS ROM中抓code,執行 fetch->decode->calculate->store...自此開始便是BIOS POST stage starts...


[有可能遇到的問題是] debug code = "00" or "FF" (意即BIOS常用的 Port80 card所顯示出的 "code" ) !!!

* 此時,強烈建議:請在BIOS entry point 處 丟Port 80(value可自行定義),因為,即使BIOS有跑到,但因為距離 1st 丟 Port80 的 code仍有一小段程式碼;若系統 hang在此其間,Port80仍是沒有 code,因此,在BIOS一開始進來便先 out Port80 將有助於判定: system hang before BIOS entry point or NOT !!! )

# Assume system hang 'before' BIOS entry point, 可能的原因有:
- incorrect power sequence: 此 sequence 有 spec,規範訊號間的相對關係與 assert/deassert的時間,violate spec有可能導致 system hang;此時需要 H/W or board designer來量測
- incorrect power-on frequency:有發生過因為 Power-On CPU frequency錯誤而不開機者.請用 scope量測
- incorrect chipset behavior: 意即上述的 power-on sequence中有關於 NB/SB的 state-machine部分,有可能這部分的行為不正常,因此需要 H/W designer來 clarify

* 曾聽說,某家chipset需要BIOS image 中 include 幾個 bytes 來 config NB/SB的 registers;這些 settings也會影響 power-on時 chipset的 behavior;因此,這幾個 byte 若是錯的,也有可能 system hang

補充:很多chipset都(or 曾經)有這個功能, SiS, NV, VIA, Intel. 以前有個詞叫ROMSIP就是指這玩意兒... 即使在現今的intel platform也有預留這東東.

#Assume system hang 'after' BIOS entry point
=> 這就是BIOS engineer的時間了,就 debug吧...(儘管,有些 issue 是 board or H/W造成的...)

* 此時的 debug方式,若有 輔助工具的(Ex. P debug card) 就用,沒有的就用Port80 card囉 !

[Summary]: 沒進入到 BIOS entry point前....不要找我....真的沒辦法 >_<

* 關於 BIOS entry point,請參考 討論區中 "追蹤BIOS code 的進入點" 文章 !!!

[Power Button開始的動作]

一般Power Btn 都是EC 控制(或稱PCU),如果你說要知道Power Btn之後的動作就是問EC 工程師就對啦。
我印象中好像是Power btn按下後-->EC 偵測到動作(應該是KBC 發Event給EC BIOS或是EC BIOS自己每隔一段時間去檢查有沒有Event..沒K過EC Spec,純猜測...)-->EC 檢查目前系統狀態(不同時間點按下Power Btn , EC可能會做一些動作,因此要判斷),檢查的時候主要會去檢查南橋ICH接到EC的訊號線,判斷Sx state-->如果是正常開機,則開始供電--->系統上電後,CPU會從起始位址開始讀取BIOS第一條指令(至於CPU何時收到重置訊號可能要看一下其他Spec...)。

另外印象中EC BIOS有分成兩種形式,因為EC Controller可能裡面的記體器容量會不足,或是說節省成本故意做成那樣,所以 EC BIOS 會是包在SBIOS或是放在EC Controller裡面兩種格式。

如果真的要K流程,應該是去看EC Spec跟ICH Spec吧...

當EC 收到power event (指power button的動作後...), 會根據目前系統的狀態來決定是否要開某些電源...For example, 當系統處於s3(suspend)的狀態時, 當user按下power button後, EC 會發一個訊號給南橋, 然後EC 會wait for SUSB and SUSC 的訊號assert. 然後開 main power的電(我指的是非suspend的power)...但是詳細的動作應該各家都不太一樣才對. 而且這些spec都是各公司的knowhow

[我所知道的BIOS]->[系統架構] 2

任何 firmware 都有相對應的硬體;也唯有深入瞭解硬體,才能寫出好的 firmware ! (當然,對 programming language 很熟,有技巧的的人可以寫出好的 firmware,但是,另一個層面是:對硬體很瞭解,所以所寫的firmware 與 H/W 搭配良好,這也是另一種值得追求的地步)

BIOS 就是 "主機板的 F/W". 所以,它的對象就是主機板上的所有 devices. (為了後續的解說,我只列出一些,其他的坊間書上都可找到)

- [CPU]
=> central process unit. 依架構不同有分 Intel or AMD cpu. 其工作之一是: fetch code->decode it->fetch operands->calculate->store result.

- [North bridge]
=> 即俗稱的北橋. 常見的 Intel 945/P/G,965 等是其北橋晶片代號. 它可以約略區分成四個 blocks(H/W view)
1. Host interface: 即 與 CPU interface 的部分.
2. DRAM interface: 即與 DRAM interface的部分
3. Display interface: 即與 AGP/PCIe VGA interface的部分
4. Link interface: 即與 South bridge(南橋) interface的部分

簡單說,North bridge的功能是: Host block 承接 CPU 所 issue 的 cycle, 辨認(identify),並且將之 forward至 "正確的接收者" ( Ex. DRAM block, display block, or Link block )

所以,它像交通警察一樣,接收中央的命令,將來自四面八方的車流引導至正確的地方,讓整個城市的各部分各角落可以相互交流無虞.

-[South bridge]
=> 及俗稱的南橋. 常見的 Intel ICH7/8為其南橋晶片代號. 它"可能"包含以下的 blocks:
1. Link interface: 即呼應北橋的部分.
2. PCI block: 處理 PCI request部分(即 implement PCI spec H/W part)
3. ACPI block: implement ACPI H/W part
4. USB
5. Audio
6. SATA(AHCI)
7. ...

所以, 南橋裡面包含許多我們常見的名詞, USB/1394/SATA/HDA/TPM/PCIE...等

-[BIOS ROM]
=> 儲存 BIOS image的device. 常見的有 ISA ROM/LPC ROM/SPI ROM. 編譯出來的 BIOS binary file透過燒錄器或是 flash tool 燒錄到此 ROM中. 內容是0101...的 binary code

所以,總結來說: BIOS code被CPU fetch, 經過 decode後, 會轉發給NB.NB接到後也會自行decode 此 request;若是 與 DRAM有關的,則 forward to DRAM block;若與 display有關,則forward to display block;若是與 PCI有關的,則將之轉發給 SB(透過兩者中間的Link),請SB再找適合的人 Ex. USB, SATA, or 1394 controller ! ( 別忘了 PCI H/W是在SB裡...)

以上依序所講到的 CPU->NB->SB->ROM,將在後面的敘述中用來說明一些觀念及flow.

Summary:
1. BIOS可以說是 chipset's driver !!!
2. CPU所 issue 的 cycle會先抵達NB,由NB判定是給誰的;若不是 for DRAM or display,則會再轉發給SB,由它判定是要給誰的

[我所知道的BIOS]->[前言] 1

本身從事BIOS相關工作已經六年了;今年由於生涯規劃,決定暫時(?)離開BIOS而轉做其他工作;即使如此,對於 BIOS仍是有著極大的興趣以及期待. 從小就是喜歡做整理以及分享的人,所以最近有個衝動是:何不將自己所知道的整理一下,並將之POST出來,讓更多對BIOS有興趣的人可以有點深入的瞭解BIOS? 也讓版上的諸多前輩可以提出指教及批評,進而糾正我的一些觀念 ? 基於這樣的想法,我選擇了這裡來作為我這個念頭付諸實現的地方,請大家多多挹注,多多指教,多多批評 ! 歡迎任何的建議 ^_^

首先要說明的是,我覺得BIOS在台灣可以分成三類的人:(自己的分法,僅供參考)
1. 撰寫BIOS kernel的人
2. 撰寫chipset code的人
3. 撰寫 OEM code的人

我是屬於第二類的人,所以我的觀點(view point)也是從chipset出發 ! 對於第一及第三類,我的接觸不多 !
要先這樣說明的原因是:有些問題我無法回答或 comment,因此,就有賴版上諸位的幫忙了(if available)

還有,我本身是撰寫某一家BIOS(A, P, or M)的,所以會幾乎以該家的所教給我的 flow/information 來敘述事情;當然,我會盡量抽離這種成分來敘述,讓大家瞭解 "事情的本質即可 "...若有偏頗之處仍須請大家包涵...

最後,我所撰寫的幾乎是親身經歷的 information,因此,不會有天馬行空的想像(不過,做BIOS仍是需要想像力的...^_^...) 若有錯誤,那應該是我的經驗不足,或是我的經驗有誤,還是要請大家指正囉 !

就這樣...

liaoo

~轉載自程式俱樂部討論區~

PCI IRQ Routing Table Specification

~~~轉載請註明出處~~~by 小華的部落格
在x86歷史的演進中,有很多的BIOS工程師對於PCI IRQ Routing Table還是搞不清楚,我剛入行的時候也是一樣,對於這個東西一點概念都沒有,只知道是因為IRQ#不夠用,所以才需要去繞線(Routing)。

[為何要繞? 背景是什麼?]
依照我自己研究出來的歷史,我發現可能的原因是因為PCI設備越來越多,然後當時的中斷控制器是串聯的8259A,所以只有IRQ0~IRQ15可以用,且IRQ2已經連接 "僕8259" (第二顆中斷控制器),所以剩下來15支IRQ#可以用,但是又因為x86系統在早期的設計中,有些IRQ#已經分配給固定的設備使用,所以剩下來沒幾支可以用,可是設備又那麼多,所以如何去分配剩下來的IRQ就是大家討論的話題。

[IRQ繞線的歷史發展]
依照我查到的資料,早期的作業系統Windows 95年代左右,PCI設備要使用哪一支IRQ中斷線是靠PCI卡上面的"跳線"去控制,所以有可能會因為兩個PCI設備跳同一支"IRQ#"而造成衝突導致當機或是藍底白字。
後來改用BIOS Setup Menu內去控制,也就是可以進去BIOS設定畫面去設定IRQ分配。

因此為了解決PCI設備越來越多,但是IRQ不夠用的情況,所以微軟找上的晶片廠商也就是Intel合作開發PIRQ Route Controller,簡單說就是微軟想在他的作業系統上面支援"共享IRQ中斷架構"的驅動程式,但是需要硬體配合,因此定義了PCI IRQ Routing Table來規範硬體線路要怎樣繞線,且需要BIOS支援哪些資訊。

[為什麼是PCI設備而不是ISA設備?]
因為當時PCI Bus取代了傳統的周邊匯流排,所以PCI設備橫行,且設備需要服務就是透過中斷請求線IRQ#請求服務,對於OS端來說,這個服務就是驅動程式,至於CPU如何把控制權交給OS,則是靠IDT (interrupt Description Table),相關詳細資料請看Windows核心說明。

[跟DOS有關嗎?]
應該是無關,除非你在DOS下替你的PCI設備寫了一個驅動程式,或是你的PCI設備在DOS模式下要工作,不過應該也是沒啥機會這樣做吧,所以PIRQ Routing都是針對Windows作業系統而言,因為與設備驅動程式管理有關。

[Windows 作業系統的改變]
對於微軟自己定義的規範中,他最希望的就是能夠共享IRQ,所以在作業系統的改變就是要能分辨是哪個PCI Device透過IRQ發出請求,這是因為可能有好幾個PCI 設備都用同一支IRQ#中斷請求,所以OS 必須要能夠讓正確的驅動程式去服務發出中斷的設備,因此在撰寫OS 端的 Driver 時有了新的規範(針對共享IRQ的驅動程式有其規範)。

[Chipset的改變]
起先為了微軟的規範,Inetl 在南橋ICH上面多了幾支接腳(PIRQA~PIRQD),這幾支接腳又有對應的暫存器可以組態他們,例如下面範例:

PIRQA Register 60h bit3:0 <--PIRQA那隻接腳的設定暫存器在LPC Reg60h,其中bit3:0定義如下
=================================================================================
IRQ Routing — R/W. (ISA compatible.)
Value IRQ
0000b Reserved
0001b Reserved
0010b Reserved
0011b IRQ3
0100b IRQ4
0101b IRQ5
0110b IRQ6
0111b IRQ7
...
由上面範例可以看出每支PIRQ接腳都可以用"軟體"設定的方式橋接到IRQ#的任何一支。
也由於上面範例我們可以知道,OS 必須"先知道哪些IRQ可以被使用" 還有"哪些IRQ已經被使用",因為OS本身有自己配置IRQ#的演算方式,因此必須要先知道這些資訊,才有辦法去對PIRQ#繞線。

[BIOS的支援]
所以BIOS要提供"PIRQ Routing Table"給作業系統,然後OS就可以得到這些資訊,但是又因為OS版本不同(Win95/Win95/Win2000/WinXp or Acpi OS/non-ACPI OS..等分類),所以透過的傳遞管道也不同。

[後來的演變]
隨著PCI設備越來越多PIRQ只有4支接腳已經不夠用,所以後來擴充到8支,分別是PIRQA~PIRQH。

至今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)。

另外由於南橋ICH有兩種PIC,所以進入ACPI OS時是採用Legacy PIC mode 還是APIC mode 也會影響BIOS提供PIRQ Routing Table的方式,所以在ACPI Mode 底下又分成APIC Mode方式或是Non-APIC Mode(PIC Mode)方式。

~~~轉載請註明出處~~~by 小華的部落格

[結論]
PIRQ#是南橋上面的接腳,連接到PCI 的INTA#~INTD#,原本INTA#~INTD#應該直接接到PIC上面的IRQ#接腳,但是因為IRQ#不夠用,所以微軟才與Intel合作,多做了幾支接腳出來,然後用軟體方式去配置這些多出來的接腳PIRQ#要繞線到哪個IRQ#,且作業系統的驅動程式可支援共享IRQ中斷,所以在Chipset 端把這種機制稱之為PIRQ Route Controller (具有PIRQ繞線功能的控制器,也就是某某一代的南橋開始把這個功能整合進去南橋晶片內)。

而BIOS所扮演的角色就是提供PIRQ Routing Table,這個Table的結構如同微軟的PCI IRQ Routing Table的規範,而當系統演變到ACPI 後,BIOS也改變了提供Table的方式,也就是改遵循ACPI Spec內的規範去提供這些資訊。

上述這些資訊只是我整理的筆記的一部分概要,詳細內容可以參考相關資料說明,畢竟我也是花了一個多星期的時間才整理出整個PIRQ的歷史,是對是錯我也不清楚,畢竟過去的架構我來不及參與,只能就我收集到的資料作一個描述,如有誤請先進指教。 ~~~轉載請註明出處~~~by 小華的部落格

[後記]
1)當ACPI OS 系統處在APIC Mode的時候,PIRQA~PIRQH會直接對應在APIC 的IRQ16~IRQ23而不需要繞線。
2)APIC 目前可提供的中斷請求線有 IRQ0~IRQ255 ,目前只使用IRQ0~IRQ23
3)APIC 前面的IRQ0#~IRQ15對應到PIC的IRQ0~IRQ15
4)PIRQ Routing 是指: IRQ不夠用才需要透過PIRQ Routing Controller繞線,所以只針對PIC,而APIC模式則不需要繞線。
4)APIC Mode只需要描述哪些PCI Device共用了哪些PIRQ線。
5)non-APIC mode則需要描述哪些PIC的IRQ#可以被使用,描述的內容如同PCI IRQ Routing Table,差別在於用ASL Code描述
6)APIC有分成Local APIC與I/O APIC,這邊所提到的都是指I/O APIC。

[Reference]
http://www.microsoft.com/whdc/archive/pciirq.mspx
http://www.microsoft.com/taiwan/whdc/system/CEC/ACPI-MP.mspx
http://www.google.com

[補充資料]
VGA IRQ的配置


早期VGA卡還在ISA時代的時候, 透過BIOS啟動系統時, 會得到interrupt 第一順位, 而且有固定存取區域在UMB(Upper Memory Black)裡頭與系統相對印; 在PnP時代, BIOS系統直接在啟動系統時給予IRQ#編號, 無論你是AGP or PCI都變成由BIOS指定位置, 而不再像ISA時代需要跟其他人搶系統控制權.

順便一提的是, MS系統推出雙螢幕(Dual VGA)的概念的時候, 一些VGA-BIOS沒規劃好的顯示卡就出現問題. 因為在BIOS啟動系統的時候, 會依照設定順序尋找開機起始用的顯示卡(預設是PCI), 結果因為有兩張PCI顯示卡(或者主機板的晶片採用SIS55xx系列, VIA早期586時代晶片都有這種現象), 反而推選不出一個可以啟動的System VGA, 變成必須在佈線的時候強制規定哪邊是佔用較高優先權的現象...

到了AGP時代, 變成系統直接佔用, 不再有IRQ衝突的事情.....對廠商對BIOS規劃人員也變得比較簡單點了....

display card在古老時代是不需要IRQ的,當時diplay card本身不過是被動式的介面,顯示記憶體都是由CPU來控制寫入或讀出與搬移(如HOYO兄所說),所以那時就是單純的使用 Linear address mapping 來處理,而遇到較大而複雜的畫面記憶體處理時,就用視訊記憶體頁切換來應付,然而隨著顯示的需求越來越複雜,VGA card和CPU間的溝通需求也越來越多,VGA本身也搭載了功能強大的GPU,可算是一個小的專門處理影像的CPU了.這時候 VGA Card不再是一個只會聽CPU命令的單元了,它開始會對CPU提出要求,以進行一些需要取用北橋資源的動作,此時就需要IRQ來做"舉手發言".

目前市面上仍然有一些VGA是不需要IRQ的,但並不代表它們不是高階顯示卡,而是視廠商所使用的技術而定.
一般的 VGA IRQ 預設大都在IRQ 11,除非有佔用系統會自動轉到別的IRQ...

PIRQ配置演算法(4 支PIRQ的時候)
PCI SLOT 中斷共有四個
INT a/b/c/d
一般的接法是
Slot1 a/b/c/d 接到南橋 a/b/c/d
Slot2 a/b/c/d 接到南橋 b/c/d/a
Slot3 a/b/c/d 接到南橋 c/d/a/b
Slot4 a/b/c/d 接到南橋 d/a/b/c
而卡上 通常是從 int a 接起
所以兩片使用一個中斷的PCI 卡會變成個別接到 int a / int b, 而不會通通都接到int a 了

PCI 要求裝置的中斷要共享,唯一缺點就是 "共享的部分" 要多消耗一些程式碼去確定中斷是給誰的
另有一些ON BOARD 的裝置已經固定接到其中的一些中斷訊號線上了,看看主機板說明書上有沒有寫
這樣你就可以知道INT a/b/c/d 哪些是完全可以獨立運作的。

中斷經過IRQ Routing table 去轉成我們常說的中斷號碼 IRQ# 這個在BIOS中可以設定,也可以自動配置。如果有獨立中斷的SLOT 就可以拿來用在IDE Card/SCSI Card這種講究效能的裝置上。

另外就是給一些卡使用,因為這些卡的驅動程式不肯跟別人分享中斷,如果分享就不肯工作。
還有一種卡和別人分享就容易當機。

有一些ISA 規格的裝置一定會佔用固定的中斷,如果不用可以DISABLE,不過 PCI 還是只有四個給你的SLOT用空再多也沒用要分享的依舊要分享
irq-0 Timer
irq-1 Keyboard
irq-2 Cascade
irq-3 Com2
irq-4 Com1
irq-7 LPT1
irq-8 RTC
irq-12 PS/2
irq-13 FPU
irq-14 IDE1
irq-15 IDE2

大部分的VGA 都沒有配中斷,另外 Win2k ACPI 會把IRQ routing table 通通都設成同一個中斷號碼 沒辦法改 效能會降低 因為每個PCI卡的驅動程式都會檢查一遍 看看是不是自己的中斷,每次也只會有一個說是他的中斷這在高速裝置是很糟糕的。