UNIQLOCK

2011年5月26日 星期四

HOB(Hand-off block)

Hand-off block

2011年4月19日 星期二

System Resources系統資源 - Memory

這裡指的memory並不是實際記憶體模組的空間大小.
說的是CPU memory addressing space.
假設今天你只有插入1GB記憶體,CPU能定址的memory space一樣是由CPU是幾位元所決定!

所謂的CPU memory addressing space就是CPU所能定址的範圍.
定址的範圍是決定於幾位元的CPU.
如果是32位元的CPU則可以定址的memory space為2^32=4GB.
64位元就是2^64.


這部分有關MMIO的觀念,目前還不清楚,之後有相關研讀在作更新.

2010年10月29日 星期五

PCI Expansion ROM(3)


Execution of initialization code
在大多數情況下,系統的上電自測試(POST)程式碼對插接的PCI設備的處理與對那些焊接在母板上的設備的處理相同。但對Expansion ROM的處理是不同的。POST程式碼分兩步檢測一個選項ROM是否存在:其中第一步確定設備是否在配置空間中實現了一個Expansion ROM基底位址暫存器,如果該暫存器存在,POST就必須將ROM映射到位址空間中未用的部分並將使能位置1;第二步是檢查前兩個位元組是否為標籤值AA55H,如果是,就表示存在一個ROM,否則就說明該設備上沒有ROM
     如果檢測到設備上有一個ROMPOST就必須在該ROM中尋找一個具有合適的程式碼類型的映射,同時該映射中的供應商識別和設備識別欄位也要與設備配置空間的相應欄位吻合。當這個合適的映射找到之後,POST就從ROM中拷貝適當數量的資料到RAM中,然後執行該設備的初時化程式碼。至於拷貝多少資料量,以及怎樣執行設備初始化程式碼,要由程式碼類型來決定。
