uefi对acpi的support

uefi-master\IntelFrameworkModulePkg\Universal\Acpi\AcpiSupportDxe
从inf文件可以看出这是一个DXE_DRIVER,其入口函数是InstallAcpiSupport
[Defines]
  MODULE_TYPE                    = DXE_DRIVER
  ENTRY_POINT                    = InstallAcpiSupport
在InstallAcpiSupport 中使用AllocateZeroPool 申请memory
然后调用AcpiSupportAcpiSupportConstructor初始化ACPI表,最终调用
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &mHandle,
                    &gEfiAcpiTableProtocolGuid,
                    &PrivateData->AcpiTableProtocol,
                    NULL
                    );


来注册gEfiAcpiTableProtocolGuid。
这样在后续中就可以通过
  //
  // Get AcpiTable Protocol.
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
  if (EFI_ERROR (Status)) {
    return Status;
  }
 来找到gEfiAcpiTableProtocolGuid的interface,然后就可以使用gEfiAcpiTableProtocolGuid提供的函数了。
   Status = AcpiTableProtocol->InstallAcpiTable (
                                AcpiTableProtocol,
                                &mFirmwarePerformanceTableTemplate,
                                mFirmwarePerformanceTableTemplate.Header.Length,
                                &mFirmwarePerformanceTableTemplateKey
                                );
我们来看看gEfiAcpiTableProtocolGuid提供了哪些函数。
EFI_STATUS
AcpiSupportAcpiSupportConstructor (
  IN EFI_ACPI_SUPPORT_INSTANCE                 *AcpiSupportInstance
  )
{
  InitializeListHead (&AcpiSupportInstance->TableList);
  AcpiSupportInstance->CurrentHandle              = 1;
  AcpiSupportInstance->AcpiSupport.GetAcpiTable   = GetAcpiTable;
  AcpiSupportInstance->AcpiSupport.SetAcpiTable   = SetAcpiTable;
  AcpiSupportInstance->AcpiSupport.PublishTables  = PublishTables;


  AcpiSupportInstance->AcpiTableProtocol.InstallAcpiTable   = InstallAcpiTable;
  AcpiSupportInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;
}
通过trace AcpiSupportAcpiSupportConstructor,就可以知道gEfiAcpiTableProtocolGuid提供了哪些函数。
在AcpiSupportAcpiSupportConstructor 中还会申请RSDP的memory,并将AcpiSupportInstance->Rsdp1
指向申请的Pointer。从下面的code中可以看出同时支持ACPI_1/ACPI_3
  //
  // Create RSDP table
  //
  RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +
                  sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);


  PageAddress = 0xFFFFFFFF;
  Status = gBS->AllocatePages (
                  AllocateMaxAddress,
                  EfiACPIReclaimMemory,
                  EFI_SIZE_TO_PAGES (RsdpTableSize),
                  &PageAddress
                  );


  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }


  Pointer = (UINT8 *) (UINTN) PageAddress;
  ZeroMem (Pointer, RsdpTableSize);


  AcpiSupportInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
  Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  AcpiSupportInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
还support Rsdt1/Rsdt3/Rsdp1/Rsdp3等子表。
最后会调用
EFI_STATUS
ChecksumCommonTables (
  IN OUT EFI_ACPI_SUPPORT_INSTANCE                 *AcpiSupportInstance
  )
{
  //
  // RSDP ACPI 1.0 checksum for 1.0 table.  This is only the first 20 bytes of the structure
  //
  AcpiPlatformChecksum (
    AcpiSupportInstance->Rsdp1,
    sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
    OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
    Checksum)
    );
}
来为每张子表计算checksum,这样如果怀疑uefi传递给kernel的acpi表有误,可以通过计算checksum的方式确定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值