blob: 091c0eae632264eb10e836f7ffac43b7f392ce87 [file] [log] [blame]
/******************************************************************************
*
* Module Name: osefixf - EFI OSL interfaces
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpi.h"
#include "accommon.h"
#include "acapps.h"
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME ("osefixf")
/* Local definitions */
#define ACPI_EFI_PRINT_LENGTH 256
/* Local prototypes */
static ACPI_STATUS
AcpiEfiArgify (
char *String,
int *ArgcPtr,
char ***ArgvPtr);
static BOOLEAN
AcpiEfiCompareGuid (
EFI_GUID *Guid1,
EFI_GUID *Guid2);
static ACPI_STATUS
AcpiEfiConvertArgcv (
CHAR16 *LoadOpt,
UINT32 LoadOptSize,
int *ArgcPtr,
char ***ArgvPtr,
char **BufferPtr);
static ACPI_PHYSICAL_ADDRESS
AcpiEfiGetRsdpViaGuid (
EFI_GUID *Guid);
static CHAR16 *
AcpiEfiFlushFile (
ACPI_FILE File,
CHAR16 *Begin,
CHAR16 *End,
CHAR16 *Pos,
BOOLEAN FlushAll);
/* Local variables */
static EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL;
EFI_GUID AcpiGbl_LoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
EFI_GUID AcpiGbl_TextInProtocol = SIMPLE_TEXT_INPUT_PROTOCOL;
EFI_GUID AcpiGbl_TextOutProtocol = SIMPLE_TEXT_OUTPUT_PROTOCOL;
EFI_GUID AcpiGbl_FileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
/******************************************************************************
*
* FUNCTION: AcpiEfiGetRsdpViaGuid
*
* PARAMETERS: Guid1 - GUID to compare
* Guid2 - GUID to compare
*
* RETURN: TRUE if Guid1 == Guid2
*
* DESCRIPTION: Compares two GUIDs
*
*****************************************************************************/
static BOOLEAN
AcpiEfiCompareGuid (
EFI_GUID *Guid1,
EFI_GUID *Guid2)
{
INT32 *g1;
INT32 *g2;
INT32 r;
g1 = (INT32 *) Guid1;
g2 = (INT32 *) Guid2;
r = g1[0] - g2[0];
r |= g1[1] - g2[1];
r |= g1[2] - g2[2];
r |= g1[3] - g2[3];
return (r ? FALSE : TRUE);
}
/******************************************************************************
*
* FUNCTION: AcpiEfiGetRsdpViaGuid
*
* PARAMETERS: None
*
* RETURN: RSDP address if found
*
* DESCRIPTION: Find RSDP address via EFI using specified GUID.
*
*****************************************************************************/
static ACPI_PHYSICAL_ADDRESS
AcpiEfiGetRsdpViaGuid (
EFI_GUID *Guid)
{
ACPI_PHYSICAL_ADDRESS Address = 0;
int i;
for (i = 0; i < ST->NumberOfTableEntries; i++)
{
if (AcpiEfiCompareGuid (&ST->ConfigurationTable[i].VendorGuid, Guid))
{
Address = ACPI_PTR_TO_PHYSADDR (
ST->ConfigurationTable[i].VendorTable);
break;
}
}
return (Address);
}
/******************************************************************************
*
* FUNCTION: AcpiOsGetRootPointer
*
* PARAMETERS: None
*
* RETURN: RSDP physical address
*
* DESCRIPTION: Gets the ACPI root pointer (RSDP)
*
*****************************************************************************/
ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer (
void)
{
ACPI_PHYSICAL_ADDRESS Address;
EFI_GUID Guid10 = ACPI_TABLE_GUID;
EFI_GUID Guid20 = ACPI_20_TABLE_GUID;
Address = AcpiEfiGetRsdpViaGuid (&Guid20);
if (!Address)
{
Address = AcpiEfiGetRsdpViaGuid (&Guid10);
}
return (Address);
}
/******************************************************************************
*
* FUNCTION: AcpiOsMapMemory
*
* PARAMETERS: where - Physical address of memory to be mapped
* length - How much memory to map
*
* RETURN: Pointer to mapped memory. Null on error.
*
* DESCRIPTION: Map physical memory into caller's address space
*
*****************************************************************************/
void *
AcpiOsMapMemory (
ACPI_PHYSICAL_ADDRESS where,
ACPI_SIZE length)
{
return (ACPI_TO_POINTER ((ACPI_SIZE) where));
}
/******************************************************************************
*
* FUNCTION: AcpiOsUnmapMemory
*
* PARAMETERS: where - Logical address of memory to be unmapped
* length - How much memory to unmap
*
* RETURN: None
*
* DESCRIPTION: Delete a previously created mapping. Where and Length must
* correspond to a previous mapping exactly.
*
*****************************************************************************/
void
AcpiOsUnmapMemory (
void *where,
ACPI_SIZE length)
{
return;
}
/******************************************************************************
*
* FUNCTION: Spinlock interfaces
*
* DESCRIPTION: No-op on single threaded BIOS
*
*****************************************************************************/
ACPI_STATUS
AcpiOsCreateLock (
ACPI_SPINLOCK *OutHandle)
{
return (AE_OK);
}
void
AcpiOsDeleteLock (
ACPI_SPINLOCK Handle)
{
}
ACPI_CPU_FLAGS
AcpiOsAcquireLock (
ACPI_SPINLOCK Handle)
{
return (0);
}
void
AcpiOsReleaseLock (
ACPI_SPINLOCK Handle,
ACPI_CPU_FLAGS Flags)
{
}
/******************************************************************************
*
* FUNCTION: AcpiOsAllocate
*
* PARAMETERS: Size - Amount to allocate, in bytes
*
* RETURN: Pointer to the new allocation. Null on error.
*
* DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
*
*****************************************************************************/
void *
AcpiOsAllocate (
ACPI_SIZE Size)
{
EFI_STATUS EfiStatus;
void *Mem;
EfiStatus = uefi_call_wrapper (BS->AllocatePool, 3,
EfiLoaderData, Size, &Mem);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_BOOT_SERVICES->AllocatePool(EfiLoaderData) failure.\n");
return (NULL);
}
return (Mem);
}
#ifdef USE_NATIVE_ALLOCATE_ZEROED
/******************************************************************************
*
* FUNCTION: AcpiOsAllocateZeroed
*
* PARAMETERS: Size - Amount to allocate, in bytes
*
* RETURN: Pointer to the new allocation. Null on error.
*
* DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
*
*****************************************************************************/
void *
AcpiOsAllocateZeroed (
ACPI_SIZE Size)
{
void *Mem;
Mem = AcpiOsAllocate (Size);
if (Mem)
{
memset (Mem, 0, Size);
}
return (Mem);
}
#endif
/******************************************************************************
*
* FUNCTION: AcpiOsFree
*
* PARAMETERS: Mem - Pointer to previously allocated memory
*
* RETURN: None
*
* DESCRIPTION: Free memory allocated via AcpiOsAllocate
*
*****************************************************************************/
void
AcpiOsFree (
void *Mem)
{
uefi_call_wrapper (BS->FreePool, 1, Mem);
}
/*******************************************************************************
*
* FUNCTION: AcpiOsOpenFile
*
* PARAMETERS: Path - File path
* Modes - File operation type
*
* RETURN: File descriptor
*
* DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
* (ACPI_FILE_WRITING).
*
******************************************************************************/
ACPI_FILE
AcpiOsOpenFile (
const char *Path,
UINT8 Modes)
{
EFI_STATUS EfiStatus = EFI_SUCCESS;
UINT64 OpenModes;
EFI_FILE_HANDLE EfiFile = NULL;
CHAR16 *Path16 = NULL;
CHAR16 *Pos16;
const char *Pos;
INTN Count, i;
if (!Path)
{
return (NULL);
}
/* Convert modes */
OpenModes = EFI_FILE_MODE_READ;
if (Modes & ACPI_FILE_WRITING)
{
OpenModes |= (EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE);
}
/* Allocate path buffer */
Count = strlen (Path);
Path16 = ACPI_ALLOCATE_ZEROED ((Count + 1) * sizeof (CHAR16));
if (!Path16)
{
EfiStatus = EFI_BAD_BUFFER_SIZE;
goto ErrorExit;
}
Pos = Path;
Pos16 = Path16;
while (*Pos == '/' || *Pos == '\\')
{
Pos++;
Count--;
}
for (i = 0; i < Count; i++)
{
if (*Pos == '/')
{
*Pos16++ = '\\';
Pos++;
}
else
{
*Pos16++ = *Pos++;
}
}
*Pos16 = '\0';
EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Open, 5,
AcpiGbl_EfiCurrentVolume, &EfiFile, Path16, OpenModes, 0);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_FILE_HANDLE->Open() failure.\n");
goto ErrorExit;
}
ErrorExit:
if (Path16)
{
ACPI_FREE (Path16);
}
return ((ACPI_FILE) EfiFile);
}
/*******************************************************************************
*
* FUNCTION: AcpiOsCloseFile
*
* PARAMETERS: File - File descriptor
*
* RETURN: None.
*
* DESCRIPTION: Close a file.
*
******************************************************************************/
void
AcpiOsCloseFile (
ACPI_FILE File)
{
EFI_FILE_HANDLE EfiFile;
if (File == ACPI_FILE_OUT ||
File == ACPI_FILE_ERR)
{
return;
}
EfiFile = (EFI_FILE_HANDLE) File;
(void) uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Close, 1, EfiFile);
return;
}
/*******************************************************************************
*
* FUNCTION: AcpiOsReadFile
*
* PARAMETERS: File - File descriptor
* Buffer - Data buffer
* Size - Data block size
* Count - Number of data blocks
*
* RETURN: Size of successfully read buffer
*
* DESCRIPTION: Read from a file.
*
******************************************************************************/
int
AcpiOsReadFile (
ACPI_FILE File,
void *Buffer,
ACPI_SIZE Size,
ACPI_SIZE Count)
{
int Length = -1;
EFI_FILE_HANDLE EfiFile;
UINTN ReadSize;
EFI_STATUS EfiStatus;
if (File == ACPI_FILE_OUT ||
File == ACPI_FILE_ERR)
{
}
else
{
EfiFile = (EFI_FILE_HANDLE) File;
if (!EfiFile)
{
goto ErrorExit;
}
ReadSize = Size * Count;
EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3,
EfiFile, &ReadSize, Buffer);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_FILE_HANDLE->Read() failure.\n");
goto ErrorExit;
}
Length = ReadSize;
}
ErrorExit:
return (Length);
}
/*******************************************************************************
*
* FUNCTION: AcpiEfiFlushFile
*
* PARAMETERS: File - File descriptor
* Begin - String with boundary
* End - Boundary of the string
* Pos - Current position
* FlushAll - Whether checking boundary before flushing
*
* RETURN: Updated position
*
* DESCRIPTION: Flush cached buffer to the file.
*
******************************************************************************/
static CHAR16 *
AcpiEfiFlushFile (
ACPI_FILE File,
CHAR16 *Begin,
CHAR16 *End,
CHAR16 *Pos,
BOOLEAN FlushAll)
{
if (FlushAll || Pos >= (End - 1))
{
*Pos = 0;
uefi_call_wrapper (File->OutputString, 2, File, Begin);
Pos = Begin;
}
return (Pos);
}
/*******************************************************************************
*
* FUNCTION: AcpiOsWriteFile
*
* PARAMETERS: File - File descriptor
* Buffer - Data buffer
* Size - Data block size
* Count - Number of data blocks
*
* RETURN: Size of successfully written buffer
*
* DESCRIPTION: Write to a file.
*
******************************************************************************/
int
AcpiOsWriteFile (
ACPI_FILE File,
void *Buffer,
ACPI_SIZE Size,
ACPI_SIZE Count)
{
int Length = -1;
CHAR16 String[ACPI_EFI_PRINT_LENGTH];
const char *Ascii;
CHAR16 *End;
CHAR16 *Pos;
int i, j;
EFI_FILE_HANDLE EfiFile;
UINTN WriteSize;
EFI_STATUS EfiStatus;
if (File == ACPI_FILE_OUT ||
File == ACPI_FILE_ERR)
{
Pos = String;
End = String + ACPI_EFI_PRINT_LENGTH - 1;
Ascii = ACPI_CAST_PTR (const char, Buffer);
Length = 0;
for (j = 0; j < Count; j++)
{
for (i = 0; i < Size; i++)
{
if (*Ascii == '\n')
{
*Pos++ = '\r';
Pos = AcpiEfiFlushFile (File, String,
End, Pos, FALSE);
}
*Pos++ = *Ascii++;
Length++;
Pos = AcpiEfiFlushFile (File, String,
End, Pos, FALSE);
}
}
Pos = AcpiEfiFlushFile (File, String, End, Pos, TRUE);
}
else
{
EfiFile = (EFI_FILE_HANDLE) File;
if (!EfiFile)
{
goto ErrorExit;
}
WriteSize = Size * Count;
EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Write, 3,
EfiFile, &WriteSize, Buffer);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_FILE_HANDLE->Write() failure.\n");
goto ErrorExit;
}
Length = WriteSize;
}
ErrorExit:
return (Length);
}
/*******************************************************************************
*
* FUNCTION: AcpiOsGetFileOffset
*
* PARAMETERS: File - File descriptor
*
* RETURN: Size of current position
*
* DESCRIPTION: Get current file offset.
*
******************************************************************************/
long
AcpiOsGetFileOffset (
ACPI_FILE File)
{
long Offset = -1;
return (Offset);
}
/*******************************************************************************
*
* FUNCTION: AcpiOsSetFileOffset
*
* PARAMETERS: File - File descriptor
* Offset - File offset
* From - From begin/end of file
*
* RETURN: Status
*
* DESCRIPTION: Set current file offset.
*
******************************************************************************/
ACPI_STATUS
AcpiOsSetFileOffset (
ACPI_FILE File,
long Offset,
UINT8 From)
{
return (AE_SUPPORT);
}
/******************************************************************************
*
* FUNCTION: AcpiOsPrintf
*
* PARAMETERS: Format, ... - Standard printf format
*
* RETURN: None
*
* DESCRIPTION: Formatted output.
*
*****************************************************************************/
void ACPI_INTERNAL_VAR_XFACE
AcpiOsPrintf (
const char *Format,
...)
{
va_list Args;
va_start (Args, Format);
AcpiOsVprintf (Format, Args);
va_end (Args);
}
/******************************************************************************
*
* FUNCTION: AcpiOsVprintf
*
* PARAMETERS: Format - Standard printf format
* Args - Argument list
*
* RETURN: None
*
* DESCRIPTION: Formatted output with arguments list pointer.
*
*****************************************************************************/
void
AcpiOsVprintf (
const char *Format,
va_list Args)
{
(void) AcpiUtFileVprintf (ACPI_FILE_OUT, Format, Args);
}
/******************************************************************************
*
* FUNCTION: AcpiOsInitialize
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize this module.
*
*****************************************************************************/
ACPI_STATUS
AcpiOsInitialize (
void)
{
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AcpiEfiArgify
*
* PARAMETERS: String - Pointer to command line argument strings
* which are seperated with spaces
* ArgcPtr - Return number of the arguments
* ArgvPtr - Return vector of the arguments
*
* RETURN: Status
*
* DESCRIPTION: Convert EFI arguments into C arguments.
*
*****************************************************************************/
static ACPI_STATUS
AcpiEfiArgify (
char *String,
int *ArgcPtr,
char ***ArgvPtr)
{
char *CopyBuffer;
int MaxArgc = *ArgcPtr;
int Argc = 0;
char **Argv = *ArgvPtr;
char *Arg;
BOOLEAN IsSingleQuote = FALSE;
BOOLEAN IsDoubleQuote = FALSE;
BOOLEAN IsEscape = FALSE;
if (String == NULL)
{
return (AE_BAD_PARAMETER);
}
CopyBuffer = String;
while (*String != '\0')
{
while (isspace (*String))
{
*String++ = '\0';
}
Arg = CopyBuffer;
while (*String != '\0')
{
if (isspace (*String) &&
!IsSingleQuote && !IsDoubleQuote && !IsEscape)
{
*Arg++ = '\0';
String++;
break;
}
if (IsEscape)
{
IsEscape = FALSE;
*Arg++ = *String;
}
else if (*String == '\\')
{
IsEscape = TRUE;
}
else if (IsSingleQuote)
{
if (*String == '\'')
{
IsSingleQuote = FALSE;
*Arg++ = '\0';
}
else
{
*Arg++ = *String;
}
}
else if (IsDoubleQuote)
{
if (*String == '"')
{
IsDoubleQuote = FALSE;
*Arg = '\0';
}
else
{
*Arg++ = *String;
}
}
else
{
if (*String == '\'')
{
IsSingleQuote = TRUE;
}
else if (*String == '"')
{
IsDoubleQuote = TRUE;
}
else
{
*Arg++ = *String;
}
}
String++;
}
if (Argv && Argc < MaxArgc)
{
Argv[Argc] = CopyBuffer;
}
Argc++;
CopyBuffer = Arg;
}
if (Argv && Argc < MaxArgc)
{
Argv[Argc] = NULL;
}
*ArgcPtr = Argc;
*ArgvPtr = Argv;
return ((MaxArgc < Argc) ? AE_NO_MEMORY : AE_OK);
}
/******************************************************************************
*
* FUNCTION: AcpiEfiConvertArgcv
*
* PARAMETERS: LoadOptions - Pointer to the EFI options buffer, which
* is NULL terminated
* LoadOptionsSize - Size of the EFI options buffer
* ArgcPtr - Return number of the arguments
* ArgvPtr - Return vector of the arguments
* BufferPtr - Buffer to contain the argument strings
*
* RETURN: Status
*
* DESCRIPTION: Convert EFI arguments into C arguments.
*
*****************************************************************************/
static ACPI_STATUS
AcpiEfiConvertArgcv (
CHAR16 *LoadOptions,
UINT32 LoadOptionsSize,
int *ArgcPtr,
char ***ArgvPtr,
char **BufferPtr)
{
ACPI_STATUS Status = AE_OK;
UINT32 Count = LoadOptionsSize / sizeof (CHAR16);
UINT32 i;
CHAR16 *From;
char *To;
int Argc = 0;
char **Argv = NULL;
char *Buffer;
/* Prepare a buffer to contain the argument strings */
Buffer = ACPI_ALLOCATE_ZEROED (Count);
if (!Buffer)
{
Status = AE_NO_MEMORY;
goto ErrorExit;
}
TryAgain:
/* Extend the argument vector */
if (Argv)
{
ACPI_FREE (Argv);
Argv = NULL;
}
if (Argc > 0)
{
Argv = ACPI_ALLOCATE_ZEROED (sizeof (char *) * (Argc + 1));
if (!Argv)
{
Status = AE_NO_MEMORY;
goto ErrorExit;
}
}
/*
* Note: As AcpiEfiArgify() will modify the content of the buffer, so
* we need to restore it each time before invoking
* AcpiEfiArgify().
*/
From = LoadOptions;
To = ACPI_CAST_PTR (char, Buffer);
for (i = 0; i < Count; i++)
{
*To++ = (char) *From++;
}
/*
* The "Buffer" will contain NULL terminated strings after invoking
* AcpiEfiArgify(). The number of the strings are saved in Argc and the
* pointers of the strings are saved in Argv.
*/
Status = AcpiEfiArgify (Buffer, &Argc, &Argv);
if (ACPI_FAILURE (Status))
{
if (Status == AE_NO_MEMORY)
{
goto TryAgain;
}
}
ErrorExit:
if (ACPI_FAILURE (Status))
{
ACPI_FREE (Buffer);
ACPI_FREE (Argv);
}
else
{
*ArgcPtr = Argc;
*ArgvPtr = Argv;
*BufferPtr = Buffer;
}
return (Status);
}
/******************************************************************************
*
* FUNCTION: efi_main
*
* PARAMETERS: Image - EFI image handle
* SystemTab - EFI system table
*
* RETURN: EFI Status
*
* DESCRIPTION: Entry point of EFI executable
*
*****************************************************************************/
EFI_STATUS
efi_main (
EFI_HANDLE Image,
EFI_SYSTEM_TABLE *SystemTab)
{
EFI_LOADED_IMAGE *Info;
EFI_STATUS EfiStatus = EFI_SUCCESS;
ACPI_STATUS Status;
int argc;
char **argv = NULL;
char *OptBuffer = NULL;
EFI_FILE_IO_INTERFACE *Volume = NULL;
/* Initialize global variables */
ST = SystemTab;
BS = SystemTab->BootServices;
/* Retrieve image information */
EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
Image, &AcpiGbl_LoadedImageProtocol, ACPI_CAST_PTR (VOID, &Info));
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(LoadedImageProtocol) failure.\n");
return (EfiStatus);
}
EfiStatus = uefi_call_wrapper (BS->HandleProtocol, 3,
Info->DeviceHandle, &AcpiGbl_FileSystemProtocol, (void **) &Volume);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_BOOT_SERVICES->HandleProtocol(FileSystemProtocol) failure.\n");
return (EfiStatus);
}
EfiStatus = uefi_call_wrapper (Volume->OpenVolume, 2,
Volume, &AcpiGbl_EfiCurrentVolume);
if (EFI_ERROR (EfiStatus))
{
AcpiLogError ("EFI_FILE_IO_INTERFACE->OpenVolume() failure.\n");
return (EfiStatus);
}
Status = AcpiEfiConvertArgcv (Info->LoadOptions,
Info->LoadOptionsSize, &argc, &argv, &OptBuffer);
if (ACPI_FAILURE (Status))
{
EfiStatus = EFI_DEVICE_ERROR;
goto ErrorAlloc;
}
acpi_main (argc, argv);
ErrorAlloc:
if (argv)
{
ACPI_FREE (argv);
}
if (OptBuffer)
{
ACPI_FREE (OptBuffer);
}
return (EfiStatus);
}