系統中的POST程式碼根據初始化長度欄位所指定的位元組數,將資料從ROM拷貝到RAM中,然後以03H處的值作為入口點調用INIT功能。在INIT返回之前,POST程式碼應將上述拷貝過來的RAM區保持為可寫狀態,以使INIT程式碼能在該區存放一些靜態資料,並調整運行存儲分配,使得系統在運行時耗費較少的空間。
當涉及到Expansion ROM時,在系統POST程式碼中有一套為PC相容而設的特別步驟,它們是:
1.       映射並使能Expansion ROM到記憶體位址空間的一個空區域。
2.       ROM中尋找一個適當的映射區,並根據初始化長度指定的位元組數從ROM中拷貝資料到RAM相容區。
3.       使Expansion ROM基底位址暫存器失效。
4.       保持RAM區為可寫狀態並遠端調用(FAR CALLINIT功能。
5.       INIT返回之後,利用偏移位址02H處的值決定運行時需要多少記憶體空間。
在系統引導之前,POST程式碼必須把含有Expansion ROM程式碼的RAM區變為唯讀區。
POST程式碼必須用特殊的方法去處理帶有Expansion ROMVGA設備,VGA設備的Expansion BIOS必須拷貝到0C0000H處。VGA設備的識別是通過檢查設備配置空間中的分類程式碼欄位來實現的。
6.        ROM的初始化(INIT)程式碼
PC相容的Expansion ROM中,含有一個INIT功能,用來負責I/O設備的初始化以及為運行操作做準備。由於在執行INIT功能時程式碼所駐留的RAM區被保持為可寫狀態,因此,允許PCI-Expansion ROM中的INIT功能具有某種Expansion 能力。
INIT功能執行期間,INIT功能可以在它的RAM區中存放靜態參數。運行BIOS或設備驅動程式便可以調用這些參數。但是該RAM區在運行期間是不能寫入的。
INIT功能還可以調整它在運行期間所消耗的RAM總量,具體方法是修改映像中位於偏移位址02H處的長度欄位,從而能夠保持Expansion ROM區(0C0000H~0DFFFFH)佔用有限的記憶體資源。例如,一個設備的Expansion ROM為其初始化和運行程式碼要求24KB的存儲空間,但運行程式碼只要求8KBROM中的映像所表現出的長度是24KB。所以,POST程式碼將全部資料拷貝到RAM中。然後,當運行到INIT功能時,它可以調整長度欄位使其減為8KB。當退出INIT功能時,POST程式碼看到的運行長度為8KB並且可以將下一個Expansion BIOS拷貝到最佳位置。
INIT功能負責保證整個映像長度的檢查的校驗和是正確的。如果它以任何方式修改了RAM區,就必須計算出新的校驗並存入映像中。INIT功能不能以任何方式修改系統記憶體(除RAM區域的INIT功能),除非它對配置記憶體採用適當的協定或BIOS服務。
如果要將INIT功能從Expansion ROM中移去,只要向初始化長度欄位(偏移位址02H)寫入0即可。在這種情況下,不產生檢查。
    INIT從入口處可以得到三個參數:設備的匯流排編號(Bus)、設備編號(Device)和功能編號(Function)。這些參數可以用來訪問正在被初始化的設備。它們被傳送到X86的寄存器AX中,其中AH包含匯流排編號,AL的高5位元為設備編號,AL的低3位元是功能編號。
    映射結構的三個長度:
一個PC相容的映射有三個長度與映射結構有關:映射長度、初始化長度和運行長度。
映射長度是映射的總長度,它必須大於或等於初始化長度。
初始化長度表示映射中所含的初始化程式碼和運行程式碼兩部分的總和,這也是在執行初始化例行程式之前,POST程式碼要拷貝到RAM區中的資料總量。初始化長度必須大於或等於運行長度。拷貝到RAM區中的初始化資料的檢查和必須為0
運行長度是指映射中所包含運行程式碼的總量。這也是系統運行時POST程式碼保留在RAM區中的資料量。這部分映射的檢查和必須為0.
PCI資料結構必須包含與映射的運行分配部分中,否則他必須包含於初始化部分


以上資料來自 老公公  百度空間
Peter Pan 修改整理.

PCI Expansion ROM(2)

這裡主要寫對ROM shadowing RequiredROM content
Expansion ROM2
2.1 ROM Shadowing Required
why ROM為什麼需要映射?它又被映射到什麼地方呢?
      PCI SPEC中要求device's expansion rom code 是不能夠在它自己的ROM裡執行的,它必須被copyRAM中去執行。這樣做的原因是:
& ROM的訪問效率是很慢的,無論何時從ROM中去指令執行性能都是很長的。
& 一旦在ROM中的driver 初始化部分已經被執行(在ram中),它可能被丟棄(比如init code copy),在ram中的code image 能夠變小,使RAM中只存在需要的code。這樣執行剩下的code 效率更高。
    一旦device rom被檢查存在,這個配置軟體就copy code image main memory並且disabled rom address decoder(把Expansion rom base address register bit 0 設為0)。在非pc環境中copycode 可能在記憶體中的任何位置。
         pc環境中,則ROM CODE image 必須被拷貝到規定的device ROMS 位址範圍:000C0000H---000DFFFFH,如果在class code(見配置空間暫存器對其描述)指明四個VGA’s device rom, 那麼它的code image必須拷貝進開始位址:000C0000h
  
哪一個image需要copy?這就要瞭解下ROM content的結構了
  
2.2 ROM Content
    2.2.1概述
   PCI Device ROM中可以包含超過一個code image(如圖 2.1),一個ROM包含適合各種廠家的device各種各樣的code image。所以被copy進主存的image 必須匹配這個function ID. 所以每個code image 包含:
-Vendor ID Device ID
-Class code。這個主要是對class device ,具體參考class code register

2.1 Multiple code images contain in one device ROM
          每一個image都是開始於一個512位元組邊界並且包含有PCI擴展ROM頭標,其開始位置決定於前一個image的長度。最後一個image在其頭標中需要標明(在位於擴展ROM data structure offset 14H的一個byte,其bit 0-bit 6 保留即全為0bit 7=1-->last imagebit 7=0-->not last image。)。
           
每一個ROM映射中所要求的資訊分為四個不同的區域:一個區域是ROM頭標,應該放在ROM映射的開始處;二個區域是PCI資料結構,必須放置在映射的第一個64KB處(為啥是64K呢?清注意頭標區 offsetPCI資料結構指標,是一個2bytes 16bits的指標-->即最大offset 64K)。圖2.2表示了擴展ROM中一個映射的典型佈局。三個是Runtime code,四個是initialization code

2.2 ROM IMAGE的典型佈局




2.     ROM頭標
ROM頭標格式如下:

ROM標識為55H 0AAHPOST程式在檢測ROM開頭兩個位元組,只要檢測到55 AA就知道知道有擴展ROM了。加電自檢程式(POST)當檢測到合適的ROM後,會直接調用偏移+3處的指令,故在此位置上(偏移+3處)總是放置一個跳轉指令。
3.     PCI資料結構
PCI資料結構格式如下:

供應商識別碼和設備識別碼必須和PCI配置空間中的相應欄位一樣,否則也不會執行映射中指令的。設備分類代碼雖然也要和PCI配置空間中資料一致,但是POST不會進行強行檢測,也就是說:這不是ROM映射是否執行的必須條件。POST主要根據該欄位(55AA)來判斷設備類型,以進行一些特別處理,例如,當為VGA設備時,POST就會將ROM 中的BIOS拷貝至RAM0C0000H處。

以上資料來自 老公公  百度空間
Peter Pan 修改整理.

PCI Expansion ROM(1)

1.Expansion ROM概述:
1.1 ROM存在的目的
           Expansion ROM的存在主要是為了Device可以在boot過程中使用,因為在Boot過程中,OS還沒有裝載進Memory,所以就沒有可能把任何 driverDISK拷貝進入Memory,所以devices在啟動過程中的enableinitialization都是通過 Expansion ROM裡的image來完成的。
1.2 Expansion ROM base address register
          這個暫存器位於配置空間的offset 30H位置處。它就是用來反應Expansion ROM的一些資訊和資源需求的。
      1.2.1   位址映射
         通過這個暫存器來判斷確定塊容量和分配位址範圍。首先判斷映射類型(即需要資源是Memory? I/O?),此暫存器的bit 0為唯讀位,用來標示映射類型:0-->記憶體空間,1-->I/O位址空間。

        * 記憶體基底位址暫存器:可以使32bits也可以是64bits的暫存器。其bit 1bit 2的對應類型如下表:
2和 位1
映射類型
00
基底位址暫存器為32位寬,可以在32位表示的記憶體位址範圍的任何地方進行映射
01
保留
10
基底位址暫存器為64位寬,可以映射到以64位表示的記憶體空間的任何地方
11
保留
至於bit 3,若資料是可預取的,就應將它設為1,否則清0。該暫存器的區域各位用來將一設備映射到記憶體空間。
基底位址暫存器中用於32位記憶體解碼器的bit31::4】和用於64位記憶體解碼器的bit63::4】稱為基底位址單元。它的作用是:確定與解碼器相關的記憶體的大小;給解碼器分配地址。如果記憶體設備需要小於4K的存儲空間,規範建議記憶體範圍強行設為4KB
*I/O基底位址暫存器
映射到I/O空間的基址暫存器寬度只能是32bits的暫存器(why?因為I/O port就那一點)。

其中bit 0值為1(用硬體實現的),bit 1為保留位並且其讀出值必須為0,其餘各位用來把設備映射到I/O空間。
當基底位址暫存器bit 0的返回值為1時,表示這是一個I/O解碼器,而不是記憶體解碼器,bit 1保留並總是返回0,【31::2】是基底位址單元,並用於確定需要的I/O塊容量,設置它的起始位址。
1.2.2塊容量和分配位址範圍
要確定記憶體的容量或I/O空間大小可以通過簡單地向基底位址暫存器寫入全“1”並回讀來確定。若返回一個是0值,則表示未實現基底位址暫存器;如果讀回地值為非0,則編程人員通過從基底位址單元的最低有效位元向上掃描返回值以找到第一個被成功置“1”bit來確定所需記憶體的容量或I/0空間的大小。假設暫存器的bit 0是一個加權二進位1,那麼bit 1的值就是2bit 2的值就是4,依此類推。這樣,在基底位址單元中第一個發現的1所對應的加權二進位值便是所需的空間數。這也是暫存器的第一個可R/W bit,在它之上的所有位均定義為可R/W bit。這個資訊發現後,程式將32/64位元記憶體起始位址或32I/O位址寫入基底位址暫存器中。
例如:寫入FFFFFFFFH,返回FFF00000H,這表明:
Bit 0=0,表示這是一個memory address decoder
Bits[2:1]=00,表示可以映射到32bits 記憶體任意位置。
Bit 3=0,表明這不是一個可預取的memory
Bit 20=1,表明bit 20是第一個值為1bit。那麼它的權為:220次方=1 048 576,這是一個記憶體大小1MB的解碼器。

以上資料來自 老公公  百度空間
Peter Pan 修改整理.

2010年10月28日 星期四

IE & FIREFOX

剛剛切換成IE時才發現,原來IE看到的字體那麼小,而且上面的時鐘版面也不完全.
因為個人是習慣使用FIREFOX,沒遇過那些問題.所以請多多見諒了!

PS:請有不同看法或是見解的可以留言給我唷!

Duplicate

當機器在測試的時候會碰到問題,也許不是你遇到的,而你需要知道這個問題是如何出現時,就需要duplicate.

因為不知道root cause,所以必須要有Steps to Reproduce.在成功 duplicate時又分為:
1. 100%
2. fail rate
這兩種.

如果是第一種當然是最好的了!可以直接開始分析找出root cause知道是誰該負責,或是可以開始debug.但如果是第二種時就非常麻煩了!就算已經可以duplicate,可能是幾百、幾千次以後才有一次fail,這時只能先推測發生的原因可能有哪些,再找個方向去做實驗,直到無法duplicate,上一次的實驗有可能就含有fail的原因.

所以在duplicate是要有方法的,不是一股腦的一直測試就行的,O.SDriverBIOSEC的版本不一樣就可能無法duplicate.第一步驟就是環境要相同.


當釐清問題後,是自己的部分造成時就要分析是否有更動過什麼,再去做實驗,雖然現在沒有任何部分是我更動的(),但也是可以學著找出發生問題的部分是跟哪些code有關,從他們updatecode去瞭解修改原因,這樣就不會只是duplicate卻不知道如何解決了!(雖然也不是我解決)