共用方式為


使用 AcpiGenFx 產生 ACPI 數據表

備註

Microsoft支持多樣化的包容性環境。 本篇文章包含Microsoft 樣式指南 認為具有排他性的術語參考,這些術語屬於無偏見溝通方式中所不建議使用的。 本文中會使用單字或片語來保持一致性,因為它目前會出現在軟體中。 當軟體更新以移除該語言時,本文也將進行更新以保持一致。

總結

  • 建立使用 AcpiGenFx 來產生 ACPI 資料表的 .NET 應用程式

適用對象

  • Windows 10

  • Windows SoC 和平台啟動

重要 API

  • 在物件瀏覽器中開啟 AcpiGenFx

  • 使用 Visual Studio 中的 IntelliSense 功能來判斷方法和屬性

使用 ACPI 世代架構 (AcpiGenFx) 連結庫來撰寫產生 ACPI 數據表的應用程式。

在 Windows 10 中,新的 C# 連結庫 AcpiGenFx 可讓您更輕鬆地撰寫應用程式,以建立 ACPI 數據表來描述平臺上的硬體裝置和資源,例如中斷控制器、SD 主機控制器、GPIO 和I 2C 裝置。 藉由使用架構物件所公開的方法和屬性,您可以描述裝置、資源和相依性,而不需要知道 ACPI 數據表的確切語法或參考 ACPI 規格。 AcpiGenFx 不僅會產生與OS無關的ACPI機器語言 (ASL) 程序代碼,也瞭解 Windows 特定需求。

應用程式會根據這些描述產生相關的 ACPI 資料表檔案 (*.aslc 和 *.asl)。 在建置階段,AcpiGenFx 會靜態分析平臺描述、偵測週期性或未解決的相依性、裝置命名和 UUID 衝突、控制器對應的資源等等錯誤。 因此,產生的 ASL 程式代碼更容易偵錯,因為 AcpiGenFx 會檢查最常見的錯誤,並擷取唯一的 ACPI 實作詳細數據。

AcpiGenFx 本質上是宣告式:其輸出只是靜態數據,而且不是設計來產生動態運行時間方法。 如果架構未涵蓋使用案例,例如進階 off-SoC 周邊裝置電源管理,則必須在 Windows 平台擴充功能驅動程式中實作方法,或手動新增至 AcpiGenFx 產生的 ASL 程式代碼。

開始之前

在 WDK 安裝的 AcpiGenFx 資料夾中找出下列檔案。

WDK 的 [工具] 資料夾中提供 AcpiGenFx.dll 和相關聯的範例。 在 [工具] 目錄中,流覽至目標架構資料夾,然後流覽至 AcpiGenFx 資料夾。 例如,x86 版本位於 C:\Program Files (x86)\Windows Kits\10\Tools\x86\ACPIGenFx 中。

  • AcpiGenFx.dll

    需要使用 ACPIGenFx。

  • DSDT樣本

    使用此專案做為起點,設計整個平臺的ACPI韌體。 輸出是一組完整的 ACPI 數據表,包括 DSDT、FADT 和 MADT。

  • SSDTSamples

    使用此項目作為起點,將周邊裝置新增至現有的系統。 此範例示範如何描述感測器裝置及其資源。 輸出是 ASL 中的 ACPI SSDT 資料表。

下載 Windows 10 套件、工具和程式代碼範例。

