DXE 其它服务

EDKII 中实现DXE Foundation 的源代码位于MdeModulePkg\Core\Dxe 目录下。

/**
  Introduces a fine-grained stall.

  @param  Microseconds           The number of microseconds to stall execution.

  @retval EFI_SUCCESS            Execution was stalled for at least the requested
                                 amount of microseconds.
  @retval EFI_NOT_AVAILABLE_YET  gMetronome is not available yet

**/
EFI_STATUS
EFIAPI
CoreStall (
  IN UINTN            Microseconds
  )
{
  UINT64  Counter;
  UINT32  Remainder;
  UINTN   Index;

  if (gMetronome == NULL) {
    return EFI_NOT_AVAILABLE_YET;
  }

  //
  // Counter = Microseconds * 10 / gMetronome->TickPeriod
  // 0x1999999999999999 = (2^64 - 1) / 10
  //
  if ((UINT64) Microseconds > 0x1999999999999999ULL) {
    //
    // Microseconds is too large to multiple by 10 first.  Perform the divide
    // operation first and loop 10 times to avoid 64-bit math overflow.
    //
    Counter = DivU64x32Remainder (
                Microseconds,
                gMetronome->TickPeriod,
                &Remainder
                );
    for (Index = 0; Index < 10; Index++) {
      CoreInternalWaitForTick (Counter);
    }

    if (Remainder != 0) {
      //
      // If Remainder was not zero, then normally, Counter would be rounded
      // up by 1 tick.  In this case, since a loop for 10 counts was used
      // to emulate the multiply by 10 operation, Counter needs to be rounded
      // up by 10 counts.
      //
      CoreInternalWaitForTick (10);
    }
  } else {
    //
    // Calculate the number of ticks by dividing the number of microseconds by
    // the TickPeriod.  Calculation is based on 100ns unit.
    //
    Counter = DivU64x32Remainder (
                MultU64x32 (Microseconds, 10),
                gMetronome->TickPeriod,
                &Remainder
                );
    if (Remainder != 0) {
      //
      // If Remainder is not zero, then round Counter up by one tick.
      //
      Counter++;
    }
    CoreInternalWaitForTick (Counter);
  }

  return EFI_SUCCESS;
}

 

CoreStall() 实现了UEFI 规范中定义的Stall 服务。它的功能非常简单,就是使得运行中的程序

进行一段时间的延时,该延时是以微秒(micro-second) 为单位的。由于每种平台用于计时的芯片

组硬件是不同的而DXE Croe 的实现又要求独立于平台特性。

 

EFI_STATUS
EFIAPI
CoreInstallConfigurationTable (
  IN EFI_GUID *Guid,
  IN VOID     *Table
  )
{
  UINTN                   Index;
  EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
  EFI_CONFIGURATION_TABLE *OldTable;

  //
  // If Guid is NULL, then this operation cannot be performed
  //
  if (Guid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  EfiConfigurationTable = gDxeCoreST->ConfigurationTable;

  //
  // Search all the table for an entry that matches Guid
  //
  for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
    if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
      break;
    }
  }

该函数的功能为向EFI 系统表(EFI System Table) 中加入, 更新或者删除一个配置表。UEFI

规范中定义了该系统表的结构,其中有一个指向配置表数组的指针ConfiguraitonTable; 该指针

指向了一系列以EFI_GUID 为标识的配置表,这些配置表的个数由系统表中的NumberOfTableEntries 来

指定。

 

通过Configuration 和NumberOfTableEntries 来遍历系统表中已经存的配置表,找寻输入的GUID

所对应的配置表。

 

 

 

发布了164 篇原创文章 · 获赞 81 · 访问量 26万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览