Home | History | Annotate | Download | only in Ia32
      1 /*++
      2 
      3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14     RuntimeLib.c
     15 
     16 Abstract:
     17 
     18   Light weight lib to support Tiano drivers.
     19 
     20 --*/
     21 
     22 #include "Tiano.h"
     23 #include "EfiRuntimeLib.h"
     24 #include "PeiHob.h"
     25 #include EFI_PROTOCOL_DEFINITION (CpuIo)
     26 #include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
     27 #include EFI_GUID_DEFINITION (StatusCodeCallerId)
     28 #include EFI_GUID_DEFINITION (Hob)
     29 #include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
     30 #include EFI_PROTOCOL_DEFINITION (SmmStatusCode)
     31 #include EFI_PROTOCOL_DEFINITION (SmmBase)
     32 
     33 //
     34 // Driver Lib Module Globals
     35 //
     36 static EFI_RUNTIME_SERVICES *mRT;
     37 static EFI_EVENT            mRuntimeNotifyEvent     = NULL;
     38 static EFI_EVENT            mEfiVirtualNotifyEvent  = NULL;
     39 static BOOLEAN              mRuntimeLibInitialized  = FALSE;
     40 static BOOLEAN              mEfiGoneVirtual         = FALSE;
     41 static BOOLEAN              mInSmm                  = FALSE;
     42 
     43 //
     44 // Runtime Global, but you should use the Lib functions
     45 //
     46 EFI_CPU_IO_PROTOCOL         *gCpuIo;
     47 BOOLEAN                     mEfiAtRuntime = FALSE;
     48 FVB_ENTRY                   *mFvbEntry;
     49 EFI_SMM_STATUS_CODE_PROTOCOL  *gSmmStatusCodeProtocol = NULL;
     50 
     51 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
     52 
     53 EFI_REPORT_STATUS_CODE      gReportStatusCode         = NULL;
     54 EFI_EVENT                   gEfiStatusCodeNotifyEvent = NULL;
     55 
     56 VOID
     57 EFIAPI
     58 OnStatusCodeInstall (
     59   IN EFI_EVENT        Event,
     60   IN VOID             *Context
     61   )
     62 {
     63   EFI_STATUS                Status;
     64   EFI_STATUS_CODE_PROTOCOL  *StatusCode;
     65 
     66   Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **) &StatusCode);
     67   if (!EFI_ERROR (Status)) {
     68     gReportStatusCode = StatusCode->ReportStatusCode;
     69   }
     70 }
     71 
     72 EFI_STATUS
     73 GetPeiProtocol (
     74   IN EFI_GUID  *ProtocolGuid,
     75   IN VOID      **Interface
     76   )
     77 /*++
     78 
     79 Routine Description:
     80 
     81   Searches for a Protocol Interface passed from PEI through a HOB
     82 
     83 Arguments:
     84 
     85   ProtocolGuid - The Protocol GUID to search for in the HOB List
     86 
     87   Interface    - A pointer to the interface for the Protocol GUID
     88 
     89 Returns:
     90 
     91   EFI_SUCCESS   - The Protocol GUID was found and its interface is returned in Interface
     92 
     93   EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
     94 
     95 --*/
     96 {
     97   EFI_STATUS            Status;
     98   EFI_PEI_HOB_POINTERS  GuidHob;
     99 
    100   //
    101   // Get Hob list
    102   //
    103   Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &GuidHob.Raw);
    104   if (EFI_ERROR (Status)) {
    105     return Status;
    106   }
    107 
    108   for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {
    109     if (END_OF_HOB_LIST (GuidHob)) {
    110       Status = EFI_NOT_FOUND;
    111       break;
    112     }
    113 
    114     if (GET_HOB_TYPE (GuidHob) == EFI_HOB_TYPE_GUID_EXTENSION) {
    115       if (EfiCompareGuid (ProtocolGuid, &GuidHob.Guid->Name)) {
    116         Status     = EFI_SUCCESS;
    117         *Interface = (VOID *) *(UINTN *) (GuidHob.Guid + 1);
    118       }
    119     }
    120 
    121     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
    122   }
    123 
    124   return Status;
    125 }
    126 
    127 #endif
    128 
    129 EFI_STATUS
    130 EfiConvertPointer (
    131   IN UINTN                     DebugDisposition,
    132   IN OUT VOID                  *Address
    133   )
    134 /*++
    135 
    136 Routine Description:
    137 
    138   Determines the new virtual address that is to be used on subsequent memory accesses.
    139 
    140 Arguments:
    141 
    142   DebugDisposition  - Supplies type information for the pointer being converted.
    143   Address           - A pointer to a pointer that is to be fixed to be the value needed
    144                       for the new virtual address mappings being applied.
    145 
    146 Returns:
    147 
    148   Status code
    149 
    150 --*/
    151 {
    152   return mRT->ConvertPointer (DebugDisposition, Address);
    153 }
    154 
    155 EFI_STATUS
    156 EfiConvertInternalPointer (
    157   IN OUT VOID                  *Address
    158   )
    159 /*++
    160 
    161 Routine Description:
    162 
    163   Call EfiConvertPointer() to convert internal pointer.
    164 
    165 Arguments:
    166 
    167   Address - A pointer to a pointer that is to be fixed to be the value needed
    168             for the new virtual address mappings being applied.
    169 
    170 Returns:
    171 
    172   Status code
    173 
    174 --*/
    175 {
    176   return EfiConvertPointer (EFI_INTERNAL_POINTER, Address);
    177 }
    178 
    179 VOID
    180 EFIAPI
    181 EfiRuntimeLibFvbVirtualNotifyEvent (
    182   IN EFI_EVENT        Event,
    183   IN VOID             *Context
    184   )
    185 /*++
    186 
    187 Routine Description:
    188 
    189   Convert all pointers in mFvbEntry after ExitBootServices.
    190 
    191 Arguments:
    192 
    193   Event   - The Event that is being processed
    194 
    195   Context - Event Context
    196 
    197 Returns:
    198 
    199   None
    200 
    201 --*/
    202 {
    203   UINTN Index;
    204   if (mFvbEntry != NULL) {
    205     for (Index = 0; Index < MAX_FVB_COUNT; Index++) {
    206       if (NULL != mFvbEntry[Index].Fvb) {
    207         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);
    208         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);
    209         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);
    210         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);
    211         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->Read);
    212         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->Write);
    213         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);
    214         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb);
    215       }
    216 
    217       if (NULL != mFvbEntry[Index].FvbExtension) {
    218         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);
    219         EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].FvbExtension);
    220       }
    221     }
    222 
    223     EfiConvertInternalPointer ((VOID **) &mFvbEntry);
    224   }
    225 }
    226 
    227 VOID
    228 EFIAPI
    229 RuntimeDriverExitBootServices (
    230   IN EFI_EVENT        Event,
    231   IN VOID             *Context
    232   )
    233 /*++
    234 
    235 Routine Description:
    236 
    237   Set AtRuntime flag as TRUE after ExitBootServices
    238 
    239 Arguments:
    240 
    241   Event   - The Event that is being processed
    242 
    243   Context - Event Context
    244 
    245 Returns:
    246 
    247   None
    248 
    249 --*/
    250 {
    251   mEfiAtRuntime = TRUE;
    252 }
    253 
    254 extern BOOLEAN  gEfiFvbInitialized;
    255 
    256 VOID
    257 EFIAPI
    258 EfiRuntimeLibVirtualNotifyEvent (
    259   IN EFI_EVENT        Event,
    260   IN VOID             *Context
    261   )
    262 /*++
    263 
    264 Routine Description:
    265 
    266   Fixup internal data so that EFI can be call in virtual mode.
    267   Call the passed in Child Notify event and convert any pointers in
    268   lib to virtual mode.
    269 
    270 Arguments:
    271 
    272   Event   - The Event that is being processed
    273 
    274   Context - Event Context
    275 
    276 Returns:
    277 
    278   None
    279 
    280 --*/
    281 {
    282   EFI_EVENT_NOTIFY  ChildNotifyEventHandler;
    283 
    284   if (Context != NULL) {
    285     ChildNotifyEventHandler = (EFI_EVENT_NOTIFY) (UINTN) Context;
    286     ChildNotifyEventHandler (Event, NULL);
    287   }
    288 
    289   if (gEfiFvbInitialized) {
    290     EfiRuntimeLibFvbVirtualNotifyEvent (Event, Context);
    291   }
    292   //
    293   // Update global for Runtime Services Table and IO
    294   //
    295   EfiConvertInternalPointer ((VOID **) &gCpuIo);
    296 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    297   if (gReportStatusCode != NULL) {
    298     EfiConvertInternalPointer ((VOID **) &gReportStatusCode);
    299   }
    300 #endif
    301   EfiConvertInternalPointer ((VOID **) &mRT);
    302 
    303   //
    304   // Clear out BootService globals
    305   //
    306   gBS             = NULL;
    307   gST             = NULL;
    308   mEfiGoneVirtual = TRUE;
    309 }
    310 
    311 EFI_STATUS
    312 EfiInitializeRuntimeDriverLib (
    313   IN EFI_HANDLE           ImageHandle,
    314   IN EFI_SYSTEM_TABLE     *SystemTable,
    315   IN EFI_EVENT_NOTIFY     GoVirtualChildEvent
    316   )
    317 /*++
    318 
    319 Routine Description:
    320 
    321   Intialize runtime Driver Lib if it has not yet been initialized.
    322 
    323 Arguments:
    324 
    325   ImageHandle     - The firmware allocated handle for the EFI image.
    326 
    327   SystemTable     - A pointer to the EFI System Table.
    328 
    329   GoVirtualChildEvent - Caller can register a virtual notification event.
    330 
    331 Returns:
    332 
    333   EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
    334 
    335 --*/
    336 {
    337   EFI_STATUS  Status;
    338 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    339   VOID *Registration;
    340 #endif
    341 
    342   if (mRuntimeLibInitialized) {
    343     return EFI_ALREADY_STARTED;
    344   }
    345 
    346   mRuntimeLibInitialized  = TRUE;
    347 
    348   gST = SystemTable;
    349   ASSERT (gST != NULL);
    350 
    351   gBS = SystemTable->BootServices;
    352   ASSERT (gBS != NULL);
    353   mRT = SystemTable->RuntimeServices;
    354   ASSERT (mRT != NULL);
    355 
    356   Status  = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
    357   ASSERT_EFI_ERROR (Status);
    358 
    359 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    360   //
    361   // Register EFI_STATUS_CODE_PROTOCOL notify function
    362   //
    363   Status = gBS->CreateEvent (
    364                   EFI_EVENT_NOTIFY_SIGNAL,
    365                   EFI_TPL_CALLBACK,
    366                   OnStatusCodeInstall,
    367                   NULL,
    368                   &gEfiStatusCodeNotifyEvent
    369                   );
    370   ASSERT_EFI_ERROR (Status);
    371 
    372   Status = gBS->RegisterProtocolNotify (
    373                   &gEfiStatusCodeRuntimeProtocolGuid,
    374                   gEfiStatusCodeNotifyEvent,
    375                   &Registration
    376                   );
    377   ASSERT_EFI_ERROR (Status);
    378 
    379   gBS->SignalEvent (gEfiStatusCodeNotifyEvent);
    380 #endif
    381 
    382   Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &gCpuIo);
    383   if (EFI_ERROR (Status)) {
    384     gCpuIo = NULL;
    385   }
    386 
    387   //
    388   // Register our ExitBootServices () notify function
    389   //
    390   Status = gBS->CreateEvent (
    391                   EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
    392                   EFI_TPL_NOTIFY,
    393                   RuntimeDriverExitBootServices,
    394                   NULL,
    395                   &mRuntimeNotifyEvent
    396                   );
    397   ASSERT_EFI_ERROR (Status);
    398 
    399   //
    400   // Register SetVirtualAddressMap () notify function
    401   //
    402   Status = gBS->CreateEvent (
    403                   EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
    404                   EFI_TPL_NOTIFY,
    405                   EfiRuntimeLibVirtualNotifyEvent,
    406                   (VOID *) (UINTN) GoVirtualChildEvent,
    407                   &mEfiVirtualNotifyEvent
    408                   );
    409   ASSERT_EFI_ERROR (Status);
    410 
    411   return EFI_SUCCESS;
    412 }
    413 
    414 EFI_STATUS
    415 EfiShutdownRuntimeDriverLib (
    416   VOID
    417   )
    418 /*++
    419 
    420 Routine Description:
    421 
    422   This routine will free some resources which have been allocated in
    423   EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
    424   it must call this routine to free the allocated resource before the exiting.
    425 
    426 Arguments:
    427 
    428   None
    429 
    430 Returns:
    431 
    432   EFI_SUCCESS     - Shotdown the Runtime Driver Lib successfully
    433   EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
    434 
    435 --*/
    436 {
    437   EFI_STATUS  Status;
    438 
    439   if (!mRuntimeLibInitialized) {
    440     //
    441     // You must call EfiInitializeRuntimeDriverLib() first
    442     //
    443     return EFI_UNSUPPORTED;
    444   }
    445 
    446   mRuntimeLibInitialized = FALSE;
    447 
    448   //
    449   // Close our ExitBootServices () notify function
    450   //
    451   if (mRuntimeNotifyEvent != NULL) {
    452     Status = gBS->CloseEvent (mRuntimeNotifyEvent);
    453     ASSERT_EFI_ERROR (Status);
    454   }
    455 
    456   //
    457   // Close SetVirtualAddressMap () notify function
    458   //
    459   if (mEfiVirtualNotifyEvent != NULL) {
    460     Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
    461     ASSERT_EFI_ERROR (Status);
    462   }
    463 
    464 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    465   //
    466   // Close EfiStatusCodeRuntimeProtocol notify function
    467   //
    468   if (gEfiStatusCodeNotifyEvent != NULL) {
    469     Status = gBS->CloseEvent (gEfiStatusCodeNotifyEvent);
    470     ASSERT_EFI_ERROR (Status);
    471   }
    472 #endif
    473 
    474   return EFI_SUCCESS;
    475 }
    476 
    477 EFI_STATUS
    478 EfiInitializeSmmDriverLib (
    479   IN EFI_HANDLE           ImageHandle,
    480   IN EFI_SYSTEM_TABLE     *SystemTable
    481   )
    482 /*++
    483 
    484 Routine Description:
    485 
    486   Intialize runtime Driver Lib if it has not yet been initialized.
    487 
    488 Arguments:
    489 
    490   ImageHandle     - The firmware allocated handle for the EFI image.
    491 
    492   SystemTable     - A pointer to the EFI System Table.
    493 
    494 Returns:
    495 
    496   EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
    497 
    498 --*/
    499 {
    500   EFI_STATUS               Status;
    501   EFI_SMM_BASE_PROTOCOL    *SmmBase;
    502 
    503   if (mRuntimeLibInitialized) {
    504     return EFI_ALREADY_STARTED;
    505   }
    506 
    507   mRuntimeLibInitialized  = TRUE;
    508 
    509   gST = SystemTable;
    510   ASSERT (gST != NULL);
    511 
    512   gBS = SystemTable->BootServices;
    513   ASSERT (gBS != NULL);
    514   mRT = SystemTable->RuntimeServices;
    515   ASSERT (mRT != NULL);
    516 
    517   //
    518   // Check whether it is in SMM mode.
    519   //
    520   Status  = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID**) &SmmBase);
    521   if (!EFI_ERROR (Status)) {
    522     SmmBase->InSmm (SmmBase, &mInSmm);
    523   }
    524 
    525   //
    526   // Directly locate SmmStatusCode protocol
    527   //
    528   Status = gBS->LocateProtocol (&gEfiSmmStatusCodeProtocolGuid, NULL, (VOID**) &gSmmStatusCodeProtocol);
    529   if (EFI_ERROR (Status)) {
    530     gSmmStatusCodeProtocol = NULL;
    531   }
    532 
    533   Status  = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &gCpuIo);
    534   if (EFI_ERROR (Status)) {
    535     gCpuIo = NULL;
    536   }
    537 
    538   return EFI_SUCCESS;
    539 }
    540 
    541 BOOLEAN
    542 EfiAtRuntime (
    543   VOID
    544   )
    545 /*++
    546 
    547 Routine Description:
    548   Return TRUE if ExitBootServices () has been called
    549 
    550 Arguments:
    551   NONE
    552 
    553 Returns:
    554   TRUE - If ExitBootServices () has been called
    555 
    556 --*/
    557 {
    558   return mEfiAtRuntime;
    559 }
    560 
    561 BOOLEAN
    562 EfiGoneVirtual (
    563   VOID
    564   )
    565 /*++
    566 
    567 Routine Description:
    568   Return TRUE if SetVirtualAddressMap () has been called
    569 
    570 Arguments:
    571   NONE
    572 
    573 Returns:
    574   TRUE - If SetVirtualAddressMap () has been called
    575 
    576 --*/
    577 {
    578   return mEfiGoneVirtual;
    579 }
    580 //
    581 // The following functions hide the mRT local global from the call to
    582 // runtime service in the EFI system table.
    583 //
    584 EFI_STATUS
    585 EfiGetTime (
    586   OUT EFI_TIME                    *Time,
    587   OUT EFI_TIME_CAPABILITIES       *Capabilities
    588   )
    589 /*++
    590 
    591 Routine Description:
    592 
    593   Returns the current time and date information, and the time-keeping
    594   capabilities of the hardware platform.
    595 
    596 Arguments:
    597 
    598   Time          - A pointer to storage to receive a snapshot of the current time.
    599   Capabilities  - An optional pointer to a buffer to receive the real time clock device's
    600                   capabilities.
    601 
    602 Returns:
    603 
    604   Status code
    605 
    606 --*/
    607 {
    608   return mRT->GetTime (Time, Capabilities);
    609 }
    610 
    611 EFI_STATUS
    612 EfiSetTime (
    613   IN EFI_TIME                   *Time
    614   )
    615 /*++
    616 
    617 Routine Description:
    618 
    619   Sets the current local time and date information.
    620 
    621 Arguments:
    622 
    623   Time  - A pointer to the current time.
    624 
    625 Returns:
    626 
    627   Status code
    628 
    629 --*/
    630 {
    631   return mRT->SetTime (Time);
    632 }
    633 
    634 EFI_STATUS
    635 EfiGetWakeupTime (
    636   OUT BOOLEAN                     *Enabled,
    637   OUT BOOLEAN                     *Pending,
    638   OUT EFI_TIME                    *Time
    639   )
    640 /*++
    641 
    642 Routine Description:
    643 
    644   Returns the current wakeup alarm clock setting.
    645 
    646 Arguments:
    647 
    648   Enabled - Indicates if the alarm is currently enabled or disabled.
    649   Pending - Indicates if the alarm signal is pending and requires acknowledgement.
    650   Time    - The current alarm setting.
    651 
    652 Returns:
    653 
    654   Status code
    655 
    656 --*/
    657 {
    658   return mRT->GetWakeupTime (Enabled, Pending, Time);
    659 }
    660 
    661 EFI_STATUS
    662 EfiSetWakeupTime (
    663   IN BOOLEAN                      Enable,
    664   IN EFI_TIME                     *Time
    665   )
    666 /*++
    667 
    668 Routine Description:
    669 
    670   Sets the system wakeup alarm clock time.
    671 
    672 Arguments:
    673 
    674   Enable  - Enable or disable the wakeup alarm.
    675   Time    - If Enable is TRUE, the time to set the wakeup alarm for.
    676             If Enable is FALSE, then this parameter is optional, and may be NULL.
    677 
    678 Returns:
    679 
    680   Status code
    681 
    682 --*/
    683 {
    684   return mRT->SetWakeupTime (Enable, Time);
    685 }
    686 
    687 EFI_STATUS
    688 EfiGetVariable (
    689   IN CHAR16                       *VariableName,
    690   IN EFI_GUID                     * VendorGuid,
    691   OUT UINT32                      *Attributes OPTIONAL,
    692   IN OUT UINTN                    *DataSize,
    693   OUT VOID                        *Data
    694   )
    695 /*++
    696 
    697 Routine Description:
    698 
    699   Returns the value of a variable.
    700 
    701 Arguments:
    702 
    703   VariableName  - A Null-terminated Unicode string that is the name of the
    704                   vendor's variable.
    705   VendorGuid    - A unique identifier for the vendor.
    706   Attributes    - If not NULL, a pointer to the memory location to return the
    707                   attributes bitmask for the variable.
    708   DataSize      - On input, the size in bytes of the return Data buffer.
    709                   On output the size of data returned in Data.
    710   Data          - The buffer to return the contents of the variable.
    711 
    712 Returns:
    713 
    714   Status code
    715 
    716 --*/
    717 {
    718   return mRT->GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
    719 }
    720 
    721 EFI_STATUS
    722 EfiGetNextVariableName (
    723   IN OUT UINTN                    *VariableNameSize,
    724   IN OUT CHAR16                   *VariableName,
    725   IN OUT EFI_GUID                 *VendorGuid
    726   )
    727 /*++
    728 
    729 Routine Description:
    730 
    731   Enumerates the current variable names.
    732 
    733 Arguments:
    734 
    735   VariableNameSize  - The size of the VariableName buffer.
    736   VariableName      - On input, supplies the last VariableName that was returned
    737                       by GetNextVariableName().
    738                       On output, returns the Nullterminated Unicode string of the
    739                       current variable.
    740   VendorGuid        - On input, supplies the last VendorGuid that was returned by
    741                       GetNextVariableName().
    742                       On output, returns the VendorGuid of the current variable.
    743 
    744 Returns:
    745 
    746   Status code
    747 
    748 --*/
    749 {
    750   return mRT->GetNextVariableName (VariableNameSize, VariableName, VendorGuid);
    751 }
    752 
    753 EFI_STATUS
    754 EfiSetVariable (
    755   IN CHAR16                       *VariableName,
    756   IN EFI_GUID                     *VendorGuid,
    757   IN UINT32                       Attributes,
    758   IN UINTN                        DataSize,
    759   IN VOID                         *Data
    760   )
    761 /*++
    762 
    763 Routine Description:
    764 
    765   Sets the value of a variable.
    766 
    767 Arguments:
    768 
    769   VariableName  - A Null-terminated Unicode string that is the name of the
    770                   vendor's variable.
    771   VendorGuid    - A unique identifier for the vendor.
    772   Attributes    - Attributes bitmask to set for the variable.
    773   DataSize      - The size in bytes of the Data buffer.
    774   Data          - The contents for the variable.
    775 
    776 Returns:
    777 
    778   Status code
    779 
    780 --*/
    781 {
    782   return mRT->SetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
    783 }
    784 
    785 
    786 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    787 
    788 EFI_STATUS
    789 EfiQueryVariableInfo (
    790   IN UINT32           Attributes,
    791   OUT UINT64          *MaximumVariableStorageSize,
    792   OUT UINT64          *RemainingVariableStorageSize,
    793   OUT UINT64          *MaximumVariableSize
    794   )
    795 
    796 /*++
    797 
    798 Routine Description:
    799 
    800   This code returns information about the EFI variables.
    801 
    802 Arguments:
    803 
    804   Attributes                      Attributes bitmask to specify the type of variables
    805                                   on which to return information.
    806   MaximumVariableStorageSize      Pointer to the maximum size of the storage space available
    807                                   for the EFI variables associated with the attributes specified.
    808   RemainingVariableStorageSize    Pointer to the remaining size of the storage space available
    809                                   for the EFI variables associated with the attributes specified.
    810   MaximumVariableSize             Pointer to the maximum size of the individual EFI variables
    811                                   associated with the attributes specified.
    812 
    813 Returns:
    814 
    815   Status code
    816 
    817 --*/
    818 {
    819   return mRT->QueryVariableInfo (Attributes, MaximumVariableStorageSize, RemainingVariableStorageSize, MaximumVariableSize);
    820 }
    821 
    822 #endif
    823 
    824 EFI_STATUS
    825 EfiGetNextHighMonotonicCount (
    826   OUT UINT32                      *HighCount
    827   )
    828 /*++
    829 
    830 Routine Description:
    831 
    832   Returns the next high 32 bits of the platform's monotonic counter.
    833 
    834 Arguments:
    835 
    836   HighCount - Pointer to returned value.
    837 
    838 Returns:
    839 
    840   Status code
    841 
    842 --*/
    843 {
    844   return mRT->GetNextHighMonotonicCount (HighCount);
    845 }
    846 
    847 VOID
    848 EfiResetSystem (
    849   IN EFI_RESET_TYPE               ResetType,
    850   IN EFI_STATUS                   ResetStatus,
    851   IN UINTN                        DataSize,
    852   IN CHAR16                       *ResetData
    853   )
    854 /*++
    855 
    856 Routine Description:
    857 
    858   Resets the entire platform.
    859 
    860 Arguments:
    861 
    862   ResetType   - The type of reset to perform.
    863   ResetStatus - The status code for the reset.
    864   DataSize    - The size, in bytes, of ResetData.
    865   ResetData   - A data buffer that includes a Null-terminated Unicode string, optionally
    866                 followed by additional binary data.
    867 
    868 Returns:
    869 
    870   None
    871 
    872 --*/
    873 {
    874   mRT->ResetSystem (ResetType, ResetStatus, DataSize, ResetData);
    875 }
    876 
    877 EFI_STATUS
    878 EfiReportStatusCode (
    879   IN EFI_STATUS_CODE_TYPE     CodeType,
    880   IN EFI_STATUS_CODE_VALUE    Value,
    881   IN UINT32                   Instance,
    882   IN EFI_GUID                 *CallerId OPTIONAL,
    883   IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL
    884   )
    885 /*++
    886 
    887 Routine Description:
    888 
    889   Status Code reporter
    890 
    891 Arguments:
    892 
    893   CodeType    - Type of Status Code.
    894 
    895   Value       - Value to output for Status Code.
    896 
    897   Instance    - Instance Number of this status code.
    898 
    899   CallerId    - ID of the caller of this status code.
    900 
    901   Data        - Optional data associated with this status code.
    902 
    903 Returns:
    904 
    905   Status code
    906 
    907 --*/
    908 {
    909   EFI_STATUS               Status;
    910 
    911   if (mInSmm) {
    912     if (gSmmStatusCodeProtocol == NULL) {
    913       return EFI_UNSUPPORTED;
    914     }
    915     Status = gSmmStatusCodeProtocol->ReportStatusCode (gSmmStatusCodeProtocol, CodeType, Value, Instance, CallerId, Data);
    916     return Status;
    917   }
    918 
    919 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    920   if (gReportStatusCode == NULL) {
    921     //
    922     // Because we've installed the protocol notification on EfiStatusCodeRuntimeProtocol,
    923     //   running here indicates that the StatusCode driver has not started yet.
    924     //
    925     if (EfiAtRuntime ()) {
    926       //
    927       // Running here only when StatusCode driver never starts.
    928       //
    929       return EFI_UNSUPPORTED;
    930     }
    931 
    932     //
    933     // Try to get the PEI version of ReportStatusCode.
    934     //
    935     Status = GetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **) &gReportStatusCode);
    936     if (EFI_ERROR (Status) || (gReportStatusCode == NULL)) {
    937       return EFI_UNSUPPORTED;
    938     }
    939   }
    940   Status = gReportStatusCode (CodeType, Value, Instance, CallerId, Data);
    941 #else
    942   if (mRT == NULL) {
    943     return EFI_UNSUPPORTED;
    944   }
    945   //
    946   // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
    947   //
    948   Status = EFI_UNSUPPORTED;
    949   if (mRT->Hdr.Revision     == EFI_SPECIFICATION_VERSION     &&
    950       mRT->Hdr.HeaderSize   == sizeof (EFI_RUNTIME_SERVICES) &&
    951       mRT->ReportStatusCode != NULL) {
    952     Status = mRT->ReportStatusCode (CodeType, Value, Instance, CallerId, Data);
    953   }
    954 #endif
    955   return Status;
    956 }
    957