2019年8月30日 星期五

General-Purpose Event (GPE)


本篇文章參考
ACPI Specification Version 6.3
Vol. 1: Intel® 200 and Z370 Series Chipset Families PCH
Vol. 2: Intel® 200 and Z370 Series Chipset Families PCH

Fixed ACPI Description Table (FADT)

Field   Byte Length   Byte Offset   Description  
Signature   4   0   'FACP'  
......   ......   ......   ......  
GPE0_BLK   4   80   GPE 0 Register Block 的 port address。
若不support,則值為0。
GPE1_BLK   4   84   GPE 1 Register Block 的 port address。
若不support,則值為0。
......   ......   ......   ......  
GPE0_BLK_LEN   1   92   GPE 0 Register Block 所decode 的bytes 長度。
其值必為2的正指數冪。
GPE1_BLK_LEN   1   93   GPE 1 Register Block 所decode 的bytes 長度。
其值必為2的正指數冪。
GPE1_BASE   1   94   GPE1 events在ACPI general-purpose event中
的offset。GPE0 events 的offset為0。
......   ......   ......   ......  

General-Purpose Event Register Blocks

ACPI 在FADT table定義了兩組GPE register blocks,GPE 0與GPE 1。register block包含 enable
與 status register(ex:GPE0_EN與GPE0_STS),這兩個register長度各佔 register block長度的
一半,所以 FADT中 register block的長度 GPE0_BLK_LEN與 GPE1_BLK_LEN必為2的冪次。


使用RWEverything讀取GPE Register Block


從 FADT table 中可得 GPE0的 IO port addresss為 0x1880,和其使用的長度為 0x20。


與 Intel PCH spec對照,可從 PMC Controller (D31:F2)的 Offset 40-43h讀出 ACPI Base
Address,用 RW讀出其值為 0x1801,bit 1代表為IO space,所以其IO address為0x1800。



與 Spec中的 PMC I/O Based Register 對照,Offset 0x80為 GPE0 block register起始位置,跟
FADT table位置為0x1880 (0x1800 + 0x80) 符合。


再用RW 讀取IO address 0x1880,就可得出GPE0 Register Block位置。若要知道GPE register 每
個bit所對應實際上的pin腳,則需參考chipset實際上的設定。



\_GPE

為ACPI predefined 的namespace,用以處理GPE register block中的General events。

使用RWEverything讀取\_GPE


以我所使用的主機板為例,\_GPE中定義了_E02 的Method,表示其為 handle GPE0_STS bit2
edge event的method。


2019年7月4日 星期四

在Windows 使用gcc - Cygwin


官方網址

http://www.cygwin.com/

Cygwin 可以讓我們在Windows 上執行Liunx或Unix-like的軟體,包含gcc。

要搭建基本的gcc C/C++開發環境,除本身預設安裝的套件外,需額外安裝幾個套件
  Categories    Package     Description  
Develgcc-coreGNU Compiler Collection (C, OpenMP)
Develgcc-g++GNU Compiler Collection (C++)
DevelmakeThe GNU version of the 'make' utility
Develbinutils GNU assembler, linker and similar utility
Develgdb The GNU debugger


test.c

#include <stdio.h>
int main() {
  printf("Hello World!\n");
  return 0;
}


編譯test.c並輸出test.exe
$ gcc test.c -o test

執行test.exe
$ ./test.exe
Hello World!


在Cygwin上安裝新的套件


1. 執行原本安裝時所使用的安裝檔(如果遺失就直接重新下載)。


2. 選擇"Download Without Installing",只下載套件不安裝。並在「Select Local Package Directory」的頁面中選擇之前安裝套件所使用的資料夾。


3. 接著選擇需要的套件下載。

4. 下載完成後,再執行Cygwin安裝檔,選擇"Install from Local Directory"來從下載好的套件安裝。

5. 在「Select Root Install Directory」選擇先前Cygwin所安裝的路徑。並一樣在
「Select Local Package Directory」的頁面中選擇之前安裝套件所使用的資料夾,
之後找到所選擇的套件進行安裝即可。

2021/07/02 Note: 安裝新套件的步驟2可直接選擇"Install from Internet",相當於步驟3到5。

2019年4月25日 星期四

USB多重開機選單製作工具 - YUMI


官方網址

https://www.pendrivelinux.com
https://www.pendrivelinux.com/yumi-multiboot-usb-creator

YUMI可在USB儲存裝置上建立多重開機選單,目前支援建立Windows 10、Ubuntu等常見OS選
單,也支援像是MemTest86的系統測試工具。


Step 1: 選擇USB磁碟磁區
Step 2: 選擇要加入的OS
Step 3: 選取OS ISO檔的路徑

2019年3月30日 星期六

Beyond BIOS Note - CH2 Basic UEFI Architecture


I believe in standards. Everyone should have one.
- George Morrow

UEFI System table

  • UEFI Boot Services
  • UEFI Runtime Services
  • Protocol Services

Handle Database

由Handle 與Protocol 組成,Handle 是Protocol 的集合,而Protocol 則是以GUID 識別的資
料結構,用來提供系統的資訊及服務。

在UEFI系統初始階段,由UEFI Driver 建立Handle 並且安裝一個或多個Protocol 在其上,而
這些Handle會被記錄在由系統韌體所管理的Handle database 中。

