1 /******************************************************************************
3 * Module Name: osefixf - EFI OSL interfaces
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
48 #define _COMPONENT ACPI_OS_SERVICES
49 ACPI_MODULE_NAME ("osefixf")
52 /* Local definitions */
54 #define ACPI_EFI_PRINT_LENGTH 256
57 /* Local prototypes */
78 static ACPI_PHYSICAL_ADDRESS
79 AcpiEfiGetRsdpViaGuid (
93 static EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL;
96 /******************************************************************************
98 * FUNCTION: AcpiEfiGetRsdpViaGuid
100 * PARAMETERS: Guid1 - GUID to compare
101 * Guid2 - GUID to compare
103 * RETURN: TRUE if Guid1 == Guid2
105 * DESCRIPTION: Compares two GUIDs
107 *****************************************************************************/
119 g1 = (INT32 *) Guid1;
120 g2 = (INT32 *) Guid2;
127 return (r ? FALSE : TRUE);
131 /******************************************************************************
133 * FUNCTION: AcpiEfiGetRsdpViaGuid
137 * RETURN: RSDP address if found
139 * DESCRIPTION: Find RSDP address via EFI using specified GUID.
141 *****************************************************************************/
143 static ACPI_PHYSICAL_ADDRESS
144 AcpiEfiGetRsdpViaGuid (
147 ACPI_PHYSICAL_ADDRESS Address = 0;
151 for (i = 0; i < ST->NumberOfTableEntries; i++)
153 if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid))
155 Address = ACPI_PTR_TO_PHYSADDR (
156 ST->ConfigurationTable[i].VendorTable);
165 /******************************************************************************
167 * FUNCTION: AcpiOsGetRootPointer
171 * RETURN: RSDP physical address
173 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
175 *****************************************************************************/
177 ACPI_PHYSICAL_ADDRESS
178 AcpiOsGetRootPointer (
181 ACPI_PHYSICAL_ADDRESS Address;
182 EFI_GUID Guid10 = ACPI_TABLE_GUID;
183 EFI_GUID Guid20 = ACPI_20_TABLE_GUID;
186 Address = AcpiEfiGetRsdpViaGuid (&Guid20);
189 Address = AcpiEfiGetRsdpViaGuid (&Guid10);
196 /******************************************************************************
198 * FUNCTION: AcpiOsMapMemory
200 * PARAMETERS: where - Physical address of memory to be mapped
201 * length - How much memory to map
203 * RETURN: Pointer to mapped memory. Null on error.
205 * DESCRIPTION: Map physical memory into caller's address space
207 *****************************************************************************/
211 ACPI_PHYSICAL_ADDRESS where,
215 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
219 /******************************************************************************
221 * FUNCTION: AcpiOsUnmapMemory
223 * PARAMETERS: where - Logical address of memory to be unmapped
224 * length - How much memory to unmap
228 * DESCRIPTION: Delete a previously created mapping. Where and Length must
229 * correspond to a previous mapping exactly.
231 *****************************************************************************/
243 /******************************************************************************
245 * FUNCTION: Spinlock interfaces
247 * DESCRIPTION: No-op on single threaded BIOS
249 *****************************************************************************/
253 ACPI_SPINLOCK *OutHandle)
260 ACPI_SPINLOCK Handle)
266 ACPI_SPINLOCK Handle)
273 ACPI_SPINLOCK Handle,
274 ACPI_CPU_FLAGS Flags)
279 /******************************************************************************
281 * FUNCTION: AcpiOsAllocate
283 * PARAMETERS: Size - Amount to allocate, in bytes
285 * RETURN: Pointer to the new allocation. Null on error.
287 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
289 *****************************************************************************/
295 EFI_STATUS EfiStatus;
299 EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3,
300 EfiLoaderData, Size, &Mem);
301 if (EFI_ERROR (EfiStatus))
303 AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n");
311 #ifdef USE_NATIVE_ALLOCATE_ZEROED
312 /******************************************************************************
314 * FUNCTION: AcpiOsAllocateZeroed
316 * PARAMETERS: Size - Amount to allocate, in bytes
318 * RETURN: Pointer to the new allocation. Null on error.
320 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
322 *****************************************************************************/
325 AcpiOsAllocateZeroed (
331 Mem = AcpiOsAllocate (Size);
334 ACPI_MEMSET (Mem, 0, Size);
342 /******************************************************************************
344 * FUNCTION: AcpiOsFree
346 * PARAMETERS: Mem - Pointer to previously allocated memory
350 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
352 *****************************************************************************/
359 uefi_call_wrapper (BS->FreePool, 1, Mem);
363 /*******************************************************************************
365 * FUNCTION: AcpiOsOpenFile
367 * PARAMETERS: Path - File path
368 * Modes - File operation type
370 * RETURN: File descriptor
372 * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
373 * (ACPI_FILE_WRITING).
375 ******************************************************************************/
382 EFI_STATUS EfiStatus = EFI_SUCCESS;
384 EFI_FILE_HANDLE EfiFile = NULL;
385 CHAR16 *Path16 = NULL;
398 OpenModes = EFI_FILE_MODE_READ;
399 if (Modes & ACPI_FILE_WRITING)
401 OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
404 /* Allocate path buffer */
406 Count = ACPI_STRLEN (Path);
407 Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16));
410 EfiStatus = EFI_BAD_BUFFER_SIZE;
415 while (*Pos == '/' || *Pos == '\\')
420 for (i = 0; i < Count; i++)
434 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5,
435 AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0);
436 if (EFI_ERROR (EfiStatus))
438 AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n");
449 return ((ACPI_FILE) EfiFile);
453 /*******************************************************************************
455 * FUNCTION: AcpiOsCloseFile
457 * PARAMETERS: File - File descriptor
461 * DESCRIPTION: Close a file.
463 ******************************************************************************/
469 EFI_FILE_HANDLE EfiFile;
472 if (File == ACPI_FILE_OUT ||
473 File == ACPI_FILE_ERR)
477 EfiFile = (EFI_FILE_HANDLE) File;
478 (void) uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Close, 1, EfiFile);
484 /*******************************************************************************
486 * FUNCTION: AcpiOsReadFile
488 * PARAMETERS: File - File descriptor
489 * Buffer - Data buffer
490 * Size - Data block size
491 * Count - Number of data blocks
493 * RETURN: Size of successfully read buffer
495 * DESCRIPTION: Read from a file.
497 ******************************************************************************/
507 EFI_FILE_HANDLE EfiFile;
509 EFI_STATUS EfiStatus;
512 if (File == ACPI_FILE_OUT ||
513 File == ACPI_FILE_ERR)
518 EfiFile = (EFI_FILE_HANDLE) File;
523 ReadSize = Size * Count;
525 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3,
526 EfiFile, &ReadSize, Buffer);
527 if (EFI_ERROR (EfiStatus))
529 AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n");
541 /*******************************************************************************
543 * FUNCTION: AcpiEfiFlushFile
545 * PARAMETERS: File - File descriptor
546 * Begin - String with boundary
547 * End - Boundary of the string
548 * Pos - Current position
549 * FlushAll - Whether checking boundary before flushing
551 * RETURN: Updated position
553 * DESCRIPTION: Flush cached buffer to the file.
555 ******************************************************************************/
566 if (FlushAll || Pos >= (End - 1))
569 uefi_call_wrapper (File->OutputString, 2, File, Begin);
577 /*******************************************************************************
579 * FUNCTION: AcpiOsWriteFile
581 * PARAMETERS: File - File descriptor
582 * Buffer - Data buffer
583 * Size - Data block size
584 * Count - Number of data blocks
586 * RETURN: Size of successfully written buffer
588 * DESCRIPTION: Write to a file.
590 ******************************************************************************/
600 CHAR16 String[ACPI_EFI_PRINT_LENGTH];
605 EFI_FILE_HANDLE EfiFile;
607 EFI_STATUS EfiStatus;
610 if (File == ACPI_FILE_OUT ||
611 File == ACPI_FILE_ERR)
614 End = String + ACPI_EFI_PRINT_LENGTH - 1;
615 Ascii = ACPI_CAST_PTR (const char, Buffer);
618 for (j = 0; j < Count; j++)
620 for (i = 0; i < Size; i++)
625 Pos = AcpiEfiFlushFile (File, String,
630 Pos = AcpiEfiFlushFile (File, String,
634 Pos = AcpiEfiFlushFile (File, String, End, Pos, TRUE);
638 EfiFile = (EFI_FILE_HANDLE) File;
643 WriteSize = Size * Count;
645 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Write, 3,
646 EfiFile, &WriteSize, Buffer);
647 if (EFI_ERROR (EfiStatus))
649 AcpiLogError ("EFI_FILE_HANDLE->Write() failure.\n");
661 /*******************************************************************************
663 * FUNCTION: AcpiOsGetFileOffset
665 * PARAMETERS: File - File descriptor
667 * RETURN: Size of current position
669 * DESCRIPTION: Get current file offset.
671 ******************************************************************************/
674 AcpiOsGetFileOffset (
684 /*******************************************************************************
686 * FUNCTION: AcpiOsSetFileOffset
688 * PARAMETERS: File - File descriptor
689 * Offset - File offset
690 * From - From begin/end of file
694 * DESCRIPTION: Set current file offset.
696 ******************************************************************************/
699 AcpiOsSetFileOffset (
709 /******************************************************************************
711 * FUNCTION: AcpiOsPrintf
713 * PARAMETERS: Format, ... - Standard printf format
717 * DESCRIPTION: Formatted output.
719 *****************************************************************************/
721 void ACPI_INTERNAL_VAR_XFACE
729 va_start (Args, Format);
730 AcpiOsVprintf (Format, Args);
735 /******************************************************************************
737 * FUNCTION: AcpiOsVprintf
739 * PARAMETERS: Format - Standard printf format
740 * Args - Argument list
744 * DESCRIPTION: Formatted output with arguments list pointer.
746 *****************************************************************************/
754 (void) AcpiUtFileVprintf (ACPI_FILE_OUT, Format, Args);
758 /******************************************************************************
760 * FUNCTION: AcpiOsInitialize
766 * DESCRIPTION: Initialize this module.
768 *****************************************************************************/
779 /******************************************************************************
781 * FUNCTION: AcpiEfiArgify
783 * PARAMETERS: String - Pointer to command line argument strings
784 * which are seperated with spaces
785 * ArgcPtr - Return number of the arguments
786 * ArgvPtr - Return vector of the arguments
790 * DESCRIPTION: Convert EFI arguments into C arguments.
792 *****************************************************************************/
801 int MaxArgc = *ArgcPtr;
803 char **Argv = *ArgvPtr;
805 BOOLEAN IsSingleQuote = FALSE;
806 BOOLEAN IsDoubleQuote = FALSE;
807 BOOLEAN IsEscape = FALSE;
812 return (AE_BAD_PARAMETER);
817 while (*String != '\0')
819 while (ACPI_IS_SPACE (*String))
824 while (*String != '\0')
826 if (ACPI_IS_SPACE (*String) &&
827 !IsSingleQuote && !IsDoubleQuote && !IsEscape)
838 else if (*String == '\\')
842 else if (IsSingleQuote)
846 IsSingleQuote = FALSE;
854 else if (IsDoubleQuote)
858 IsDoubleQuote = FALSE;
870 IsSingleQuote = TRUE;
872 else if (*String == '"')
874 IsDoubleQuote = TRUE;
883 if (Argv && Argc < MaxArgc)
885 Argv[Argc] = CopyBuffer;
890 if (Argv && Argc < MaxArgc)
898 return ((MaxArgc < Argc) ? AE_NO_MEMORY : AE_OK);
902 /******************************************************************************
904 * FUNCTION: AcpiEfiConvertArgcv
906 * PARAMETERS: LoadOptions - Pointer to the EFI options buffer, which
908 * LoadOptionsSize - Size of the EFI options buffer
909 * ArgcPtr - Return number of the arguments
910 * ArgvPtr - Return vector of the arguments
911 * BufferPtr - Buffer to contain the argument strings
915 * DESCRIPTION: Convert EFI arguments into C arguments.
917 *****************************************************************************/
920 AcpiEfiConvertArgcv (
922 UINT32 LoadOptionsSize,
927 ACPI_STATUS Status = AE_OK;
928 UINT32 Count = LoadOptionsSize / sizeof (CHAR16);
937 /* Prepare a buffer to contain the argument strings */
939 Buffer = ACPI_ALLOCATE_ZEROED (Count);
942 Status = AE_NO_MEMORY;
948 /* Extend the argument vector */
957 Argv = ACPI_ALLOCATE_ZEROED (sizeof (char *) * (Argc + 1));
960 Status = AE_NO_MEMORY;
966 * Note: As AcpiEfiArgify() will modify the content of the buffer, so
967 * we need to restore it each time before invoking
971 To = ACPI_CAST_PTR (char, Buffer);
972 for (i = 0; i < Count; i++)
974 *To++ = (char) *From++;
978 * The "Buffer" will contain NULL terminated strings after invoking
979 * AcpiEfiArgify(). The number of the strings are saved in Argc and the
980 * pointers of the strings are saved in Argv.
982 Status = AcpiEfiArgify (Buffer, &Argc, &Argv);
983 if (ACPI_FAILURE (Status))
985 if (Status == AE_NO_MEMORY)
993 if (ACPI_FAILURE (Status))
1002 *BufferPtr = Buffer;
1008 /******************************************************************************
1010 * FUNCTION: efi_main
1012 * PARAMETERS: Image - EFI image handle
1013 * SystemTab - EFI system table
1015 * RETURN: EFI Status
1017 * DESCRIPTION: Entry point of EFI executable
1019 *****************************************************************************/
1024 EFI_SYSTEM_TABLE *SystemTab)
1026 EFI_LOADED_IMAGE *Info;
1027 EFI_STATUS EfiStatus = EFI_SUCCESS;
1031 char *OptBuffer = NULL;
1032 EFI_FILE_IO_INTERFACE *Volume = NULL;
1035 /* Initialize EFI library */
1037 InitializeLib (Image, SystemTab);
1039 /* Retrieve image information */
1041 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1042 Image, &LoadedImageProtocol, ACPI_CAST_PTR (VOID, &Info));
1043 if (EFI_ERROR (EfiStatus))
1045 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(LoadedImageProtocol) failure.\n");
1048 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1049 Info->DeviceHandle, &FileSystemProtocol, (void **) &Volume);
1050 if (EFI_ERROR (EfiStatus))
1052 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(FileSystemProtocol) failure.\n");
1055 EfiStatus = uefi_call_wrapper (Volume->OpenVolume, 2,
1056 Volume, &AcpiGbl_EfiCurrentVolume);
1057 if (EFI_ERROR (EfiStatus))
1059 AcpiLogError ("EFI_FILE_IO_INTERFACE->OpenVolume() failure.\n");
1063 Status = AcpiEfiConvertArgcv (Info->LoadOptions,
1064 Info->LoadOptionsSize, &argc, &argv, &OptBuffer);
1065 if (ACPI_FAILURE (Status))
1067 EfiStatus = EFI_DEVICE_ERROR;
1071 acpi_main (argc, argv);
1081 ACPI_FREE (OptBuffer);