ACPI Tables
  • System Descript Table Architecture
    • 兩種方可以取得 RSDP
      • EBDA 1K 的位置取的 RSDP 的 Address。
      • Signature 'RSD PTR' 在實體記憶體 E0000h ~ FFFFFh 中搜尋。
  • Root System Descript Pointer(RSDP)
    • BIOS 在開機過程中會把包在 BIOS ROM 中的 ACPI Table 載入到 RAM 中,然後留下一些資訊給 OS 來找到他們,Ex: RSDP Structure 會放在 1M 以下的某個位址(一般都是在 E0000h ~ FFFFFh),然後 OS 就可以透過搜尋 'Signature' 的方式來找到 ACPI Table Entry Point。
    • RSDP 保存在 Extended BIOS Data Area(EBDA) or in the BIOS Read-Only Memory Space。
    • RSDP 中存放了 RSDT/ XSDT Table Physical Address
  • Root System Description Table (RSDT)
    • RSDT Table 中有指向其他 Tables 的 Address,這些 Tables 向操作系統提供了基本系統實現和配置訊息。
    • RSDT 的位址由 RSDP 提供,RSDT 必定是第一張 Table
  • Extended System Descript Table(XSDT)
    • 與 RSDT 功能相同,提供64Bit Others Table Address
  • Fixed ACPI Description Table (FADT)
    • 包含 ACPI Fixed HW Register Blocks 的實作和配置詳細資訊的 Table,OS 用這些配置資訊來直接管理 ACPI Fixed HW Register Blocks & DSDT Table Address,DSDT Table 則包含其他平台的實作和配置詳細資訊。
    • OEM 廠商必須在 RSDT/ XSDT 中提供 FADF 給相容 ACPI 的 OS 。當系統啟動的時候, OS 則總是把已經定義好了的 Namespace 資訊 (存放於DSDT 的 Differentiated Definition Block中) 插入到 ACPI Namespace,並且 OS 絕對不會刪除它。
    • FADT 包含以下三種資訊
      • Firmware ACPI Control Structure(FACS)
      • Differentiated System Description Table(DSDT)
      • Fixed Register
  • Firmware ACPI Control Structure (FACS)
    • BIOS 用它來實作 Firmware 的 OS 之間的資訊交換 (Handshaking)。透過 FADT Table , FACS 被轉到相容 ACPI 的 OS 中。
    • FACS 包含以下資訊
      • HW Signature(Wake up from S4)
        • 紀錄系統最後一次 Boot 資訊的硬體簽章
        • 當 OS 要進入 S4 , BIOS 會根據 HW Configuration 去計算填寫這個 Value,將它存放於 Non-Volatile Memory ,當 OS 要從 S4 Wake up,會透過比對這個 Value ,看硬體規劃是否有變動,來決定是否 Restore Information。
      • Firmware Waking Vector
        • 這代表 OS 要進入 Sleeping State ,會去紀錄一個 Waking 的 Vector 在這個欄位,當 OS 要 Wake up 時, BIOS 會去看這個 Waking Vector,就知道要從哪個 Address Wake up 。喚醒的 Address 是位在 1MB之下,程式會將控制權交給 Real Mode。
      • Global Lock
        • OS 和 BIOS 根據需求可能會去存取相同的 HW Register , 那可能會造成搶資訊的狀況。
  • Differentiated System Description Table(DSDT)
    • 存放了一些 Event Code,當某個 HW Event 發生後,系統 OS 會去依照描述在這個 DSDT Table 中的 AML Code 去執行,而這些 ACPI Table 包在 BIOS ROM 中的形式是 AML Code(類似機器碼)。
    • 在 Differentiated Definition Block 中存放了 Basic System HW Model ,無法被卸載當 OEM 廠商需要加入自己的 Control Method 時,則需要透過 SSDT 去增加 Action
  • Secondary System Description Table (SSDT)
    • SSDT 是 DSDT 的延伸,其中也是存放 Definition Block,可以有多個 SSDT ,允許 OEM 廠商提供一些基本的支援或增加一些較小的系統功能。
  • Alert Standard Format Table (ASF!)
    • 定義了 Alerting & Corrective Action 的標準基礎介面,使 OEM 廠商可以實作產品並確保其相互操作性。
  • Multiple APIC Description Table (MADT)
    • 描述系統上與 Interrupt 相關的資訊。
    • ACPI Support 三種 Interrupt Model。
      • Dual 8259(PIC Model)
      • ACPI Model
      • SAPIC Model
    • OSPM 會透過 MADT 裡面的 Information 去決定讓 System 運作在 APIC or SAPIC Mode下。
  • Simple Boot Flag Table (BOOT)
    • OS 可以透過 Boot Table 與 BIOS 聯絡構通下次開機時的行為。
    • 存放於 BIOS Memory 的 Boot Register 中。
    • 當 OS 為 EFI System 時,SimpleBootFlag Global Variable 無論是在 Boot 或 Runtime 時都是可以使用的。
  • Software Licensing Description Table (SLIC)
    • ACPI Table 可以用來當作OS 啟動金鑰,OS 透過檢查包在 BIOS ROM 中的 ACPI Table 的內容來決定是不是一個台 OEM 電腦。
  • PCI Express Memory Mapped Configuration Space Base Address Description Table (MCFG)
    • 對於 PCI Configuration Space 的存取,不只可以透過 I/O(CF8/CFC) 的方式,也可以透過 Memory 的方式去存取 Configuration Space 的 Information。
    • 我們可以透過 MCFG Table 上面的 Base Address 來 Mapping 到 PCI Configuration Space Memory 的起始位置,透過這個起史位置就可以計算出選定的 PCI Configuration Space 。
  • Other Tables...

文章內容來源:APCI Spec 5.0 以上內容如有不符合 Spec. 中敘述,那百分百是小弟的理解有錯,請以 Spec. 上為主。

  • Implement
    • 使用 Windows API
    UINT WINAPI EnumSystemFirmwareTables(
         _In_ DWORD FirmwareTableProviderSignature,
         _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableEnumBuffer,
         _In_ DWORD BufferSize
    );
    UINT WINAPI GetSystemFirmwareTable(
        _In_ DWORD FirmwareTableProviderSignature,
        _In_ DWORD FirmwareTableID,
        _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
        _In_ DWORD BufferSize
    );
    • 讀取 ACPI Tables

// 第一次先取得 ACPI Tables Enum Buffer Size
PBYTE buffer;
DWORD buffer_size = EnumSystemFirmwareTables('ACPI', 0, 0);
if (buffer_size == 0)
   return false;

// 產生一塊Buffer去取得 ACPI Tables Enum
buffer = new BYTE[buffer_size];
if (EnumSystemFirmwareTables('ACPI', buffer, buffer_size) != buffer_size)
{
   free(buffer);
   return false;
}

for (unsigned __int32 i = 0; i < buffer_size; i = i + 4)
{
   DWORD fw_table_id = (*(DWORD *)(buffer + i)));

   PBYTE table_uffer;
   DWORD table_buffer_size;
   if(GetSystemFirmwareTable(' ACPI', table, buffer, buffer_size)){
      typedef struct _sACPITableHeader {
         BYTE Signature[4];
         DWORD Length;
         BYTE Revision;
         BYTE Checksum;
         BYTE OEMID[6];
         BYTE OEMTableID[8];
         DWORD OEMRevision;
         BYTE CreatorID[4];
         DWORD CreatorRevision;
     } sACPITableHeader;

     // 取的 ACPI Table Buffer
     //...
   }
}

free(buffer);

arrow
arrow

    語 發表在 痞客邦 留言(0) 人氣()