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