Step to UEFI (129)EFI_CPU_ARCH_PROTOCOL

最近在看 EFI_CPU_ARCH_PROTOCOL 相关内容,相关定义只在 PI Specification的DXE_CIS 章节,和 UEFI Specification 无关。具体如下:

car1

这次先试试其中的NumberOfTimers 和GetTimerValue 。NumberOfTimers 返回的是当前系统中的Timer数量,从我的几个机器的实验看,目前都是 1。GetTimerValue定义如下:

car2

其中的 TimerValue 给出当前系统Timer的值;TimerPeriod给出当前系统Timer值的单位,这个单位是飞秒(10^-15)。比如,TimerPeriod=10^6 (1ns),TimerValue=10^3,那么 Timer 经过的事件是两者相乘的 10^9, 1 微秒(1 microsecond)。

我们编写一个代码来进行实验,测试一个 gBS->stall 1秒,经过的时间。代码如下 :

 

/** @file

    A simple, basic, application showing how the Hello application could be

    built using the "Standard C Libraries" from StdLib.



    Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>

    This program and the accompanying materials

    are licensed and made available under the terms and conditions of the BSD License

    which accompanies this distribution. The full text of the license may be found at

    http://opensource.org/licenses/bsd-license.



    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <Library/BaseLib.h>

#include <Uefi.h>

#include <Library/UefiLib.h>

#include <Library/PrintLib.h>

#include <Library/ShellCEntryLib.h>



#include <Protocol/Cpu.h>



EFI_GUID gEfiCpuArchProtocolGuid =

                { 0x26BACCB1, 0x6F42, 0x11D4,

                        { 0xBC, 0xE7, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }};



extern EFI_BOOT_SERVICES         *gBS;



/***

  Demonstrates basic workings of the main() function by displaying a

  welcoming message.



  Note that the UEFI command line is composed of 16-bit UCS2 wide characters.

  The easiest way to access the command line parameters is to cast Argv as:

      wchar_t **wArgv = (wchar_t **)Argv;



  @param[in]  Argc    Number of argument tokens pointed to by Argv.

  @param[in]  Argv    Array of Argc pointers to command line tokens.



  @retval  0         The application exited normally.

  @retval  Other     An error occurred.

***/

int

main (

  IN int Argc,

  IN char **Argv

  )

{

  EFI_CPU_ARCH_PROTOCOL  *Cpu;

  UINT64                 TimerValue;

  UINT64                 StartTimerValue; 

  UINT64                 EndTimerValue; 

  UINT64                 TimerPerioid;

  EFI_STATUS             Status;

  UINT64                 tmp;



  //

  // Locate the Cpu Arch Protocol.

  //

  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, &Cpu);

  if (EFI_ERROR (Status)) {

    Print(L"Can't find EFI_CPU_ARCH_PROTOCOL\n");

    return Status;

  }



  //Get some base information

  Cpu->GetTimerValue(

        Cpu,

        0, //There is only one timer in system

        &TimerValue,

        &TimerPerioid

  );



  //Usually there is only one timer in this protocol

  Print(L"NumberOfTimers: %d\n",Cpu->NumberOfTimers); 

  //The unite of one timer ,femtoseconds 10^(-15)s

  Print(L"Timer period  : %ld\n",TimerPerioid);



  //Make a simple test here, delay 1 second

  //And check how long it is in the timer

  Print(L"Timer Test Start delay 1s\n");

  Cpu->GetTimerValue(

                Cpu,

                0, //There is only one timer in system

                &StartTimerValue,

                &TimerPerioid

        ); 

  Print(L"   Start at: %ld\n",StartTimerValue);

  gBS->Stall(1000000UL);

  Cpu->GetTimerValue(

                Cpu,

                0, //There is only one timer in system

                &EndTimerValue,

                &TimerPerioid

        ); 

  Print(L"     End at: %ld\n",EndTimerValue);

  tmp = MultU64x64(EndTimerValue-StartTimerValue,TimerPerioid);

  tmp = DivU64x32 (tmp,1000000000UL);

  Print(L"    Elapsed: %ld us\n",tmp);



  return 0;

}

NT32 的虚拟机实验结果如下:

car3

实体机上实验结果如下(看起来实体机上偏差更大?):

car4

X64 EFI Application下载:

cat1

完整代码下载:

CPUArchTest1

时间单位的简单介绍【参考1】:

second millisecond microsecond nanosecond picosecond femtosecond

1ms (毫秒) 1毫秒=0.001秒=10-3
1μs (微秒)   1微秒=0.000001=10-6
1ns (纳秒)  1纳秒=0.0000000001秒=10-9
1ps (皮秒)  1皮秒=0.0000000000001秒=10-12
1fs (飞秒)  1飞秒=0.000000000000001秒=10-15

参考:

  1. http://blog.163.com/digoal@126/blog/static/163877040201062810748700/

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注