建立平臺

  1. 在 Visual Studio 中,開啟新的 C# 控制台專案。

  2. 新增對 AutoAcpi.dll 組件的參考。 在 [ 專案] 功能表下,按兩下 [ 新增參考]。 按一下 瀏覽 並瀏覽至 AutoAcpi.dll的位置。 按一下 [確定]

  3. [方案總管] 中,展開 [參考 ],然後選取 acpigenfx。 在物件瀏覽器中檢視物件(檢視 > 對象瀏覽器)。

  4. 以 .NET Framework 4.5 或更新版本為目標。 開啟項目屬性。 在 [ 應用程式] 頁面上,確定 [目標架構 ] 設定為 .NET Framework 4.5

  5. Using在應用程式的程式代碼開頭新增 AutoAcpi 物件的 指示詞。

  6. 建立平台物件。 根據您的架構,呼叫 Platform.CreateArmPlatformPlatform.Createx86Platform 來具現化 Platform 物件。 指定 OEMIDOEMTableIDCreatorRevisionFileName

  7. 呼叫 Platform.WriteAsl 以寫入檔案。

    此範例示範如何具現化平臺。

    using AutoAcpi;
    
    namespace ACPI
    {
        class Program
        {
            static void Main(string[] args)
            {
                ArmPlatform myPlatform = Platforms.CreateArmPlatform(
                    OEMID: "MSFT",
                    OEMTableID: "EDK2",
                    CreatorID: "MSFT",
                    Revision: 1,
                    FileName: "Platform");
    
                myPlatform.WriteAsl();
            }
        }
    }
    
  8. 按兩下 [開始 ] 建置並執行您的應用程式。 Visual Studio 會在 [輸出] 視窗中顯示建置進度。 (如果看不到 [輸出] 視窗,請選擇 [檢視] 功能表中的 [輸出]。

  9. 開啟 project\bin\Debug 或 Release\Output 下名為 的資料夾。 [輸出] 資料夾包含應用程式所產生的檔案。 檢視 SSDT.asl 的內容。

    以下是上述範例的輸出。

    DefinitionBlock ("Platform.aml", "DSDT", 5, "MSFT", "EDK2", 1)
    {
        Scope (\_SB_)
        {
        }
    
    }
    

應用程式會產生兩個額外的資料夾:Aslc 和 Bin。 Aslc 包含 aslc 格式的所有韌體數據表。 Bin 包含二進位 Blob 格式的所有韌體數據表。

使用 WDK 中提供的 asl.exe 編譯程式,將 ASL 程式代碼檔案編譯為 ACPI 機器語言 (AML) 二進位檔。

在 DSDT 中新增裝置和資源

您可以將元件新增至平臺。 這些元件通常包括處理器、總線控制器、電源資源等等。 以下是 DSDTSamples 中使用的一些元件。

物件類型 建立方法 元件
ACAdapter Platform.AddACAdapter 新增 AC 配接器。
電池裝置 平台.新增電池設備

電池裝置.熱限制
新增電池裝置並指定其熱限制。
按鈕陣列裝置 Platform.AddButtonArrayDevice

ButtonArrayDevice.AddBackButton

ButtonArrayDevice.新增相機快門按鈕

ButtonArrayDevice.AddCameraAutofocusButton

ButtonArrayDevice.新增通用按鈕

ButtonArrayDevice.新增電源按鈕

ButtonArrayDevice.新增螢幕旋轉鎖定按鈕

按鈕陣列設備.添加搜尋按鈕

ButtonArrayDevice.AddVolumeDownButton

ButtonArrayDevice.AddVolumeUpButton

按鈕陣列設備.新增Windows主畫面按鈕
新增按鈕,例如 Windows、返回、音量 +/-、電源、旋轉鎖定和搜尋。
顯示感應器 平台.添加顯示感測器 新增顯示感測器。
通用裝置 平台.添加通用設備 新增一般裝置,可用來取代架構中任何支援的內部裝置類型。
GpioController Platform.AddGpioController 新增 GPIO 控制器和相關聯的資源,例如中斷、I/O 和事件。
HidOverI2C Platform.AddHidI2CDevice 新增連線到 I2C 總線的 HID 裝置。
I2CController Platform.AddI2C控制器 新增 I2C 控制器和相關聯的資源,例如中斷、I/O 和事件。
KDNet2Usb 平台.AddKDNet2Usb (添加 KDNet 到 USB) 使用 Kdnet over USB 新增核心偵錯的支援。
PEPDevice Platform.AddPepDevice 新增 PEP 裝置以及其資源和方法,以傳回封裝和靜態類型。
處理器

處理器匯集器
平台.添加處理器

Platform.AddProcessorAggregator
新增處理器和處理器匯總工具。
RTCDevice Platform.AddRTCDevice 新增 ACPI 時間和警報裝置。
SdHostController 平台.新增SdHost控制器 新增 SD 主機控制器。
SerialPort 平台.新增序列埠 新增序列和 UART 裝置的支援。
ThermalZone Platform.AddThermalZone 新增熱能區域和相關聯的取樣和監控頻率。
Xhci USB 控制器

EhciUsbController

USB裝置
Platform.AddEhciUsbController

Platform.AddXhciUsbController

EhciUsbController.AddUsbDevice

XhciUsbController.AddUsbDevice

UsbDevice.AddUsbDevice(新增USB設備)
新增USB主機控制器和其子設備(包括集線器)。

若要檢視完整清單,請在 對象瀏覽器中開啟 AcpiGenFx。 使用 IntelliSense 來判斷物件所公開的方法(和參數)和屬性。 如需示範如何新增類別和設定上表所列屬性的範例程序代碼,請參閱 DSDTSamples 專案。

新增偵錯支援

若要將埠設定為可偵錯,請將 物件上的 DebugEnabled 屬性設定為 「true」。

例如,您可能想要使用 USB 偵錯埠來描述 xHCI 主機控制器。 在您的應用程式中,呼叫 Platform.AddXhciUsbController 以取得 XhciUsbController 物件,並將 DebugEnabled 屬性設定為 “true”。 AcpiGenFx 會產生自動包含在應用程式的 Output\Aslc 資料夾中的 Microsoft DBG2 資料表。

以下是如何新增 xHCI 主機控制器並將其宣告為可偵錯的範例。

XhciUsbController usb1 = Platform.AddXhciUsbController("USB1", "XHCICONT", 0);
usb1.Description = "USB Controller with Debug Support";

Memory32Fixed mem = usb1.AddMemory32Fixed(true, 0xf9000000, 0xfffff, "");
usb1.AddMemory32Fixed(true, 0xf7000000, 0xfffff, "");
usb1.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Shared, 0x8);
usb1.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Shared, 0x9);

