UEFI向SRAT 表中添加memory信息

从inf文件可以看到这是一个DXE_DRIVER,其入口函数是AcpiPlatformEntryPoint
[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = AcpiPlatform
  MODULE_UNI_FILE                = AcpiPlatform.uni
  FILE_GUID                      = cb933912-df8f-4305-b1f9-7b44fa11395c
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = AcpiPlatformEntryPoint

在其入口函数AcpiPlatformEntryPoint中会调用PlatformUpdateTables 来更新APCI的SRAT表
EFI_STATUS
PlatformUpdateTables (
  IN OUT EFI_ACPI_COMMON_HEADER       **Table
  )
{
  EFI_STATUS                              Status;
  EFI_ACPI_DESCRIPTION_HEADER             *TableHeader;

  Status = EFI_SUCCESS;
//强转指针后,调用UpdateAcpiTable来更新SRAT
  TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (*Table);

  UpdateAcpiTable(TableHeader, &Status);

  return Status;
}
VOID
UpdateAcpiTable (
  IN OUT EFI_ACPI_DESCRIPTION_HEADER      *TableHeader,
  IN OUT EFI_STATUS                       *CommonCodeReturnStatus
)
{
  switch ((TableHeader)->Signature) {

  case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
    *CommonCodeReturnStatus = UpdateSrat (TableHeader);
    break;

  case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
    *CommonCodeReturnStatus = UpdateSlit (TableHeader);
    break;
  }
  return;
}
根据Signature 来决定更新是srat还是slit。这里以srat为例

STATIC
EFI_STATUS
UpdateSrat (
  IN OUT EFI_ACPI_DESCRIPTION_HEADER  *Table
  )
{
  UINT8               Skt = 0;
  UINT8               Ch = 0;
  VOID*               HobList;
  GBL_DATA           *Gbl_Data;
  UINTN               Base;
  UINTN               Size;
  UINT8               NodeId;
  UINT32              DieInterleaveEn;
  UINT8               i;

  DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT memory information!\n" ));
// 原来这里也是从HOB中拿到memory的信息,也就说在SEC 阶段就已经建立好memory的HOB信息,后续所以关于硬件的信息其实都是从HOB中的到的.
  HobList = GetHobList();
  Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
  Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
  for(Skt = 0; Skt < MAX_SOCKET; Skt++){
      for(Ch = 0; Ch < MAX_NUM_PER_TYPE; Ch++){
          NodeId = Gbl_Data->NumaInfo[Skt][Ch].NodeId;
          Base = Gbl_Data->NumaInfo[Skt][Ch].Base;
          Size = Gbl_Data->NumaInfo[Skt][Ch].Length;
          DieInterleaveEn = Gbl_Data->NumaInfo[Skt][Ch].DieInterleaveEn;
          DEBUG((EFI_D_INFO,"Skt %d Ch: %d NodeId = %d, Base = 0x%lx, Size = 0x%lx, DieInterLeaveEn = %d\n",Skt,Ch,NodeId,Base,Size,DieInterleaveEn));
          if (Size > 0)
          {
              ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].ProximityDomain = NodeId;
              ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseLow = Base;
              ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
              ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthLow = Size;
              ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Memory[MemoryNode].LengthHigh = Size >> 32;
              MemoryNode = MemoryNode + 1;
          }
      }
  }

  //update gicc structure
  if(DieInterleaveEn != 0)
  {
      DEBUG(( EFI_D_ERROR, "\nSRAT: Updating SRAT Gicc information!\n" ));
      for (i = 0; i < 32; i ++)
          ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 0;
      for (i = 32; i < 64; i ++)
          ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) Table)->Gicc[i].ProximityDomain = 2;
  }

  //remove invalid memory node
  (VOID)RemoveInvalidMemoryNode (Table, MemoryNode);

  return EFI_SUCCESS;

}

这样在kernel初始化阶段就可以看到从SRAT表中得到memory信息

[    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x00000000-0x3fffffff]
[    0.000000] NUMA: Adding memblock [0x2000000000 - 0x2fffffffff] on node 1
[    0.000000] ACPI: SRAT: Node 1 PXM 1 [mem 0x2000000000-0x2fffffffff]
[    0.000000] NUMA: Adding memblock [0x1000000000 - 0x1fffffffff] on node 0
[    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x1000000000-0x1fffffffff]
[    0.000000] NUMA: Adding memblock [0x40000000000 - 0x4003fffffff] on node 2
[    0.000000] ACPI: SRAT: Node 2 PXM 2 [mem 0x40000000000-0x4003fffffff]
[    0.000000] NUMA: Adding memblock [0x42000000000 - 0x42fffffffff] on node 3
[    0.000000] ACPI: SRAT: Node 3 PXM 3 [mem 0x42000000000-0x42fffffffff]
[    0.000000] NUMA: Adding memblock [0x41000000000 - 0x41fffffffff] on node 2
[    0.000000] ACPI: SRAT: Node 2 PXM 2 [mem 0x41000000000-0x41fffffffff]


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UEFI memory指的是在UEFI环境下进行内存管理的一种机制。UEFI(Unified Extensible Firmware Interface)是一种新一代的固件接口标准,代替了传统的BIOS。在UEFI环境下,内存管理是通过UEFI提供的函数来进行的。 其中,UEFI提供的函数可以用来从指定类型的内存中分配一定大小的内存区域,并返回被分配的内存地址。这些函数会确保分配的内存是按八字节对齐的。 此外,UEFI还提供了另一类函数,用于分配一定数量的页面,并返回所分配页面范围的基址。这些函数会通过扫描内存映射来定位空闲的内存页面,并找到连续且足够大的页面来满足分配请求。一旦找到满足条件的页面,函数会修改内存映射,以指示这些页面的类型为MemoryType。 因此,UEFI memory管理涉及使用UEFI提供的函数来分配和管理内存,确保内存按需分配且对齐。这些函数提供了灵活的内存管理机制,用于支持不同类型和大小的内存分配需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [A Tour beyond BIOS Memory Map Design in UEFI BIOS](https://download.csdn.net/download/xiaoming141/10017477)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【BIOS/UEFIMemory Service(篇目二)DXE内存服务](https://blog.csdn.net/weixin_45258382/article/details/129850439)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值