Protocol

  • Driver
  • 在系統初始階段會根據系統的需求來建立相關的Protocol。

  • Protocol
  • 以GUID 為識別,為包含function pointer 與data 的結構。

  • Working with Protocols
  • Handle database 在ExitBootServices() 之後就無法使用。

  • Multiple Protocol Instances
  • Driver 會安裝特定Protocol 的多個instance在不同的handle 上。例如PCI bus driver
    會負責安裝PCI I/O Protocol在不同的Device Handle上,這些instance 包含PCI
    Device獨有的數值,像是Option ROM的位置及Size。

  • Tag GUID
  • Protocol可以不包含任何東西,僅用Protcol GUID作識別用,可以方便系統找到特定的Handle。

UEFI Images

UEFI image by processor type

  • UEFI applications
  • 在Application exit之後,image其使用的記憶體將會被系統回收。

  • UEFI Boot Service drivers
  • 在ExitBootServices ()之後,image其使用的記憶體將會被系統回收。

  • UEFI Runtime drivers
  • 在ExitBootServices ()之後依然存在,可以被UEFI OS執行。

Start an UEFI image

  1. gBS->LoadImage()
  2. gBS->LoadImage() 的流程
    1. Allocate image所要被加載的記憶體位置
    2. Relocation fix-up
    3. 在Handle database建立一個image handle,並且安裝
      EFI_LOADED_IMAGE_PROTOCOL 的Instance。

  3. gBS->StartImage()

Image entry point

Image 的entry point會接收到兩個參數
  • Image 所在的Hangle
  • 讓 Image能知道從哪裡被加載及加載後的記憶體位置。

  • 指向 UEFI System Table的指標
  • 讓Image 可以調用UEFI 系統服務。

OS Loader

在OS Kernel取得控制權之前,由OS Loader負責去呼叫ExitBootServices()。

Event and Task Priority Levels

一個Event可以被create或者destroy,且只能是signaled state或waitiing state其中一種狀態。
最常見的應用是讓UEFI driver使用timer event來輪詢(polling)需要服務的device。

Elements associated with Event

  • Notification function
  • Wait Event在waited upon及Signal event從waiting state變成signaled state時所執
    行的function。

  • Notification context
  • 傳入Notification function的參數。

  • Task Priority Level(TPL)
  • Notification function的優先執行順序(priority)
    • TPL_APPLICATION
    • TPL_CALLBACK
    • TPL_NOTIFY
    • TPL_HIGH_LEVEL
    當多個event都在signaled stated時,會依TPL來執行notification function。而TPL 較高的event會中斷TPL較低的event。

    Driver在可以暫時提高TPL來避免其他的event衝出造成使用相同的data structure而衝突。


2019年3月17日 星期日

Memory Type Range Register (MTRR)

MTRR 為幾組CPU 所提供的MSR 暫存器,用來描述記憶體的區段讓CPU知道該用哪一種
Cache模式來存取。

CPU可用的快取模式為下列幾種
                       
  Memory Type and Mnemonic    Encoding in MTRR  
Uncacheable (UC)00H
Write Combining (WC)01H
Reserved02H
Reserved03H
Write-through (WT)04H
Write-protected (WP)05H
Write-back (WB)06H
Reserved07H-FFH


可藉由讀取CPUID判斷此CPU支不支援MTRR
CPUID Function 0x00000001, EDX
bit 12 - MTRR supported

MTRRCap - MTRR Capabilities

0x000000FE


bit 0-7 (VCNT) - Variable range register 的數量
bit 8 (FIX) - 是否支援Fixed range register
bit 10 (WC) - 是否支援Write Combining的cache type
bit 11 (SMRR) - 是否支援SMRR

MTRR 可以分為兩種,Fixed range register 與Variable range register,1MB記憶體以下位置的
cache 是由Fixed range register來控制,1MB以上就由Variable range register控制,剩下未被
指定的記憶體區塊就由 MTRRdefType (0x000002FF) 的bit0-7 來決定。



MTRRdefType - MTRR Default Memory Type

0x000002FF


bit 0-7 (Type) - 未被MTRR指定的Memory cache type
bit 10 (FE) - Enable Fixed MTRR
bit 11 (E) - Enable MTRR


1MB以下的記憶體由Fixed Range MTRR控制,可分為一組64k、兩組16k和八組4k,每組中可指
定八段range。

MtrrVar_64K

0x00000250

MtrrVar_16K

0x00000258, 0x00000259

MtrrVar_4K

0x00000268 - 0x0000026F


bit 0-3 (Type) - Memory cache type


1MB以上的記憶體可用Variable Range MTRR來控制,由Base與Mask成對組成,並可以指定長
度,其支援的數量可由MTRRCap的VCNT讀出

MtrrVarBase

0x00000200, 0x00000202, ...

bit 0-7 (Type) - 指定range的Memory cache type
bit 12-MAXPHYADDR (PhysBase) - 後面補上3個0,即為base address
  MAXPHYADDR為CPU的定址能力,可從CPUID Function 0x80000008讀出

MtrrVarMask

0x00000201, 0x00000203, ...

bit 11 (V) - 此組MTRR是否有效
bit 12-MAXPHYADDR (PhysMask) - 後面補上3個0,再取2的補數,即為MTRR長度
  Address_Within_Range & PhysMask == PhysBase & PhysMask