1 /******************************************************************************
3 * Module Name: osefixf - EFI OSL interfaces
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, 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.
50 /* Local definitions */
52 #define ACPI_EFI_PRINT_LENGTH 256
55 /* Local definitions */
57 typedef struct acpi_efi_memory_descriptor {
58 EFI_MEMORY_DESCRIPTOR *Descriptor;
63 } ACPI_EFI_MEMORY_DESCRIPTOR;
66 /* Local prototypes */
91 static ACPI_PHYSICAL_ADDRESS
92 AcpiEfiGetRsdpViaGuid (
108 AcpiEfiInitializeMemoryMap (
112 AcpiEfiTerminateMemoryMap (
116 /* Local variables */
118 static EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL;
119 static ACPI_EFI_MEMORY_DESCRIPTOR AcpiGbl_EfiMemoryMap;
120 static BOOLEAN AcpiGbl_EfiMemoryInitialized = FALSE;
121 static UINTN AcpiGbl_EfiPoolAllocation = EfiBootServicesData;
124 /******************************************************************************
126 * FUNCTION: AcpiEfiGetRsdpViaGuid
128 * PARAMETERS: Guid1 - GUID to compare
129 * Guid2 - GUID to compare
131 * RETURN: TRUE if Guid1 == Guid2
133 * DESCRIPTION: Compares two GUIDs
135 *****************************************************************************/
147 g1 = (INT32 *) Guid1;
148 g2 = (INT32 *) Guid2;
155 return (r ? FALSE : TRUE);
159 /******************************************************************************
161 * FUNCTION: AcpiEfiInitializeMemoryMap
167 * DESCRIPTION: Initialize EFI memory map.
169 *****************************************************************************/
172 AcpiEfiInitializeMemoryMap (
176 ACPI_EFI_MEMORY_DESCRIPTOR *Map;
180 if (AcpiGbl_EfiMemoryInitialized)
187 Map = &AcpiGbl_EfiMemoryMap;
188 Length = sizeof (EFI_MEMORY_DESCRIPTOR);
189 Map->Descriptor = NULL;
190 Status = EFI_BUFFER_TOO_SMALL;
192 /* Allocation and GetMemoryMap() loop */
194 while (!AcpiGbl_EfiMemoryInitialized &&
195 Status == EFI_BUFFER_TOO_SMALL)
197 Map->Descriptor = AcpiEfiAllocatePool (Length);
198 if (!Map->Descriptor)
200 return (AE_NO_MEMORY);
202 Status = uefi_call_wrapper (BS->GetMemoryMap, 5,
203 &Length, Map->Descriptor,
204 &Map->Cookie, &Map->EntrySize, &Map->Version);
205 if (!EFI_ERROR (Status))
207 AcpiGbl_EfiMemoryInitialized = TRUE;
209 else if (Status == EFI_BUFFER_TOO_SMALL)
211 AcpiEfiFreePool (Map->Descriptor);
217 if (!AcpiGbl_EfiMemoryInitialized)
221 AcpiEfiFreePool (Map->Descriptor);
222 Map->Descriptor = NULL;
228 Map->EntryCount = Length / sizeof (EFI_MEMORY_DESCRIPTOR);
235 /******************************************************************************
237 * FUNCTION: AcpiEfiTerminateMemoryMap
243 * DESCRIPTION: Terminate EFI memory map.
245 *****************************************************************************/
248 AcpiEfiTerminateMemoryMap (
252 if (AcpiGbl_EfiMemoryInitialized)
254 AcpiEfiFreePool (AcpiGbl_EfiMemoryMap.Descriptor);
255 AcpiGbl_EfiMemoryInitialized = FALSE;
260 /******************************************************************************
262 * FUNCTION: AcpiEfiGetRsdpViaGuid
266 * RETURN: RSDP address if found
268 * DESCRIPTION: Find RSDP address via EFI using specified GUID.
270 *****************************************************************************/
272 static ACPI_PHYSICAL_ADDRESS
273 AcpiEfiGetRsdpViaGuid (
276 unsigned long Address = 0;
280 for (i = 0; i < ST->NumberOfTableEntries; i++)
282 if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid))
284 Address = (ACPI_PHYSICAL_ADDRESS)
285 ST->ConfigurationTable[i].VendorTable;
290 return ((ACPI_PHYSICAL_ADDRESS) (Address));
294 /******************************************************************************
296 * FUNCTION: AcpiEfiAllocatePool
298 * PARAMETERS: Size - Amount to allocate, in bytes
300 * RETURN: Pointer to the new allocation. Null on error.
302 * DESCRIPTION: Allocate pool memory.
304 *****************************************************************************/
307 AcpiEfiAllocatePool (
310 EFI_STATUS EfiStatus;
314 EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3,
315 AcpiGbl_EfiPoolAllocation, Size, &Mem);
316 if (EFI_ERROR (EfiStatus))
318 AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n");
325 /******************************************************************************
327 * FUNCTION: AcpiEfiFreePool
329 * PARAMETERS: Mem - Pointer to previously allocated memory
333 * DESCRIPTION: Free memory allocated via AcpiEfiAllocatePool
335 *****************************************************************************/
342 uefi_call_wrapper (BS->FreePool, 1, Mem);
346 /******************************************************************************
348 * FUNCTION: AcpiOsGetRootPointer
352 * RETURN: RSDP physical address
354 * DESCRIPTION: Gets the ACPI root pointer (RSDP)
356 *****************************************************************************/
358 ACPI_PHYSICAL_ADDRESS
359 AcpiOsGetRootPointer (
362 ACPI_PHYSICAL_ADDRESS Address;
363 EFI_GUID Guid10 = ACPI_TABLE_GUID;
364 EFI_GUID Guid20 = ACPI_20_TABLE_GUID;
367 Address = AcpiEfiGetRsdpViaGuid (&Guid20);
370 Address = AcpiEfiGetRsdpViaGuid (&Guid10);
377 /******************************************************************************
379 * FUNCTION: AcpiOsMapMemory
381 * PARAMETERS: where - Physical address of memory to be mapped
382 * length - How much memory to map
384 * RETURN: Pointer to mapped memory. Null on error.
386 * DESCRIPTION: Map physical memory into caller's address space
388 *****************************************************************************/
392 ACPI_PHYSICAL_ADDRESS where,
396 EFI_MEMORY_DESCRIPTOR *p;
398 EFI_PHYSICAL_ADDRESS End;
401 for (i = 0, p = AcpiGbl_EfiMemoryMap.Descriptor;
402 i < AcpiGbl_EfiMemoryMap.EntryCount;
403 i++, p = ACPI_ADD_PTR (EFI_MEMORY_DESCRIPTOR, p, AcpiGbl_EfiMemoryMap.EntrySize))
405 Size = p->NumberOfPages << EFI_PAGE_SHIFT;
406 End = p->PhysicalStart + Size;
408 if (!(p->Attribute & EFI_MEMORY_RUNTIME) || !p->VirtualStart)
413 if (where >= p->PhysicalStart && where < End)
415 where += p->VirtualStart - p->PhysicalStart;
420 /* Default to use the physical address */
422 return (ACPI_TO_POINTER ((ACPI_SIZE) where));
426 /******************************************************************************
428 * FUNCTION: AcpiOsUnmapMemory
430 * PARAMETERS: where - Logical address of memory to be unmapped
431 * length - How much memory to unmap
435 * DESCRIPTION: Delete a previously created mapping. Where and Length must
436 * correspond to a previous mapping exactly.
438 *****************************************************************************/
450 /******************************************************************************
452 * FUNCTION: Spinlock interfaces
454 * DESCRIPTION: No-op on single threaded BIOS
456 *****************************************************************************/
460 ACPI_SPINLOCK *OutHandle)
467 ACPI_SPINLOCK Handle)
473 ACPI_SPINLOCK Handle)
480 ACPI_SPINLOCK Handle,
481 ACPI_CPU_FLAGS Flags)
486 /******************************************************************************
488 * FUNCTION: AcpiOsAllocate
490 * PARAMETERS: Size - Amount to allocate, in bytes
492 * RETURN: Pointer to the new allocation. Null on error.
494 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
496 *****************************************************************************/
502 EFI_STATUS EfiStatus;
506 EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3,
507 EfiLoaderData, Size, &Mem);
508 if (EFI_ERROR (EfiStatus))
510 AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n");
518 #ifdef USE_NATIVE_ALLOCATE_ZEROED
519 /******************************************************************************
521 * FUNCTION: AcpiOsAllocateZeroed
523 * PARAMETERS: Size - Amount to allocate, in bytes
525 * RETURN: Pointer to the new allocation. Null on error.
527 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
529 *****************************************************************************/
532 AcpiOsAllocateZeroed (
538 Mem = AcpiOsAllocate (Size);
541 ACPI_MEMSET (Mem, 0, Size);
549 /******************************************************************************
551 * FUNCTION: AcpiOsFree
553 * PARAMETERS: Mem - Pointer to previously allocated memory
557 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
559 *****************************************************************************/
566 uefi_call_wrapper (BS->FreePool, 1, Mem);
570 /*******************************************************************************
572 * FUNCTION: AcpiOsOpenFile
574 * PARAMETERS: Path - File path
575 * Modes - File operation type
577 * RETURN: File descriptor
579 * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
580 * (ACPI_FILE_WRITING).
582 ******************************************************************************/
589 EFI_STATUS EfiStatus = EFI_SUCCESS;
591 EFI_FILE_HANDLE EfiFile = NULL;
592 CHAR16 *Path16 = NULL;
605 OpenModes = EFI_FILE_MODE_READ;
606 if (Modes & ACPI_FILE_WRITING)
608 OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
611 /* Allocate path buffer */
613 Count = ACPI_STRLEN (Path);
614 Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16));
617 EfiStatus = EFI_BAD_BUFFER_SIZE;
622 while (*Pos == '/' || *Pos == '\\')
627 for (i = 0; i < Count; i++)
641 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5,
642 AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0);
643 if (EFI_ERROR (EfiStatus))
645 AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n");
656 return ((ACPI_FILE) EfiFile);
660 /*******************************************************************************
662 * FUNCTION: AcpiOsCloseFile
664 * PARAMETERS: File - File descriptor
668 * DESCRIPTION: Close a file.
670 ******************************************************************************/
676 EFI_FILE_HANDLE EfiFile;
679 if (File == ACPI_FILE_OUT ||
680 File == ACPI_FILE_ERR)
684 EfiFile = (EFI_FILE_HANDLE) File;
685 (void) uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Close, 1, EfiFile);
691 /*******************************************************************************
693 * FUNCTION: AcpiOsReadFile
695 * PARAMETERS: File - File descriptor
696 * Buffer - Data buffer
697 * Size - Data block size
698 * Count - Number of data blocks
700 * RETURN: Size of successfully read buffer
702 * DESCRIPTION: Read from a file.
704 ******************************************************************************/
714 EFI_FILE_HANDLE EfiFile;
716 EFI_STATUS EfiStatus;
719 if (File == ACPI_FILE_OUT ||
720 File == ACPI_FILE_ERR)
725 EfiFile = (EFI_FILE_HANDLE) File;
730 ReadSize = Size * Count;
732 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3,
733 EfiFile, &ReadSize, Buffer);
734 if (EFI_ERROR (EfiStatus))
736 AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n");
748 /*******************************************************************************
750 * FUNCTION: AcpiEfiFlushFile
752 * PARAMETERS: File - File descriptor
753 * Begin - String with boundary
754 * End - Boundary of the string
755 * Pos - Current position
756 * FlushAll - Whether checking boundary before flushing
758 * RETURN: Updated position
760 * DESCRIPTION: Flush cached buffer to the file.
762 ******************************************************************************/
773 if (FlushAll || Pos >= (End - 1))
776 uefi_call_wrapper (File->OutputString, 2, File, Begin);
784 /*******************************************************************************
786 * FUNCTION: AcpiOsWriteFile
788 * PARAMETERS: File - File descriptor
789 * Buffer - Data buffer
790 * Size - Data block size
791 * Count - Number of data blocks
793 * RETURN: Size of successfully written buffer
795 * DESCRIPTION: Write to a file.
797 ******************************************************************************/
807 CHAR16 String[ACPI_EFI_PRINT_LENGTH];
812 EFI_FILE_HANDLE EfiFile;
814 EFI_STATUS EfiStatus;
817 if (File == ACPI_FILE_OUT ||
818 File == ACPI_FILE_ERR)
821 End = String + ACPI_EFI_PRINT_LENGTH - 1;
822 Ascii = ACPI_CAST_PTR (const char, Buffer);
825 for (j = 0; j < Count; j++)
827 for (i = 0; i < Size; i++)
832 Pos = AcpiEfiFlushFile (File, String,
837 Pos = AcpiEfiFlushFile (File, String,
841 Pos = AcpiEfiFlushFile (File, String, End, Pos, TRUE);
845 EfiFile = (EFI_FILE_HANDLE) File;
850 WriteSize = Size * Count;
852 EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Write, 3,
853 EfiFile, &WriteSize, Buffer);
854 if (EFI_ERROR (EfiStatus))
856 AcpiLogError ("EFI_FILE_HANDLE->Write() failure.\n");
868 /*******************************************************************************
870 * FUNCTION: AcpiOsGetFileOffset
872 * PARAMETERS: File - File descriptor
874 * RETURN: Size of current position
876 * DESCRIPTION: Get current file offset.
878 ******************************************************************************/
881 AcpiOsGetFileOffset (
891 /*******************************************************************************
893 * FUNCTION: AcpiOsSetFileOffset
895 * PARAMETERS: File - File descriptor
896 * Offset - File offset
897 * From - From begin/end of file
901 * DESCRIPTION: Set current file offset.
903 ******************************************************************************/
906 AcpiOsSetFileOffset (
916 /******************************************************************************
918 * FUNCTION: AcpiOsPrintf
920 * PARAMETERS: Format, ... - Standard printf format
924 * DESCRIPTION: Formatted output.
926 *****************************************************************************/
928 void ACPI_INTERNAL_VAR_XFACE
936 va_start (Args, Format);
937 AcpiOsVprintf (Format, Args);
942 /******************************************************************************
944 * FUNCTION: AcpiOsVprintf
946 * PARAMETERS: Format - Standard printf format
947 * Args - Argument list
951 * DESCRIPTION: Formatted output with arguments list pointer.
953 *****************************************************************************/
961 (void) AcpiUtFileVprintf (ACPI_FILE_OUT, Format, Args);
965 /******************************************************************************
967 * FUNCTION: AcpiOsInitialize
973 * DESCRIPTION: Initialize this module.
975 *****************************************************************************/
986 /******************************************************************************
988 * FUNCTION: AcpiEfiArgify
990 * PARAMETERS: String - Pointer to command line argument strings
991 * which are seperated with spaces
992 * ArgcPtr - Return number of the arguments
993 * ArgvPtr - Return vector of the arguments
997 * DESCRIPTION: Convert EFI arguments into C arguments.
999 *****************************************************************************/
1008 int MaxArgc = *ArgcPtr;
1010 char **Argv = *ArgvPtr;
1012 BOOLEAN IsSingleQuote = FALSE;
1013 BOOLEAN IsDoubleQuote = FALSE;
1014 BOOLEAN IsEscape = FALSE;
1019 return (AE_BAD_PARAMETER);
1022 CopyBuffer = String;
1024 while (*String != '\0')
1026 while (ACPI_IS_SPACE (*String))
1031 while (*String != '\0')
1033 if (ACPI_IS_SPACE (*String) &&
1034 !IsSingleQuote && !IsDoubleQuote && !IsEscape)
1045 else if (*String == '\\')
1049 else if (IsSingleQuote)
1051 if (*String == '\'')
1053 IsSingleQuote = FALSE;
1061 else if (IsDoubleQuote)
1065 IsDoubleQuote = FALSE;
1075 if (*String == '\'')
1077 IsSingleQuote = TRUE;
1079 else if (*String == '"')
1081 IsDoubleQuote = TRUE;
1090 if (Argv && Argc < MaxArgc)
1092 Argv[Argc] = CopyBuffer;
1097 if (Argv && Argc < MaxArgc)
1105 return ((MaxArgc < Argc) ? AE_NO_MEMORY : AE_OK);
1109 /******************************************************************************
1111 * FUNCTION: AcpiEfiConvertArgcv
1113 * PARAMETERS: LoadOptions - Pointer to the EFI options buffer, which
1114 * is NULL terminated
1115 * LoadOptionsSize - Size of the EFI options buffer
1116 * ArgcPtr - Return number of the arguments
1117 * ArgvPtr - Return vector of the arguments
1118 * BufferPtr - Buffer to contain the argument strings
1122 * DESCRIPTION: Convert EFI arguments into C arguments.
1124 *****************************************************************************/
1127 AcpiEfiConvertArgcv (
1128 CHAR16 *LoadOptions,
1129 UINT32 LoadOptionsSize,
1134 ACPI_STATUS Status = AE_OK;
1135 UINT32 Count = LoadOptionsSize / sizeof (CHAR16);
1144 /* Prepare a buffer to contain the argument strings */
1146 Buffer = ACPI_ALLOCATE_ZEROED (Count);
1149 Status = AE_NO_MEMORY;
1155 /* Extend the argument vector */
1164 Argv = ACPI_ALLOCATE_ZEROED (sizeof (char *) * (Argc + 1));
1167 Status = AE_NO_MEMORY;
1173 * Note: As AcpiEfiArgify() will modify the content of the buffer, so
1174 * we need to restore it each time before invoking
1178 To = ACPI_CAST_PTR (char, Buffer);
1179 for (i = 0; i < Count; i++)
1181 *To++ = (char) *From++;
1185 * The "Buffer" will contain NULL terminated strings after invoking
1186 * AcpiEfiArgify(). The number of the strings are saved in Argc and the
1187 * pointers of the strings are saved in Argv.
1189 Status = AcpiEfiArgify (Buffer, &Argc, &Argv);
1190 if (ACPI_FAILURE (Status))
1192 if (Status == AE_NO_MEMORY)
1200 if (ACPI_FAILURE (Status))
1209 *BufferPtr = Buffer;
1215 /******************************************************************************
1217 * FUNCTION: efi_main
1219 * PARAMETERS: Image - EFI image handle
1220 * SystemTab - EFI system table
1222 * RETURN: EFI Status
1224 * DESCRIPTION: Entry point of EFI executable
1226 *****************************************************************************/
1231 EFI_SYSTEM_TABLE *SystemTab)
1233 EFI_LOADED_IMAGE *Info;
1234 EFI_STATUS EfiStatus = EFI_SUCCESS;
1238 char *OptBuffer = NULL;
1239 EFI_FILE_IO_INTERFACE *Volume = NULL;
1242 /* Initialize EFI library */
1244 InitializeLib (Image, SystemTab);
1246 /* Retrieve image information */
1248 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1249 Image, &LoadedImageProtocol, ACPI_CAST_PTR (VOID, &Info));
1250 if (EFI_ERROR (EfiStatus))
1252 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(LoadedImageProtocol) failure.\n");
1255 AcpiGbl_EfiPoolAllocation = Info->ImageDataType;
1256 EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
1257 Info->DeviceHandle, &FileSystemProtocol, (void **) &Volume);
1258 if (EFI_ERROR (EfiStatus))
1260 AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(FileSystemProtocol) failure.\n");
1263 EfiStatus = uefi_call_wrapper (Volume->OpenVolume, 2,
1264 Volume, &AcpiGbl_EfiCurrentVolume);
1265 if (EFI_ERROR (EfiStatus))
1267 AcpiLogError ("EFI_FILE_IO_INTERFACE->OpenVolume() failure.\n");
1270 Status = AcpiEfiInitializeMemoryMap ();
1271 if (ACPI_FAILURE (Status))
1273 EfiStatus = EFI_DEVICE_ERROR;
1277 Status = AcpiEfiConvertArgcv (Info->LoadOptions,
1278 Info->LoadOptionsSize, &argc, &argv, &OptBuffer);
1279 if (ACPI_FAILURE (Status))
1281 EfiStatus = EFI_DEVICE_ERROR;
1285 acpi_main (argc, argv);
1295 ACPI_FREE (OptBuffer);
1297 AcpiEfiTerminateMemoryMap ();