usb1.DebugEnabled = true;
mem.DebugAccessSize = DebugAccessSize.DWordAccess;

在上述代碼段中,xHCI 主機控制器具有中斷資源和偵錯支援。 它依賴於 PEP 裝置和 GPIO 控制器。 若要查看這些裝置的描述,請參閱 DSDTSamples。

此範例示範如何將 I2C 控制器新增至 DSDT。

I2CController i2c = Platform.AddI2CController("I2C1", "I2CCONTR", 0);
i2c.AddMemory32Fixed(true, 0xf9999000, 0x400, "");
i2c.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Exclusive, 40);

以下是主控台應用程式的輸出,其中包含 xHCI 主機和 I2C 控制器先前的定義。

DefinitionBlock ("Platform.aml", "DSDT", 5, "MSFT", "EDK2", 1)
{
    Scope (\_SB_)
    {
        //
        // Description: USB Controller with Debug Support
        //

        Device (USB1)
        {
            Name (_HID, "XHCICONT")
            Name (_CID, "PNP0D10")
            Name (_UID, 0x0)
            Method (_STA)
            {
                Return(0xf)
            }
            Method (_CRS, 0x0, NotSerialized) {
                Name (RBUF, ResourceTemplate () {
                    MEMORY32FIXED(ReadWrite, 0xF9000000, 0xFFFFF, )
                    MEMORY32FIXED(ReadWrite, 0xF7000000, 0xFFFFF, )
                    Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 0x8 }
                    Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 0x9 }
                })
                Return(RBUF)
            }
        }

        //
        // Description: This is an i2cController.
        //

        Device (I2C1)
        {
            Name (_HID, "I2CCONTR")
            Name (_CID, "")
            Name (_UID, 0x0)
            Method (_STA)
            {
                Return(0xf)
            }
            Method (_CRS, 0x0, NotSerialized) {
                Name (RBUF, ResourceTemplate () {
                    MEMORY32FIXED(ReadWrite, 0xF9999000, 0x400, )
                    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 0x28 }
                })
                Return(RBUF)
            }
        }

    }

}  

