1 /*++ 2 3 Copyright (c) 2004 - 2012, 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 Sal drivers. 19 20 --*/ 21 22 #include "Tiano.h" 23 #include "EfiRuntimeLib.h" 24 #include EFI_PROTOCOL_DEFINITION (ExtendedSalBootService) 25 #include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid) 26 #include "IpfDefines.h" 27 #include "SalApi.h" 28 29 // 30 // Worker functions in EsalLib.s 31 // 32 SAL_RETURN_REGS 33 GetEsalEntryPoint ( 34 VOID 35 ); 36 37 SAL_RETURN_REGS 38 SetEsalPhysicalEntryPoint ( 39 IN UINT64 EntryPoint, 40 IN UINT64 Gp 41 ); 42 43 SAL_RETURN_REGS 44 SetEsalVirtualEntryPoint ( 45 IN UINT64 EntryPoint, 46 IN UINT64 Gp 47 ); 48 49 VOID 50 SalFlushCache ( 51 IN EFI_PHYSICAL_ADDRESS Start, 52 IN UINT64 Length 53 ); 54 55 // 56 // Module Globals. It's not valid to use these after the 57 // EfiRuntimeLibVirtualNotifyEvent has fired. 58 // 59 static EFI_EVENT mEfiVirtualNotifyEvent; 60 static EFI_RUNTIME_SERVICES *mRT; 61 static EFI_PLABEL mPlabel; 62 static EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService; 63 static BOOLEAN mRuntimeLibInitialized = FALSE; 64 65 VOID 66 EFIAPI 67 EfiRuntimeLibVirtualNotifyEvent ( 68 IN EFI_EVENT Event, 69 IN VOID *Context 70 ) 71 /*++ 72 73 Routine Description: 74 75 Fixup internal data so that EFI and SAL can be call in virtual mode. 76 Call the passed in Child Notify event and convert any pointers in 77 lib to virtual mode. 78 79 Arguments: 80 81 Event - The Event that is being processed 82 83 Context - Event Context 84 85 Returns: 86 87 None 88 89 --*/ 90 { 91 EFI_EVENT_NOTIFY ChildNotify; 92 93 if (Context != NULL) { 94 // 95 // Call child event 96 // 97 ChildNotify = (EFI_EVENT_NOTIFY) (UINTN) Context; 98 ChildNotify (Event, NULL); 99 } 100 101 mRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mPlabel.EntryPoint); 102 mRT->ConvertPointer (EFI_INTERNAL_POINTER | EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP); 103 104 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP); 105 106 // 107 // Clear out BootService globals 108 // 109 gBS = NULL; 110 gST = NULL; 111 mRT = NULL; 112 113 // 114 // Pointers don't work you must use a direct lib call 115 // 116 } 117 118 EFI_STATUS 119 EfiInitializeRuntimeDriverLib ( 120 IN EFI_HANDLE ImageHandle, 121 IN EFI_SYSTEM_TABLE *SystemTable, 122 IN EFI_EVENT_NOTIFY GoVirtualChildEvent 123 ) 124 /*++ 125 126 Routine Description: 127 128 Intialize runtime Driver Lib if it has not yet been initialized. 129 130 Arguments: 131 132 ImageHandle - The firmware allocated handle for the EFI image. 133 134 SystemTable - A pointer to the EFI System Table. 135 136 GoVirtualChildEvent - Caller can register a virtual notification event. 137 138 Returns: 139 140 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started. 141 142 --*/ 143 { 144 EFI_STATUS Status; 145 EFI_PLABEL *Plabel; 146 147 if (mRuntimeLibInitialized) { 148 return EFI_ALREADY_STARTED; 149 } 150 151 mRuntimeLibInitialized = TRUE; 152 153 gST = SystemTable; 154 gBS = SystemTable->BootServices; 155 mRT = SystemTable->RuntimeServices; 156 Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS); 157 ASSERT_EFI_ERROR (Status); 158 159 // 160 // The protocol contains a function pointer, which is an indirect procedure call. 161 // An indirect procedure call goes through a plabel, and pointer to a function is 162 // a pointer to a plabel. To implement indirect procedure calls that can work in 163 // both physical and virtual mode, two plabels are required (one physical and one 164 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it 165 // away. We cache it in a module global, so we can register the vitrual version. 166 // 167 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService); 168 ASSERT_EFI_ERROR (Status); 169 170 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc; 171 172 mPlabel.EntryPoint = Plabel->EntryPoint; 173 mPlabel.GP = Plabel->GP; 174 175 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP); 176 177 // 178 // Create a Virtual address change notification event. Pass in the callers 179 // GoVirtualChildEvent so it's get passed to the event as contex. 180 // 181 Status = gBS->CreateEvent ( 182 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, 183 EFI_TPL_NOTIFY, 184 EfiRuntimeLibVirtualNotifyEvent, 185 (VOID *) GoVirtualChildEvent, 186 &mEfiVirtualNotifyEvent 187 ); 188 ASSERT_EFI_ERROR (Status); 189 190 return EFI_SUCCESS; 191 } 192 193 EFI_STATUS 194 EfiShutdownRuntimeDriverLib ( 195 VOID 196 ) 197 /*++ 198 199 Routine Description: 200 201 This routine will free some resources which have been allocated in 202 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error, 203 it must call this routine to free the allocated resource before the exiting. 204 205 Arguments: 206 207 None 208 209 Returns: 210 211 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully 212 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all 213 214 --*/ 215 { 216 EFI_STATUS Status; 217 218 if (!mRuntimeLibInitialized) { 219 // 220 // You must call EfiInitializeRuntimeDriverLib() first 221 // 222 return EFI_UNSUPPORTED; 223 } 224 225 mRuntimeLibInitialized = FALSE; 226 227 // 228 // Close SetVirtualAddressMap () notify function 229 // 230 Status = gBS->CloseEvent (mEfiVirtualNotifyEvent); 231 ASSERT_EFI_ERROR (Status); 232 233 return EFI_SUCCESS; 234 } 235 236 EFI_STATUS 237 RegisterEsalFunction ( 238 IN UINT64 FunctionId, 239 IN EFI_GUID *ClassGuid, 240 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function, 241 IN VOID *ModuleGlobal 242 ) 243 /*++ 244 245 Routine Description: 246 247 Register ESAL Class Function and it's asociated global. 248 This function is boot service only! 249 250 Arguments: 251 FunctionId - ID of function to register 252 ClassGuid - GUID of function class 253 Function - Function to register under ClassGuid/FunctionId pair 254 ModuleGlobal - Module global for Function. 255 256 Returns: 257 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered. 258 259 --*/ 260 { 261 return mEsalBootService->AddExtendedSalProc ( 262 mEsalBootService, 263 ClassGuid, 264 FunctionId, 265 Function, 266 ModuleGlobal 267 ); 268 } 269 270 EFI_STATUS 271 RegisterEsalClass ( 272 IN EFI_GUID *ClassGuid, 273 IN VOID *ModuleGlobal, 274 ... 275 ) 276 /*++ 277 278 Routine Description: 279 280 Register ESAL Class and it's asociated global. 281 This function is boot service only! 282 283 Arguments: 284 ClassGuid - GUID of function class 285 ModuleGlobal - Module global for Function. 286 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL 287 indicates the end of the list. 288 289 Returns: 290 EFI_SUCCESS - All members of ClassGuid registered 291 292 --*/ 293 { 294 VA_LIST Args; 295 EFI_STATUS Status; 296 SAL_INTERNAL_EXTENDED_SAL_PROC Function; 297 UINT64 FunctionId; 298 EFI_HANDLE NewHandle; 299 300 VA_START (Args, ModuleGlobal); 301 302 Status = EFI_SUCCESS; 303 while (!EFI_ERROR (Status)) { 304 Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC); 305 if (Function == NULL) { 306 break; 307 } 308 309 FunctionId = VA_ARG (Args, UINT64); 310 311 Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal); 312 } 313 314 VA_END (Args); 315 316 if (EFI_ERROR (Status)) { 317 return Status; 318 } 319 320 NewHandle = NULL; 321 return gBS->InstallProtocolInterface ( 322 &NewHandle, 323 ClassGuid, 324 EFI_NATIVE_INTERFACE, 325 NULL 326 ); 327 } 328 329 SAL_RETURN_REGS 330 EfiCallEsalService ( 331 IN EFI_GUID *ClassGuid, 332 IN UINT64 FunctionId, 333 IN UINT64 Arg2, 334 IN UINT64 Arg3, 335 IN UINT64 Arg4, 336 IN UINT64 Arg5, 337 IN UINT64 Arg6, 338 IN UINT64 Arg7, 339 IN UINT64 Arg8 340 ) 341 /*++ 342 343 Routine Description: 344 345 Call module that is not linked direclty to this module. This code is IP 346 relative and hides the binding issues of virtual or physical calling. The 347 function that gets dispatched has extra arguments that include the registered 348 module global and a boolean flag to indicate if the system is in virutal mode. 349 350 Arguments: 351 ClassGuid - GUID of function 352 FunctionId - Function in ClassGuid to call 353 Arg2 - Argument 2 ClassGuid/FunctionId defined 354 Arg3 - Argument 3 ClassGuid/FunctionId defined 355 Arg4 - Argument 4 ClassGuid/FunctionId defined 356 Arg5 - Argument 5 ClassGuid/FunctionId defined 357 Arg6 - Argument 6 ClassGuid/FunctionId defined 358 Arg7 - Argument 7 ClassGuid/FunctionId defined 359 Arg8 - Argument 8 ClassGuid/FunctionId defined 360 361 Returns: 362 Status of ClassGuid/FuncitonId 363 364 --*/ 365 { 366 SAL_RETURN_REGS ReturnReg; 367 SAL_EXTENDED_SAL_PROC EsalProc; 368 369 ReturnReg = GetEsalEntryPoint (); 370 if (ReturnReg.Status != EFI_SAL_SUCCESS) { 371 return ReturnReg; 372 } 373 374 if (ReturnReg.r11 & PSR_IT_MASK) { 375 // 376 // Virtual mode plabel to entry point 377 // 378 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10; 379 } else { 380 // 381 // Physical mode plabel to entry point 382 // 383 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9; 384 } 385 386 return EsalProc ( 387 ClassGuid, 388 FunctionId, 389 Arg2, 390 Arg3, 391 Arg4, 392 Arg5, 393 Arg6, 394 Arg7, 395 Arg8 396 ); 397 } 398 399 EFI_STATUS 400 EfiConvertPointer ( 401 IN UINTN DebugDisposition, 402 IN OUT VOID *Address 403 ) 404 /*++ 405 406 Routine Description: 407 408 Determines the new virtual address that is to be used on subsequent memory accesses. 409 410 Arguments: 411 412 DebugDisposition - Supplies type information for the pointer being converted. 413 Address - A pointer to a pointer that is to be fixed to be the value needed 414 for the new virtual address mappings being applied. 415 416 Returns: 417 418 Status code 419 420 --*/ 421 { 422 return mRT->ConvertPointer (DebugDisposition, Address); 423 } 424 425 BOOLEAN 426 EfiGoneVirtual ( 427 VOID 428 ) 429 /*++ 430 431 Routine Description: 432 Return TRUE if SetVirtualAddressMap () has been called 433 434 Arguments: 435 NONE 436 437 Returns: 438 TRUE - If SetVirtualAddressMap () has been called 439 440 --*/ 441 { 442 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID; 443 SAL_RETURN_REGS ReturnReg; 444 445 ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0); 446 447 return (BOOLEAN) (ReturnReg.r9 == 1); 448 } 449 450 BOOLEAN 451 EfiAtRuntime ( 452 VOID 453 ) 454 /*++ 455 456 Routine Description: 457 Return TRUE if ExitBootService () has been called 458 459 Arguments: 460 NONE 461 462 Returns: 463 TRUE - If ExitBootService () has been called 464 465 --*/ 466 { 467 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID; 468 SAL_RETURN_REGS ReturnReg; 469 470 ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0); 471 472 return (BOOLEAN) (ReturnReg.r9 == 1); 473 } 474 475 EFI_STATUS 476 EfiReportStatusCode ( 477 IN EFI_STATUS_CODE_TYPE CodeType, 478 IN EFI_STATUS_CODE_VALUE Value, 479 IN UINT32 Instance, 480 IN EFI_GUID * CallerId, 481 IN EFI_STATUS_CODE_DATA * Data OPTIONAL 482 ) 483 /*++ 484 485 Routine Description: 486 487 Status Code reporter 488 489 Arguments: 490 491 CodeType - Type of Status Code. 492 493 Value - Value to output for Status Code. 494 495 Instance - Instance Number of this status code. 496 497 CallerId - ID of the caller of this status code. 498 499 Data - Optional data associated with this status code. 500 501 Returns: 502 503 Status code 504 505 --*/ 506 { 507 EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID; 508 SAL_RETURN_REGS ReturnReg; 509 510 511 ReturnReg = EfiCallEsalService ( 512 &Guid, 513 StatusCode, 514 (UINT64) CodeType, 515 (UINT64) Value, 516 (UINT64) Instance, 517 (UINT64) CallerId, 518 (UINT64) Data, 519 0, 520 0 521 ); 522 523 return (EFI_STATUS) ReturnReg.Status; 524 } 525 // 526 // Sal Reset Driver Class 527 // 528 VOID 529 EfiResetSystem ( 530 IN EFI_RESET_TYPE ResetType, 531 IN EFI_STATUS ResetStatus, 532 IN UINTN DataSize, 533 IN CHAR16 *ResetData 534 ) 535 /*++ 536 537 Routine Description: 538 539 Resets the entire platform. 540 541 Arguments: 542 543 ResetType - The type of reset to perform. 544 ResetStatus - The status code for the reset. 545 DataSize - The size, in bytes, of ResetData. 546 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally 547 followed by additional binary data. 548 549 Returns: 550 551 None 552 553 --*/ 554 { 555 EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID; 556 557 EfiCallEsalService ( 558 &Guid, 559 ResetSystem, 560 (UINT64) ResetType, 561 (UINT64) ResetStatus, 562 (UINT64) DataSize, 563 (UINT64) ResetData, 564 0, 565 0, 566 0 567 ); 568 } 569 // 570 // Sal MTC Driver Class 571 // 572 EFI_STATUS 573 EfiGetNextHighMonotonicCount ( 574 OUT UINT32 *HighCount 575 ) 576 /*++ 577 578 Routine Description: 579 580 Returns the next high 32 bits of the platform's monotonic counter. 581 582 Arguments: 583 584 HighCount - Pointer to returned value. 585 586 Returns: 587 588 Status code 589 590 --*/ 591 { 592 SAL_RETURN_REGS ReturnReg; 593 594 EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID; 595 596 ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0); 597 return (EFI_STATUS) ReturnReg.Status; 598 } 599 // 600 // Sal Variable Driver Class 601 // 602 EFI_STATUS 603 EfiGetVariable ( 604 IN CHAR16 *VariableName, 605 IN EFI_GUID * VendorGuid, 606 OUT UINT32 *Attributes OPTIONAL, 607 IN OUT UINTN *DataSize, 608 OUT VOID *Data 609 ) 610 /*++ 611 612 Routine Description: 613 614 Returns the value of a variable. 615 616 Arguments: 617 618 VariableName - A Null-terminated Unicode string that is the name of the 619 vendor's variable. 620 VendorGuid - A unique identifier for the vendor. 621 Attributes - If not NULL, a pointer to the memory location to return the 622 attributes bitmask for the variable. 623 DataSize - On input, the size in bytes of the return Data buffer. 624 On output the size of data returned in Data. 625 Data - The buffer to return the contents of the variable. 626 627 Returns: 628 629 Status code 630 631 --*/ 632 { 633 SAL_RETURN_REGS ReturnReg; 634 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID; 635 636 ReturnReg = EfiCallEsalService ( 637 &Guid, 638 EsalGetVariable, 639 (UINT64) VariableName, 640 (UINT64) VendorGuid, 641 (UINT64) Attributes, 642 (UINT64) DataSize, 643 (UINT64) Data, 644 0, 645 0 646 ); 647 return (EFI_STATUS) ReturnReg.Status; 648 } 649 650 EFI_STATUS 651 EfiGetNextVariableName ( 652 IN OUT UINTN *VariableNameSize, 653 IN OUT CHAR16 *VariableName, 654 IN OUT EFI_GUID *VendorGuid 655 ) 656 /*++ 657 658 Routine Description: 659 660 Enumerates the current variable names. 661 662 Arguments: 663 664 VariableNameSize - The size of the VariableName buffer. 665 VariableName - On input, supplies the last VariableName that was returned 666 by GetNextVariableName(). 667 On output, returns the Nullterminated Unicode string of the 668 current variable. 669 VendorGuid - On input, supplies the last VendorGuid that was returned by 670 GetNextVariableName(). 671 On output, returns the VendorGuid of the current variable. 672 673 Returns: 674 675 Status code 676 677 --*/ 678 { 679 SAL_RETURN_REGS ReturnReg; 680 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID; 681 682 ReturnReg = EfiCallEsalService ( 683 &Guid, 684 EsalGetNextVariableName, 685 (UINT64) VariableNameSize, 686 (UINT64) VariableName, 687 (UINT64) VendorGuid, 688 0, 689 0, 690 0, 691 0 692 ); 693 return (EFI_STATUS) ReturnReg.Status; 694 } 695 696 EFI_STATUS 697 EfiSetVariable ( 698 IN CHAR16 *VariableName, 699 IN EFI_GUID *VendorGuid, 700 IN UINT32 Attributes, 701 IN UINTN DataSize, 702 IN VOID *Data 703 ) 704 /*++ 705 706 Routine Description: 707 708 Sets the value of a variable. 709 710 Arguments: 711 712 VariableName - A Null-terminated Unicode string that is the name of the 713 vendor's variable. 714 VendorGuid - A unique identifier for the vendor. 715 Attributes - Attributes bitmask to set for the variable. 716 DataSize - The size in bytes of the Data buffer. 717 Data - The contents for the variable. 718 719 Returns: 720 721 Status code 722 723 --*/ 724 { 725 SAL_RETURN_REGS ReturnReg; 726 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID; 727 728 ReturnReg = EfiCallEsalService ( 729 &Guid, 730 EsalSetVariable, 731 (UINT64) VariableName, 732 (UINT64) VendorGuid, 733 (UINT64) Attributes, 734 (UINT64) DataSize, 735 (UINT64) Data, 736 0, 737 0 738 ); 739 return (EFI_STATUS) ReturnReg.Status; 740 } 741 742 #if (EFI_SPECIFICATION_VERSION >= 0x00020000) 743 744 EFI_STATUS 745 EfiQueryVariableInfo ( 746 IN UINT32 Attributes, 747 OUT UINT64 *MaximumVariableStorageSize, 748 OUT UINT64 *RemainingVariableStorageSize, 749 OUT UINT64 *MaximumVariableSize 750 ) 751 /*++ 752 753 Routine Description: 754 755 This code returns information about the EFI variables. 756 757 Arguments: 758 759 Attributes Attributes bitmask to specify the type of variables 760 on which to return information. 761 MaximumVariableStorageSize Pointer to the maximum size of the storage space available 762 for the EFI variables associated with the attributes specified. 763 RemainingVariableStorageSize Pointer to the remaining size of the storage space available 764 for the EFI variables associated with the attributes specified. 765 MaximumVariableSize Pointer to the maximum size of the individual EFI variables 766 associated with the attributes specified. 767 768 Returns: 769 770 Status code 771 772 --*/ 773 { 774 SAL_RETURN_REGS ReturnReg; 775 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID; 776 777 ReturnReg = EfiCallEsalService ( 778 &Guid, 779 EsalQueryVariableInfo, 780 (UINT64) Attributes, 781 (UINT64) MaximumVariableStorageSize, 782 (UINT64) RemainingVariableStorageSize, 783 (UINT64) MaximumVariableSize, 784 0, 785 0, 786 0 787 ); 788 return (EFI_STATUS) ReturnReg.Status; 789 } 790 791 #endif 792 793 // 794 // Sal RTC Driver Class. 795 // 796 EFI_STATUS 797 EfiGetTime ( 798 OUT EFI_TIME *Time, 799 OUT EFI_TIME_CAPABILITIES *Capabilities 800 ) 801 /*++ 802 803 Routine Description: 804 805 Returns the current time and date information, and the time-keeping 806 capabilities of the hardware platform. 807 808 Arguments: 809 810 Time - A pointer to storage to receive a snapshot of the current time. 811 Capabilities - An optional pointer to a buffer to receive the real time clock device's 812 capabilities. 813 814 Returns: 815 816 Status code 817 818 --*/ 819 { 820 SAL_RETURN_REGS ReturnReg; 821 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID; 822 823 ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0); 824 return ReturnReg.Status; 825 } 826 827 EFI_STATUS 828 EfiSetTime ( 829 OUT EFI_TIME *Time 830 ) 831 /*++ 832 833 Routine Description: 834 835 Sets the current local time and date information. 836 837 Arguments: 838 839 Time - A pointer to the current time. 840 841 Returns: 842 843 Status code 844 845 --*/ 846 { 847 SAL_RETURN_REGS ReturnReg; 848 849 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID; 850 851 ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0); 852 return ReturnReg.Status; 853 } 854 855 EFI_STATUS 856 EfiGetWakeupTime ( 857 OUT BOOLEAN *Enabled, 858 OUT BOOLEAN *Pending, 859 OUT EFI_TIME *Time 860 ) 861 /*++ 862 863 Routine Description: 864 865 Returns the current wakeup alarm clock setting. 866 867 Arguments: 868 869 Enabled - Indicates if the alarm is currently enabled or disabled. 870 Pending - Indicates if the alarm signal is pending and requires acknowledgement. 871 Time - The current alarm setting. 872 873 Returns: 874 875 Status code 876 877 --*/ 878 { 879 SAL_RETURN_REGS ReturnReg; 880 881 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID; 882 883 ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0); 884 return ReturnReg.Status; 885 } 886 887 EFI_STATUS 888 EfiSetWakeupTime ( 889 IN BOOLEAN Enable, 890 IN EFI_TIME *Time 891 ) 892 /*++ 893 894 Routine Description: 895 896 Sets the system wakeup alarm clock time. 897 898 Arguments: 899 900 Enable - Enable or disable the wakeup alarm. 901 Time - If Enable is TRUE, the time to set the wakeup alarm for. 902 If Enable is FALSE, then this parameter is optional, and may be NULL. 903 904 Returns: 905 906 Status code 907 908 --*/ 909 { 910 SAL_RETURN_REGS ReturnReg; 911 912 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID; 913 914 ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0); 915 return ReturnReg.Status; 916 } 917 918 919 920 // 921 // Base IO Services 922 // 923 EFI_STATUS 924 EfiIoRead ( 925 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 926 IN UINT64 Address, 927 IN UINTN Count, 928 IN OUT VOID *Buffer 929 ) 930 /*++ 931 932 Routine Description: 933 Perform an IO read into Buffer. 934 935 Arguments: 936 Width - Width of read transaction, and repeat operation to use 937 Address - IO address to read 938 Count - Number of times to read the IO address. 939 Buffer - Buffer to read data into. size is Width * Count 940 941 Returns: 942 Status code 943 944 --*/ 945 { 946 947 SAL_RETURN_REGS ReturnReg; 948 949 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID; 950 951 ReturnReg = EfiCallEsalService (&Guid, IoRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0); 952 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS); 953 954 return ReturnReg.Status; 955 956 } 957 958 EFI_STATUS 959 EfiIoWrite ( 960 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 961 IN UINT64 Address, 962 IN UINTN Count, 963 IN OUT VOID *Buffer 964 ) 965 /*++ 966 967 Routine Description: 968 Perform an IO write into Buffer. 969 970 Arguments: 971 Width - Width of write transaction, and repeat operation to use 972 Address - IO address to write 973 Count - Number of times to write the IO address. 974 Buffer - Buffer to write data from. size is Width * Count 975 976 Returns: 977 Status code 978 979 --*/ 980 { 981 982 SAL_RETURN_REGS ReturnReg; 983 984 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID; 985 986 ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0); 987 988 return ReturnReg.Status; 989 990 } 991 992 EFI_STATUS 993 EfiMemRead ( 994 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 995 IN UINT64 Address, 996 IN UINTN Count, 997 IN OUT VOID *Buffer 998 ) 999 /*++ 1000 1001 Routine Description: 1002 Perform a Memory mapped IO read into Buffer. 1003 1004 Arguments: 1005 Width - Width of each read transaction. 1006 Address - Memory mapped IO address to read 1007 Count - Number of Width quanta to read 1008 Buffer - Buffer to read data into. size is Width * Count 1009 1010 Returns: 1011 Status code 1012 1013 --*/ 1014 { 1015 1016 SAL_RETURN_REGS ReturnReg; 1017 1018 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID; 1019 1020 ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0); 1021 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS); 1022 1023 return ReturnReg.Status; 1024 1025 } 1026 1027 EFI_STATUS 1028 EfiMemWrite ( 1029 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 1030 IN UINT64 Address, 1031 IN UINTN Count, 1032 IN OUT VOID *Buffer 1033 ) 1034 /*++ 1035 1036 Routine Description: 1037 Perform a memory mapped IO write into Buffer. 1038 1039 Arguments: 1040 Width - Width of write transaction, and repeat operation to use 1041 Address - IO address to write 1042 Count - Number of times to write the IO address. 1043 Buffer - Buffer to write data from. size is Width * Count 1044 1045 Returns: 1046 Status code 1047 1048 --*/ 1049 { 1050 1051 SAL_RETURN_REGS ReturnReg; 1052 1053 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID; 1054 1055 ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0); 1056 1057 return ReturnReg.Status; 1058 1059 } 1060 1061 1062 #define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \ 1063 (((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF 1064 1065 // 1066 // PCI Class Functions 1067 // 1068 UINT8 1069 PciRead8 ( 1070 UINT8 Segment, 1071 UINT8 Bus, 1072 UINT8 DevFunc, 1073 UINT8 Register 1074 ) 1075 /*++ 1076 1077 Routine Description: 1078 Perform an one byte PCI config cycle read 1079 1080 Arguments: 1081 Segment - PCI Segment ACPI _SEG 1082 Bus - PCI Bus 1083 DevFunc - PCI Device(7:3) and Func(2:0) 1084 Register - PCI config space register 1085 1086 Returns: 1087 Data read from PCI config space 1088 1089 --*/ 1090 { 1091 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1092 UINT64 Address; 1093 SAL_RETURN_REGS Return; 1094 1095 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1096 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0); 1097 1098 return (UINT8) Return.r9; 1099 } 1100 1101 1102 UINT16 1103 PciRead16 ( 1104 UINT8 Segment, 1105 UINT8 Bus, 1106 UINT8 DevFunc, 1107 UINT8 Register 1108 ) 1109 /*++ 1110 1111 Routine Description: 1112 Perform an two byte PCI config cycle read 1113 1114 Arguments: 1115 Segment - PCI Segment ACPI _SEG 1116 Bus - PCI Bus 1117 DevFunc - PCI Device(7:3) and Func(2:0) 1118 Register - PCI config space register 1119 1120 Returns: 1121 Data read from PCI config space 1122 1123 --*/ 1124 { 1125 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1126 UINT64 Address; 1127 SAL_RETURN_REGS Return; 1128 1129 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1130 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0); 1131 1132 return (UINT16) Return.r9; 1133 } 1134 1135 UINT32 1136 PciRead32 ( 1137 UINT8 Segment, 1138 UINT8 Bus, 1139 UINT8 DevFunc, 1140 UINT8 Register 1141 ) 1142 /*++ 1143 1144 Routine Description: 1145 Perform an four byte PCI config cycle read 1146 1147 Arguments: 1148 Segment - PCI Segment ACPI _SEG 1149 Bus - PCI Bus 1150 DevFunc - PCI Device(7:3) and Func(2:0) 1151 Register - PCI config space register 1152 1153 Returns: 1154 Data read from PCI config space 1155 1156 --*/ 1157 { 1158 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1159 UINT64 Address; 1160 SAL_RETURN_REGS Return; 1161 1162 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1163 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0); 1164 1165 return (UINT32) Return.r9; 1166 } 1167 1168 VOID 1169 PciWrite8 ( 1170 UINT8 Segment, 1171 UINT8 Bus, 1172 UINT8 DevFunc, 1173 UINT8 Register, 1174 UINT8 Data 1175 ) 1176 /*++ 1177 1178 Routine Description: 1179 Perform an one byte PCI config cycle write 1180 1181 Arguments: 1182 Segment - PCI Segment ACPI _SEG 1183 Bus - PCI Bus 1184 DevFunc - PCI Device(7:3) and Func(2:0) 1185 Register - PCI config space register 1186 Data - Data to write 1187 1188 Returns: 1189 NONE 1190 1191 --*/ 1192 { 1193 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1194 UINT64 Address; 1195 1196 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1197 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0); 1198 } 1199 1200 VOID 1201 PciWrite16 ( 1202 UINT8 Segment, 1203 UINT8 Bus, 1204 UINT8 DevFunc, 1205 UINT8 Register, 1206 UINT16 Data 1207 ) 1208 /*++ 1209 1210 Routine Description: 1211 Perform an two byte PCI config cycle write 1212 1213 Arguments: 1214 Segment - PCI Segment ACPI _SEG 1215 Bus - PCI Bus 1216 DevFunc - PCI Device(7:3) and Func(2:0) 1217 Register - PCI config space register 1218 Data - Data to write 1219 1220 Returns: 1221 None. 1222 1223 --*/ 1224 { 1225 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1226 UINT64 Address; 1227 1228 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1229 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0); 1230 } 1231 1232 VOID 1233 PciWrite32 ( 1234 UINT8 Segment, 1235 UINT8 Bus, 1236 UINT8 DevFunc, 1237 UINT8 Register, 1238 UINT32 Data 1239 ) 1240 /*++ 1241 1242 Routine Description: 1243 Perform an four byte PCI config cycle write 1244 1245 Arguments: 1246 Segment - PCI Segment ACPI _SEG 1247 Bus - PCI Bus 1248 DevFunc - PCI Device(7:3) and Func(2:0) 1249 Register - PCI config space register 1250 Data - Data to write 1251 1252 Returns: 1253 NONE 1254 1255 --*/ 1256 { 1257 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID; 1258 UINT64 Address; 1259 1260 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register); 1261 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0); 1262 } 1263 1264 // 1265 // Stall class functions 1266 // 1267 VOID 1268 EfiStall ( 1269 IN UINTN Microseconds 1270 ) 1271 /*++ 1272 1273 Routine Description: 1274 Delay for at least the request number of microseconds 1275 1276 Arguments: 1277 Microseconds - Number of microseconds to delay. 1278 1279 Returns: 1280 NONE 1281 1282 --*/ 1283 { 1284 EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID; 1285 1286 if (EfiAtRuntime ()) { 1287 EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0); 1288 } else { 1289 gBS->Stall (Microseconds); 1290 } 1291 } 1292 // 1293 // Cache Flush Routine. 1294 // 1295 EFI_STATUS 1296 EfiCpuFlushCache ( 1297 IN EFI_PHYSICAL_ADDRESS Start, 1298 IN UINT64 Length 1299 ) 1300 /*++ 1301 1302 Routine Description: 1303 1304 Flush cache with specified range. 1305 1306 Arguments: 1307 1308 Start - Start address 1309 Length - Length in bytes 1310 1311 Returns: 1312 1313 Status code 1314 1315 EFI_SUCCESS - success 1316 1317 --*/ 1318 { 1319 SalFlushCache (Start, Length); 1320 return EFI_SUCCESS; 1321 } 1322