1/****************************************************************************** 2 * 3 * Module Name: osefixf - EFI OSL interfaces 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include "acpi.h" 45#include "accommon.h" 46#include "acapps.h" 47 48#define _COMPONENT ACPI_OS_SERVICES 49 ACPI_MODULE_NAME ("osefixf") 50 51 52/* Local definitions */ 53 54#define ACPI_EFI_PRINT_LENGTH 256 55 56 57/* Local prototypes */ 58 59static ACPI_STATUS 60AcpiEfiArgify ( 61 char *String, 62 int *ArgcPtr, 63 char ***ArgvPtr); 64 65static BOOLEAN 66AcpiEfiCompareGuid ( 67 EFI_GUID *Guid1, 68 EFI_GUID *Guid2); 69 70static ACPI_STATUS 71AcpiEfiConvertArgcv ( 72 CHAR16 *LoadOpt, 73 UINT32 LoadOptSize, 74 int *ArgcPtr, 75 char ***ArgvPtr, 76 char **BufferPtr); 77 78static ACPI_PHYSICAL_ADDRESS 79AcpiEfiGetRsdpViaGuid ( 80 EFI_GUID *Guid); 81 82static CHAR16 * 83AcpiEfiFlushFile ( 84 ACPI_FILE File, 85 CHAR16 *Begin, 86 CHAR16 *End, 87 CHAR16 *Pos, 88 BOOLEAN FlushAll); 89 90 91/* Local variables */ 92 93static EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL; 94EFI_GUID AcpiGbl_LoadedImageProtocol = LOADED_IMAGE_PROTOCOL; 95EFI_GUID AcpiGbl_TextInProtocol = SIMPLE_TEXT_INPUT_PROTOCOL; 96EFI_GUID AcpiGbl_TextOutProtocol = SIMPLE_TEXT_OUTPUT_PROTOCOL; 97EFI_GUID AcpiGbl_FileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL; 98 99 100/****************************************************************************** 101 * 102 * FUNCTION: AcpiEfiGetRsdpViaGuid 103 * 104 * PARAMETERS: Guid1 - GUID to compare 105 * Guid2 - GUID to compare 106 * 107 * RETURN: TRUE if Guid1 == Guid2 108 * 109 * DESCRIPTION: Compares two GUIDs 110 * 111 *****************************************************************************/ 112 113static BOOLEAN 114AcpiEfiCompareGuid ( 115 EFI_GUID *Guid1, 116 EFI_GUID *Guid2) 117{ 118 INT32 *g1; 119 INT32 *g2; 120 INT32 r; 121 122 123 g1 = (INT32 *) Guid1; 124 g2 = (INT32 *) Guid2; 125 126 r = g1[0] - g2[0]; 127 r |= g1[1] - g2[1]; 128 r |= g1[2] - g2[2]; 129 r |= g1[3] - g2[3]; 130 131 return (r ? FALSE : TRUE); 132} 133 134 135/****************************************************************************** 136 * 137 * FUNCTION: AcpiEfiGetRsdpViaGuid 138 * 139 * PARAMETERS: None 140 * 141 * RETURN: RSDP address if found 142 * 143 * DESCRIPTION: Find RSDP address via EFI using specified GUID. 144 * 145 *****************************************************************************/ 146 147static ACPI_PHYSICAL_ADDRESS 148AcpiEfiGetRsdpViaGuid ( 149 EFI_GUID *Guid) 150{ 151 ACPI_PHYSICAL_ADDRESS Address = 0; 152 int i; 153 154 155 for (i = 0; i < ST->NumberOfTableEntries; i++) 156 { 157 if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid)) 158 { 159 Address = ACPI_PTR_TO_PHYSADDR ( 160 ST->ConfigurationTable[i].VendorTable); 161 break; 162 } 163 } 164 165 return (Address); 166} 167 168 169/****************************************************************************** 170 * 171 * FUNCTION: AcpiOsGetRootPointer 172 * 173 * PARAMETERS: None 174 * 175 * RETURN: RSDP physical address 176 * 177 * DESCRIPTION: Gets the ACPI root pointer (RSDP) 178 * 179 *****************************************************************************/ 180 181ACPI_PHYSICAL_ADDRESS 182AcpiOsGetRootPointer ( 183 void) 184{ 185 ACPI_PHYSICAL_ADDRESS Address; 186 EFI_GUID Guid10 = ACPI_TABLE_GUID; 187 EFI_GUID Guid20 = ACPI_20_TABLE_GUID; 188 189 190 Address = AcpiEfiGetRsdpViaGuid (&Guid20); 191 if (!Address) 192 { 193 Address = AcpiEfiGetRsdpViaGuid (&Guid10); 194 } 195 196 return (Address); 197} 198 199 200/****************************************************************************** 201 * 202 * FUNCTION: AcpiOsMapMemory 203 * 204 * PARAMETERS: where - Physical address of memory to be mapped 205 * length - How much memory to map 206 * 207 * RETURN: Pointer to mapped memory. Null on error. 208 * 209 * DESCRIPTION: Map physical memory into caller's address space 210 * 211 *****************************************************************************/ 212 213void * 214AcpiOsMapMemory ( 215 ACPI_PHYSICAL_ADDRESS where, 216 ACPI_SIZE length) 217{ 218 219 return (ACPI_TO_POINTER ((ACPI_SIZE) where)); 220} 221 222 223/****************************************************************************** 224 * 225 * FUNCTION: AcpiOsUnmapMemory 226 * 227 * PARAMETERS: where - Logical address of memory to be unmapped 228 * length - How much memory to unmap 229 * 230 * RETURN: None 231 * 232 * DESCRIPTION: Delete a previously created mapping. Where and Length must 233 * correspond to a previous mapping exactly. 234 * 235 *****************************************************************************/ 236 237void 238AcpiOsUnmapMemory ( 239 void *where, 240 ACPI_SIZE length) 241{ 242 243 return; 244} 245 246 247/****************************************************************************** 248 * 249 * FUNCTION: Spinlock interfaces 250 * 251 * DESCRIPTION: No-op on single threaded BIOS 252 * 253 *****************************************************************************/ 254 255ACPI_STATUS 256AcpiOsCreateLock ( 257 ACPI_SPINLOCK *OutHandle) 258{ 259 return (AE_OK); 260} 261 262void 263AcpiOsDeleteLock ( 264 ACPI_SPINLOCK Handle) 265{ 266} 267 268ACPI_CPU_FLAGS 269AcpiOsAcquireLock ( 270 ACPI_SPINLOCK Handle) 271{ 272 return (0); 273} 274 275void 276AcpiOsReleaseLock ( 277 ACPI_SPINLOCK Handle, 278 ACPI_CPU_FLAGS Flags) 279{ 280} 281 282 283/****************************************************************************** 284 * 285 * FUNCTION: AcpiOsAllocate 286 * 287 * PARAMETERS: Size - Amount to allocate, in bytes 288 * 289 * RETURN: Pointer to the new allocation. Null on error. 290 * 291 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS. 292 * 293 *****************************************************************************/ 294 295void * 296AcpiOsAllocate ( 297 ACPI_SIZE Size) 298{ 299 EFI_STATUS EfiStatus; 300 void *Mem; 301 302 303 EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3, 304 EfiLoaderData, Size, &Mem); 305 if (EFI_ERROR (EfiStatus)) 306 { 307 AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n"); 308 return (NULL); 309 } 310 311 return (Mem); 312} 313 314 315#ifdef USE_NATIVE_ALLOCATE_ZEROED 316/****************************************************************************** 317 * 318 * FUNCTION: AcpiOsAllocateZeroed 319 * 320 * PARAMETERS: Size - Amount to allocate, in bytes 321 * 322 * RETURN: Pointer to the new allocation. Null on error. 323 * 324 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. 325 * 326 *****************************************************************************/ 327 328void * 329AcpiOsAllocateZeroed ( 330 ACPI_SIZE Size) 331{ 332 void *Mem; 333 334 335 Mem = AcpiOsAllocate (Size); 336 if (Mem) 337 { 338 memset (Mem, 0, Size); 339 } 340 341 return (Mem); 342} 343#endif 344 345 346/****************************************************************************** 347 * 348 * FUNCTION: AcpiOsFree 349 * 350 * PARAMETERS: Mem - Pointer to previously allocated memory 351 * 352 * RETURN: None 353 * 354 * DESCRIPTION: Free memory allocated via AcpiOsAllocate 355 * 356 *****************************************************************************/ 357 358void 359AcpiOsFree ( 360 void *Mem) 361{ 362 363 uefi_call_wrapper (BS->FreePool, 1, Mem); 364} 365 366 367/******************************************************************************* 368 * 369 * FUNCTION: AcpiOsOpenFile 370 * 371 * PARAMETERS: Path - File path 372 * Modes - File operation type 373 * 374 * RETURN: File descriptor 375 * 376 * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing 377 * (ACPI_FILE_WRITING). 378 * 379 ******************************************************************************/ 380 381ACPI_FILE 382AcpiOsOpenFile ( 383 const char *Path, 384 UINT8 Modes) 385{ 386 EFI_STATUS EfiStatus = EFI_SUCCESS; 387 UINT64 OpenModes; 388 EFI_FILE_HANDLE EfiFile = NULL; 389 CHAR16 *Path16 = NULL; 390 CHAR16 *Pos16; 391 const char *Pos; 392 INTN Count, i; 393 394 395 if (!Path) 396 { 397 return (NULL); 398 } 399 400 /* Convert modes */ 401 402 OpenModes = EFI_FILE_MODE_READ; 403 if (Modes & ACPI_FILE_WRITING) 404 { 405 OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE); 406 } 407 408 /* Allocate path buffer */ 409 410 Count = strlen (Path); 411 Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16)); 412 if (!Path16) 413 { 414 EfiStatus = EFI_BAD_BUFFER_SIZE; 415 goto ErrorExit; 416 } 417 Pos = Path; 418 Pos16 = Path16; 419 while (*Pos == '/' || *Pos == '\\') 420 { 421 Pos++; 422 Count--; 423 } 424 for (i = 0; i < Count; i++) 425 { 426 if (*Pos == '/') 427 { 428 *Pos16++ = '\\'; 429 Pos++; 430 } 431 else 432 { 433 *Pos16++ = *Pos++; 434 } 435 } 436 *Pos16 = '\0'; 437 438 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5, 439 AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0); 440 if (EFI_ERROR (EfiStatus)) 441 { 442 AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n"); 443 goto ErrorExit; 444 } 445 446ErrorExit: 447 448 if (Path16) 449 { 450 ACPI_FREE (Path16); 451 } 452 453 return ((ACPI_FILE) EfiFile); 454} 455 456 457/******************************************************************************* 458 * 459 * FUNCTION: AcpiOsCloseFile 460 * 461 * PARAMETERS: File - File descriptor 462 * 463 * RETURN: None. 464 * 465 * DESCRIPTION: Close a file. 466 * 467 ******************************************************************************/ 468 469void 470AcpiOsCloseFile ( 471 ACPI_FILE File) 472{ 473 EFI_FILE_HANDLE EfiFile; 474 475 476 if (File == ACPI_FILE_OUT || 477 File == ACPI_FILE_ERR) 478 { 479 return; 480 } 481 EfiFile = (EFI_FILE_HANDLE) File; 482 (void) uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Close, 1, EfiFile); 483 484 return; 485} 486 487 488/******************************************************************************* 489 * 490 * FUNCTION: AcpiOsReadFile 491 * 492 * PARAMETERS: File - File descriptor 493 * Buffer - Data buffer 494 * Size - Data block size 495 * Count - Number of data blocks 496 * 497 * RETURN: Size of successfully read buffer 498 * 499 * DESCRIPTION: Read from a file. 500 * 501 ******************************************************************************/ 502 503int 504AcpiOsReadFile ( 505 ACPI_FILE File, 506 void *Buffer, 507 ACPI_SIZE Size, 508 ACPI_SIZE Count) 509{ 510 int Length = -1; 511 EFI_FILE_HANDLE EfiFile; 512 UINTN ReadSize; 513 EFI_STATUS EfiStatus; 514 515 516 if (File == ACPI_FILE_OUT || 517 File == ACPI_FILE_ERR) 518 { 519 } 520 else 521 { 522 EfiFile = (EFI_FILE_HANDLE) File; 523 if (!EfiFile) 524 { 525 goto ErrorExit; 526 } 527 ReadSize = Size * Count; 528 529 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3, 530 EfiFile, &ReadSize, Buffer); 531 if (EFI_ERROR (EfiStatus)) 532 { 533 AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n"); 534 goto ErrorExit; 535 } 536 Length = ReadSize; 537 } 538 539ErrorExit: 540 541 return (Length); 542} 543 544 545/******************************************************************************* 546 * 547 * FUNCTION: AcpiEfiFlushFile 548 * 549 * PARAMETERS: File - File descriptor 550 * Begin - String with boundary 551 * End - Boundary of the string 552 * Pos - Current position 553 * FlushAll - Whether checking boundary before flushing 554 * 555 * RETURN: Updated position 556 * 557 * DESCRIPTION: Flush cached buffer to the file. 558 * 559 ******************************************************************************/ 560 561static CHAR16 * 562AcpiEfiFlushFile ( 563 ACPI_FILE File, 564 CHAR16 *Begin, 565 CHAR16 *End, 566 CHAR16 *Pos, 567 BOOLEAN FlushAll) 568{ 569 570 if (FlushAll || Pos >= (End - 1)) 571 { 572 *Pos = 0; 573 uefi_call_wrapper (File->OutputString, 2, File, Begin); 574 Pos = Begin; 575 } 576 577 return (Pos); 578} 579 580 581/******************************************************************************* 582 * 583 * FUNCTION: AcpiOsWriteFile 584 * 585 * PARAMETERS: File - File descriptor 586 * Buffer - Data buffer 587 * Size - Data block size 588 * Count - Number of data blocks 589 * 590 * RETURN: Size of successfully written buffer 591 * 592 * DESCRIPTION: Write to a file. 593 * 594 ******************************************************************************/ 595 596int 597AcpiOsWriteFile ( 598 ACPI_FILE File, 599 void *Buffer, 600 ACPI_SIZE Size, 601 ACPI_SIZE Count) 602{ 603 int Length = -1; 604 CHAR16 String[ACPI_EFI_PRINT_LENGTH]; 605 const char *Ascii; 606 CHAR16 *End; 607 CHAR16 *Pos; 608 int i, j; 609 EFI_FILE_HANDLE EfiFile; 610 UINTN WriteSize; 611 EFI_STATUS EfiStatus; 612 613 614 if (File == ACPI_FILE_OUT || 615 File == ACPI_FILE_ERR) 616 { 617 Pos = String; 618 End = String + ACPI_EFI_PRINT_LENGTH - 1; 619 Ascii = ACPI_CAST_PTR (const char, Buffer); 620 Length = 0; 621 622 for (j = 0; j < Count; j++) 623 { 624 for (i = 0; i < Size; i++) 625 { 626 if (*Ascii == '\n') 627 { 628 *Pos++ = '\r'; 629 Pos = AcpiEfiFlushFile (File, String, 630 End, Pos, FALSE); 631 } 632 *Pos++ = *Ascii++; 633 Length++; 634 Pos = AcpiEfiFlushFile (File, String, 635 End, Pos, FALSE); 636 } 637 } 638 Pos = AcpiEfiFlushFile (File, String, End, Pos, TRUE); 639 } 640 else 641 { 642 EfiFile = (EFI_FILE_HANDLE) File; 643 if (!EfiFile) 644 { 645 goto ErrorExit; 646 } 647 WriteSize = Size * Count; 648 649 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Write, 3, 650 EfiFile, &WriteSize, Buffer); 651 if (EFI_ERROR (EfiStatus)) 652 { 653 AcpiLogError ("EFI_FILE_HANDLE->Write() failure.\n"); 654 goto ErrorExit; 655 } 656 Length = WriteSize; 657 } 658 659ErrorExit: 660 661 return (Length); 662} 663 664 665/******************************************************************************* 666 * 667 * FUNCTION: AcpiOsGetFileOffset 668 * 669 * PARAMETERS: File - File descriptor 670 * 671 * RETURN: Size of current position 672 * 673 * DESCRIPTION: Get current file offset. 674 * 675 ******************************************************************************/ 676 677long 678AcpiOsGetFileOffset ( 679 ACPI_FILE File) 680{ 681 long Offset = -1; 682 683 684 return (Offset); 685} 686 687 688/******************************************************************************* 689 * 690 * FUNCTION: AcpiOsSetFileOffset 691 * 692 * PARAMETERS: File - File descriptor 693 * Offset - File offset 694 * From - From begin/end of file 695 * 696 * RETURN: Status 697 * 698 * DESCRIPTION: Set current file offset. 699 * 700 ******************************************************************************/ 701 702ACPI_STATUS 703AcpiOsSetFileOffset ( 704 ACPI_FILE File, 705 long Offset, 706 UINT8 From) 707{ 708 709 return (AE_SUPPORT); 710} 711 712 713/****************************************************************************** 714 * 715 * FUNCTION: AcpiOsPrintf 716 * 717 * PARAMETERS: Format, ... - Standard printf format 718 * 719 * RETURN: None 720 * 721 * DESCRIPTION: Formatted output. 722 * 723 *****************************************************************************/ 724 725void ACPI_INTERNAL_VAR_XFACE 726AcpiOsPrintf ( 727 const char *Format, 728 ...) 729{ 730 va_list Args; 731 732 733 va_start (Args, Format); 734 AcpiOsVprintf (Format, Args); 735 va_end (Args); 736} 737 738 739/****************************************************************************** 740 * 741 * FUNCTION: AcpiOsVprintf 742 * 743 * PARAMETERS: Format - Standard printf format 744 * Args - Argument list 745 * 746 * RETURN: None 747 * 748 * DESCRIPTION: Formatted output with arguments list pointer. 749 * 750 *****************************************************************************/ 751 752void 753AcpiOsVprintf ( 754 const char *Format, 755 va_list Args) 756{ 757 758 (void) AcpiUtFileVprintf (ACPI_FILE_OUT, Format, Args); 759} 760 761 762/****************************************************************************** 763 * 764 * FUNCTION: AcpiOsInitialize 765 * 766 * PARAMETERS: None 767 * 768 * RETURN: Status 769 * 770 * DESCRIPTION: Initialize this module. 771 * 772 *****************************************************************************/ 773 774ACPI_STATUS 775AcpiOsInitialize ( 776 void) 777{ 778 779 return (AE_OK); 780} 781 782 783/****************************************************************************** 784 * 785 * FUNCTION: AcpiEfiArgify 786 * 787 * PARAMETERS: String - Pointer to command line argument strings 788 * which are seperated with spaces 789 * ArgcPtr - Return number of the arguments 790 * ArgvPtr - Return vector of the arguments 791 * 792 * RETURN: Status 793 * 794 * DESCRIPTION: Convert EFI arguments into C arguments. 795 * 796 *****************************************************************************/ 797 798static ACPI_STATUS 799AcpiEfiArgify ( 800 char *String, 801 int *ArgcPtr, 802 char ***ArgvPtr) 803{ 804 char *CopyBuffer; 805 int MaxArgc = *ArgcPtr; 806 int Argc = 0; 807 char **Argv = *ArgvPtr; 808 char *Arg; 809 BOOLEAN IsSingleQuote = FALSE; 810 BOOLEAN IsDoubleQuote = FALSE; 811 BOOLEAN IsEscape = FALSE; 812 813 814 if (String == NULL) 815 { 816 return (AE_BAD_PARAMETER); 817 } 818 819 CopyBuffer = String; 820 821 while (*String != '\0') 822 { 823 while (isspace (*String)) 824 { 825 *String++ = '\0'; 826 } 827 Arg = CopyBuffer; 828 while (*String != '\0') 829 { 830 if (isspace (*String) && 831 !IsSingleQuote && !IsDoubleQuote && !IsEscape) 832 { 833 *Arg++ = '\0'; 834 String++; 835 break; 836 } 837 if (IsEscape) 838 { 839 IsEscape = FALSE; 840 *Arg++ = *String; 841 } 842 else if (*String == '\\') 843 { 844 IsEscape = TRUE; 845 } 846 else if (IsSingleQuote) 847 { 848 if (*String == '\'') 849 { 850 IsSingleQuote = FALSE; 851 *Arg++ = '\0'; 852 } 853 else 854 { 855 *Arg++ = *String; 856 } 857 } 858 else if (IsDoubleQuote) 859 { 860 if (*String == '"') 861 { 862 IsDoubleQuote = FALSE; 863 *Arg = '\0'; 864 } 865 else 866 { 867 *Arg++ = *String; 868 } 869 } 870 else 871 { 872 if (*String == '\'') 873 { 874 IsSingleQuote = TRUE; 875 } 876 else if (*String == '"') 877 { 878 IsDoubleQuote = TRUE; 879 } 880 else 881 { 882 *Arg++ = *String; 883 } 884 } 885 String++; 886 } 887 if (Argv && Argc < MaxArgc) 888 { 889 Argv[Argc] = CopyBuffer; 890 } 891 Argc++; 892 CopyBuffer = Arg; 893 } 894 if (Argv && Argc < MaxArgc) 895 { 896 Argv[Argc] = NULL; 897 } 898 899 *ArgcPtr = Argc; 900 *ArgvPtr = Argv; 901 902 return ((MaxArgc < Argc) ? AE_NO_MEMORY : AE_OK); 903} 904 905 906/****************************************************************************** 907 * 908 * FUNCTION: AcpiEfiConvertArgcv 909 * 910 * PARAMETERS: LoadOptions - Pointer to the EFI options buffer, which 911 * is NULL terminated 912 * LoadOptionsSize - Size of the EFI options buffer 913 * ArgcPtr - Return number of the arguments 914 * ArgvPtr - Return vector of the arguments 915 * BufferPtr - Buffer to contain the argument strings 916 * 917 * RETURN: Status 918 * 919 * DESCRIPTION: Convert EFI arguments into C arguments. 920 * 921 *****************************************************************************/ 922 923static ACPI_STATUS 924AcpiEfiConvertArgcv ( 925 CHAR16 *LoadOptions, 926 UINT32 LoadOptionsSize, 927 int *ArgcPtr, 928 char ***ArgvPtr, 929 char **BufferPtr) 930{ 931 ACPI_STATUS Status = AE_OK; 932 UINT32 Count = LoadOptionsSize / sizeof (CHAR16); 933 UINT32 i; 934 CHAR16 *From; 935 char *To; 936 int Argc = 0; 937 char **Argv = NULL; 938 char *Buffer; 939 940 941 /* Prepare a buffer to contain the argument strings */ 942 943 Buffer = ACPI_ALLOCATE_ZEROED (Count); 944 if (!Buffer) 945 { 946 Status = AE_NO_MEMORY; 947 goto ErrorExit; 948 } 949 950TryAgain: 951 952 /* Extend the argument vector */ 953 954 if (Argv) 955 { 956 ACPI_FREE (Argv); 957 Argv = NULL; 958 } 959 if (Argc > 0) 960 { 961 Argv = ACPI_ALLOCATE_ZEROED (sizeof (char *) * (Argc + 1)); 962 if (!Argv) 963 { 964 Status = AE_NO_MEMORY; 965 goto ErrorExit; 966 } 967 } 968 969 /* 970 * Note: As AcpiEfiArgify() will modify the content of the buffer, so 971 * we need to restore it each time before invoking 972 * AcpiEfiArgify(). 973 */ 974 From = LoadOptions; 975 To = ACPI_CAST_PTR (char, Buffer); 976 for (i = 0; i < Count; i++) 977 { 978 *To++ = (char) *From++; 979 } 980 981 /* 982 * The "Buffer" will contain NULL terminated strings after invoking 983 * AcpiEfiArgify(). The number of the strings are saved in Argc and the 984 * pointers of the strings are saved in Argv. 985 */ 986 Status = AcpiEfiArgify (Buffer, &Argc, &Argv); 987 if (ACPI_FAILURE (Status)) 988 { 989 if (Status == AE_NO_MEMORY) 990 { 991 goto TryAgain; 992 } 993 } 994 995ErrorExit: 996 997 if (ACPI_FAILURE (Status)) 998 { 999 ACPI_FREE (Buffer); 1000 ACPI_FREE (Argv); 1001 } 1002 else 1003 { 1004 *ArgcPtr = Argc; 1005 *ArgvPtr = Argv; 1006 *BufferPtr = Buffer; 1007 } 1008 return (Status); 1009} 1010 1011 1012/****************************************************************************** 1013 * 1014 * FUNCTION: efi_main 1015 * 1016 * PARAMETERS: Image - EFI image handle 1017 * SystemTab - EFI system table 1018 * 1019 * RETURN: EFI Status 1020 * 1021 * DESCRIPTION: Entry point of EFI executable 1022 * 1023 *****************************************************************************/ 1024 1025EFI_STATUS 1026efi_main ( 1027 EFI_HANDLE Image, 1028 EFI_SYSTEM_TABLE *SystemTab) 1029{ 1030 EFI_LOADED_IMAGE *Info; 1031 EFI_STATUS EfiStatus = EFI_SUCCESS; 1032 ACPI_STATUS Status; 1033 int argc; 1034 char **argv = NULL; 1035 char *OptBuffer = NULL; 1036 EFI_FILE_IO_INTERFACE *Volume = NULL; 1037 1038 1039 /* Initialize global variables */ 1040 1041 ST = SystemTab; 1042 BS = SystemTab->BootServices; 1043 1044 /* Retrieve image information */ 1045 1046 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3, 1047 Image, &AcpiGbl_LoadedImageProtocol, ACPI_CAST_PTR (VOID, &Info)); 1048 if (EFI_ERROR (EfiStatus)) 1049 { 1050 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(LoadedImageProtocol) failure.\n"); 1051 return (EfiStatus); 1052 } 1053 1054 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3, 1055 Info->DeviceHandle, &AcpiGbl_FileSystemProtocol, (void **) &Volume); 1056 if (EFI_ERROR (EfiStatus)) 1057 { 1058 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(FileSystemProtocol) failure.\n"); 1059 return (EfiStatus); 1060 } 1061 EfiStatus = uefi_call_wrapper (Volume->OpenVolume, 2, 1062 Volume, &AcpiGbl_EfiCurrentVolume); 1063 if (EFI_ERROR (EfiStatus)) 1064 { 1065 AcpiLogError ("EFI_FILE_IO_INTERFACE->OpenVolume() failure.\n"); 1066 return (EfiStatus); 1067 } 1068 1069 Status = AcpiEfiConvertArgcv (Info->LoadOptions, 1070 Info->LoadOptionsSize, &argc, &argv, &OptBuffer); 1071 if (ACPI_FAILURE (Status)) 1072 { 1073 EfiStatus = EFI_DEVICE_ERROR; 1074 goto ErrorAlloc; 1075 } 1076 1077 acpi_main (argc, argv); 1078 1079ErrorAlloc: 1080 1081 if (argv) 1082 { 1083 ACPI_FREE (argv); 1084 } 1085 if (OptBuffer) 1086 { 1087 ACPI_FREE (OptBuffer); 1088 } 1089 1090 return (EfiStatus); 1091} 1092