建置項目之後,在專案目錄中流覽至 Output\Aslc。 Dbg2.aslc 檔案包含如下所示的 DB2 數據表:

// Debug Port Table (DBG2)
// Automatically generated by AutoAcpi

#include "AutoACPI.h"
char DBG2[112] = {
    0x44, 0x42, 0x47, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x4D, 0x53, 0x46, 0x54, 0x20, 0x20, 0x45, 0x44, 0x4B, 0x32,
    0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x4D, 0x53,
    0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x02, 0x0E, 0x00,
    0x36, 0x00, 0x00, 0x00, 0x44, 0x00, 0x02, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x16, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x03,
    0x00, 0x00, 0x00, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0x00,
    0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0x22, 0x5C,
    0x5C, 0x5F, 0x53, 0x42, 0x5F, 0x2E, 0x55, 0x53, 0x42, 0x31,
    0x22, 0x00
};

void * ReferenceDBG2Table(void) {
    return (void *) &DBG2;
}

在 SSDT 中新增周邊裝置的 ACPI 描述

  1. 呼叫 Platform.CreateArmPlatformPlatform.Createx86Platform 來建立平台物件。

  2. SSDT 屬性設定為 true。 這表示框架識別此表格為 SSDT。

  3. 建立裝置並指派資源。 例如,針對此處顯示的感測器裝置,範例會呼叫 Platform.AddGenericDevice ,並指定裝置名稱、硬體標識碼和唯一實例。 連接到 I2C 序列總線 I2C1 的感測器裝置,正如 DSDT 中所描述。

namespace SSDTSample
{
    class Program
    {
        static void Main(string[] args)
        {

          ArmPlatform Platform = Platforms.CreateArmPlatform(
                OEMID: "MSFT",
                OEMTableID: "EDK2",
                CreatorID: "MSFT",
                Revision: 1,
                FileName: "SSDT"
                );

            platform.SSDT = true;

            var sensor = platform.AddGenericDevice("ADXL", "ACPI\\ADXL345Acc", 1);

            sensor.AddI2CSerialBus(
                SlaveAddress: 0x1d,
                Mode: SlaveMode.ControllerInitiated,
                ConnectionSpeed: 400000,
                addressmode: AddressMode._7Bit,
                controllername: "I2C1"
                );

            platform.WriteAsl();

        }
    }
}

以下是上述範例的輸出。

DefinitionBlock ("SSDT.aml", "SSDT", 5, "MSFT", "EDK2", 1)
{
    Scope (\_SB_)
    {

        Device (ADXL)
        {
            Name (_HID, "ACPI\ADXL345Acc")
            Name (_UID, 0x1)
            Method (_STA)
            {
                Return(0xf)
            }
            Method (_CRS, 0x0, NotSerialized) {
                Name (RBUF, ResourceTemplate () {
                    I2CSerialBus(0x1D, ControllerInitiated, 0x61A80, AddressingMode7Bit, "I2C1", 0, ResourceConsumer, , RawDataBuffer() { 0 })
                })
                Return(RBUF)
            }
        }

    }

}

在開發和測試期間替換 ACPI 韌體

在開發和測試案例中,您可以取代裝置上 asl.exe 編譯程式所產生的 AML 二進位檔。 若要這樣做,請將 AML 二進位檔重新命名為 acpitabl.dat,並將它移至 \system32 %windir%。 在開機時,Windows 會以acpitabl.dat中的數據表取代 ACPI 韌體中的數據表。

請確定已使用 命令啟用測試簽署:

bcdedit /set testsigning on

ACPI 系統描述數據表