summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2016-12-20 07:26:32 -0800
committerGitHub <noreply@github.com>2016-12-20 07:26:32 -0800
commit9e63bf92de0583429e615f915d3df31eac1581db (patch)
tree3eda2a43e863fa04ad8b8c059d83b073b68f28d7
parent86c2065d7d1e28889c67a43d6631cb3f2c3ed2cc (diff)
parent3fcc59f4755607dd066ac8ef869f0aa95e871b84 (diff)
downloadacpica-9e63bf92de0583429e615f915d3df31eac1581db.tar.gz
Merge pull request #195 from zetalog/efi-hello
Efi hello
-rw-r--r--generate/efi/Makefile.config3
-rw-r--r--generate/efi/efihello/Makefile55
-rw-r--r--source/components/utilities/utclib.c142
-rw-r--r--source/include/acclib.h38
-rw-r--r--source/include/platform/acefi.h4
-rw-r--r--source/include/platform/acefiex.h52
-rw-r--r--source/include/platform/acenv.h3
-rw-r--r--source/os_specific/efi/oseficlib.c401
-rw-r--r--source/tools/efihello/efihello.c81
9 files changed, 758 insertions, 21 deletions
diff --git a/generate/efi/Makefile.config b/generate/efi/Makefile.config
index bbb78b72a..225123419 100644
--- a/generate/efi/Makefile.config
+++ b/generate/efi/Makefile.config
@@ -38,7 +38,7 @@
#
# Common defines
#
-PROGS = acpidump
+PROGS = acpidump efihello
HOST = $(shell uname -m | sed s,i[3456789]86,ia32,)
TARGET = $(shell uname -m | sed s,i[3456789]86,ia32,)
OBJDIR = obj
@@ -70,6 +70,7 @@ ACPICA_UTILITIES = $(ACPICA_CORE)/utilities
# ACPICA tool and utility source directories
#
ACPIDUMP = $(ACPICA_TOOLS)/acpidump
+EFIHELLO = $(ACPICA_TOOLS)/efihello
#
# Common ACPICA header files
diff --git a/generate/efi/efihello/Makefile b/generate/efi/efihello/Makefile
new file mode 100644
index 000000000..c28743efd
--- /dev/null
+++ b/generate/efi/efihello/Makefile
@@ -0,0 +1,55 @@
+#
+# efihello - ACPI EFI demo
+#
+
+#
+# Note: This makefile is intended to be used from within the native
+# ACPICA directory structure, from under generate/efi. It specifically
+# places all object files in a generate/efi subdirectory, not within
+# the various ACPICA source directories. This prevents collisions
+# between different compilations of the same source file with different
+# compile options, and prevents pollution of the source code.
+#
+include ../Makefile.config
+PROG = $(OBJDIR)/efihello
+
+#
+# Search paths for source files
+#
+vpath %.c \
+ $(EFIHELLO)\
+ $(ACPICA_UTILITIES)\
+ $(ACPICA_COMMON)\
+ $(ACPICA_OSL)\
+ $(ACPICA_EFI)
+
+HEADERS = \
+ $(wildcard $(EFIHELLO)/*.h)
+
+OBJECTS = \
+ $(OBJDIR)/efihello.o\
+ $(OBJDIR)/getopt.o\
+ $(OBJDIR)/oseficlib.o\
+ $(OBJDIR)/osefixf.o\
+ $(OBJDIR)/utascii.o\
+ $(OBJDIR)/utbuffer.o\
+ $(OBJDIR)/utdebug.o\
+ $(OBJDIR)/utclib.o\
+ $(OBJDIR)/utexcep.o\
+ $(OBJDIR)/utglobal.o\
+ $(OBJDIR)/utmath.o\
+ $(OBJDIR)/utprint.o\
+ $(OBJDIR)/utstring.o\
+ $(OBJDIR)/utxferror.o
+
+#
+# Flags specific to efihello
+#
+CFLAGS += \
+ -DACPI_EFI_HELLO\
+ -I$(EFIHELLO)
+
+#
+# Common Rules
+#
+include ../Makefile.rules
diff --git a/source/components/utilities/utclib.c b/source/components/utilities/utclib.c
index 26fbaf958..31241a992 100644
--- a/source/components/utilities/utclib.c
+++ b/source/components/utilities/utclib.c
@@ -201,6 +201,61 @@ memcmp (
/*******************************************************************************
*
+ * FUNCTION: memmove
+ *
+ * PARAMETERS: Dest - Target of the copy
+ * Src - Source buffer to copy
+ * Count - Number of bytes to copy
+ *
+ * RETURN: Dest
+ *
+ * DESCRIPTION: Copy arbitrary bytes of memory with respect to the overlapping
+ *
+ ******************************************************************************/
+
+void *
+memmove (
+ void *Dest,
+ const void *Src,
+ ACPI_SIZE Count)
+{
+ char *New = (char *) Dest;
+ char *Old = (char *) Src;
+
+
+ if (Old > New)
+ {
+ /* Copy from the beginning */
+
+ while (Count)
+ {
+ *New = *Old;
+ New++;
+ Old++;
+ Count--;
+ }
+ }
+ else if (Old < New)
+ {
+ /* Copy from the end */
+
+ New = New + Count - 1;
+ Old = Old + Count - 1;
+ while (Count)
+ {
+ *New = *Old;
+ New--;
+ Old--;
+ Count--;
+ }
+ }
+
+ return (Dest);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: memcpy
*
* PARAMETERS: Dest - Target of the copy
@@ -303,6 +358,93 @@ strlen (
/*******************************************************************************
*
+ * FUNCTION: strpbrk
+ *
+ * PARAMETERS: String - Null terminated string
+ * Delimiters - Delimiters to match
+ *
+ * RETURN: The first occurance in the string of any of the bytes in the
+ * delimiters
+ *
+ * DESCRIPTION: Search a string for any of a set of the delimiters
+ *
+ ******************************************************************************/
+
+char *
+strpbrk (
+ const char *String,
+ const char *Delimiters)
+{
+ const char *Delimiter;
+
+
+ for ( ; *String != '\0'; ++String)
+ {
+ for (Delimiter = Delimiters; *Delimiter != '\0'; Delimiter++)
+ {
+ if (*String == *Delimiter)
+ {
+ return (ACPI_CAST_PTR (char, String));
+ }
+ }
+ }
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strtok
+ *
+ * PARAMETERS: String - Null terminated string
+ * Delimiters - Delimiters to match
+ *
+ * RETURN: Pointer to the next token
+ *
+ * DESCRIPTION: Split string into tokens
+ *
+ ******************************************************************************/
+
+char*
+strtok (
+ char *String,
+ const char *Delimiters)
+{
+ char *Begin = String;
+ static char *SavedPtr;
+
+
+ if (Begin == NULL)
+ {
+ if (SavedPtr == NULL)
+ {
+ return (NULL);
+ }
+ Begin = SavedPtr;
+ }
+
+ SavedPtr = strpbrk (Begin, Delimiters);
+ while (SavedPtr == Begin)
+ {
+ *Begin++ = '\0';
+ SavedPtr = strpbrk (Begin, Delimiters);
+ }
+
+ if (SavedPtr)
+ {
+ *SavedPtr++ = '\0';
+ return (Begin);
+ }
+ else
+ {
+ return (NULL);
+ }
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: strcpy
*
* PARAMETERS: DstString - Target of the copy
diff --git a/source/include/acclib.h b/source/include/acclib.h
index f18f2b8b7..e39b3e3e8 100644
--- a/source/include/acclib.h
+++ b/source/include/acclib.h
@@ -176,6 +176,16 @@ strchr (
int ch);
char *
+strpbrk (
+ const char *String,
+ const char *Delimiters);
+
+char *
+strtok (
+ char *String,
+ const char *Delimiters);
+
+char *
strcpy (
char *DstString,
const char *SrcString);
@@ -237,6 +247,12 @@ memcpy (
ACPI_SIZE Count);
void *
+memmove (
+ void *Dest,
+ const void *Src,
+ ACPI_SIZE Count);
+
+void *
memset (
void *Dest,
int Value,
@@ -298,6 +314,13 @@ sprintf (
*/
extern int errno;
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#define putchar(c) fputc(stdout, c)
+#define getchar(c) fgetc(stdin)
+
int
vprintf (
const char *Format,
@@ -352,6 +375,21 @@ fseek (
long
ftell (
FILE *File);
+
+int
+fgetc (
+ FILE *File);
+
+int
+fputc (
+ FILE *File,
+ char c);
+
+char *
+fgets (
+ char *s,
+ ACPI_SIZE Size,
+ FILE *File);
#endif
#endif /* _ACCLIB_H */
diff --git a/source/include/platform/acefi.h b/source/include/platform/acefi.h
index dfa489454..8328ab609 100644
--- a/source/include/platform/acefi.h
+++ b/source/include/platform/acefi.h
@@ -323,8 +323,10 @@ struct _ACPI_EFI_PCI_IO;
extern struct _ACPI_EFI_SYSTEM_TABLE *ST;
extern struct _ACPI_EFI_BOOT_SERVICES *BS;
-#define FILE struct _ACPI_SIMPLE_TEXT_OUTPUT_INTERFACE
+typedef union acpi_efi_file ACPI_EFI_FILE;
+#define FILE ACPI_EFI_FILE
+extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
diff --git a/source/include/platform/acefiex.h b/source/include/platform/acefiex.h
index 1101b39b2..e90b89712 100644
--- a/source/include/platform/acefiex.h
+++ b/source/include/platform/acefiex.h
@@ -167,6 +167,20 @@ typedef struct {
UINT8 Data4[8];
} ACPI_EFI_GUID;
+typedef struct {
+ UINT16 Year; /* 1998 - 20XX */
+ UINT8 Month; /* 1 - 12 */
+ UINT8 Day; /* 1 - 31 */
+ UINT8 Hour; /* 0 - 23 */
+ UINT8 Minute; /* 0 - 59 */
+ UINT8 Second; /* 0 - 59 */
+ UINT8 Pad1;
+ UINT32 Nanosecond; /* 0 - 999,999,999 */
+ INT16 TimeZone; /* -1440 to 1440 or 2047 */
+ UINT8 Daylight;
+ UINT8 Pad2;
+} ACPI_EFI_TIME;
+
typedef struct _ACPI_EFI_DEVICE_PATH {
UINT8 Type;
UINT8 SubType;
@@ -447,6 +461,22 @@ ACPI_EFI_STATUS
struct _ACPI_EFI_FILE_HANDLE *File,
UINT64 *Position);
+#define ACPI_EFI_FILE_INFO_ID \
+ { 0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} }
+
+typedef struct {
+ UINT64 Size;
+ UINT64 FileSize;
+ UINT64 PhysicalSize;
+ ACPI_EFI_TIME CreateTime;
+ ACPI_EFI_TIME LastAccessTime;
+ ACPI_EFI_TIME ModificationTime;
+ UINT64 Attribute;
+ CHAR16 FileName[1];
+} ACPI_EFI_FILE_INFO;
+
+#define SIZE_OF_ACPI_EFI_FILE_INFO ACPI_OFFSET(ACPI_EFI_FILE_INFO, FileName)
+
typedef
ACPI_EFI_STATUS
(ACPI_EFI_API *ACPI_EFI_FILE_GET_INFO) (
@@ -529,6 +559,15 @@ ACPI_EFI_STATUS
ACPI_EFI_HANDLE ImageHandle);
+typedef
+ACPI_EFI_STATUS
+(ACPI_EFI_API *ACPI_EFI_SET_WATCHDOG_TIMER) (
+ UINTN Timeout,
+ UINT64 WatchdogCode,
+ UINTN DataSize,
+ CHAR16 *WatchdogData);
+
+
#define EFI_IMAGE_INFORMATION_REVISION 0x1000
typedef struct {
UINT32 Revision;
@@ -816,13 +855,12 @@ typedef struct _ACPI_EFI_BOOT_SERVICES {
ACPI_EFI_EXIT_BOOT_SERVICES ExitBootServices;
ACPI_EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
ACPI_EFI_STALL Stall;
- ACPI_EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
#else
ACPI_EFI_UNKNOWN_INTERFACE ExitBootServices;
ACPI_EFI_UNKNOWN_INTERFACE GetNextMonotonicCount;
ACPI_EFI_UNKNOWN_INTERFACE Stall;
- ACPI_EFI_UNKNOWN_INTERFACE SetWatchdogTimer;
#endif
+ ACPI_EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
#if 0
ACPI_EFI_CONNECT_CONTROLLER ConnectController;
@@ -968,6 +1006,15 @@ typedef struct _ACPI_EFI_PCI_IO {
VOID *RomImage;
} ACPI_EFI_PCI_IO;
+/* FILE abstraction */
+
+union acpi_efi_file {
+ struct _ACPI_EFI_FILE_HANDLE File;
+ struct _ACPI_SIMPLE_TEXT_OUTPUT_INTERFACE ConOut;
+ struct _ACPI_SIMPLE_INPUT_INTERFACE ConIn;
+};
+
+
/* GNU EFI definitions */
#if defined(_GNU_EFI)
@@ -1001,5 +1048,6 @@ extern ACPI_EFI_GUID AcpiGbl_LoadedImageProtocol;
extern ACPI_EFI_GUID AcpiGbl_TextInProtocol;
extern ACPI_EFI_GUID AcpiGbl_TextOutProtocol;
extern ACPI_EFI_GUID AcpiGbl_FileSystemProtocol;
+extern ACPI_EFI_GUID AcpiGbl_GenericFileInfo;
#endif /* __ACEFIEX_H__ */
diff --git a/source/include/platform/acenv.h b/source/include/platform/acenv.h
index 02c9af1d0..6e715bb50 100644
--- a/source/include/platform/acenv.h
+++ b/source/include/platform/acenv.h
@@ -148,7 +148,8 @@
(defined ACPI_NAMES_APP) || \
(defined ACPI_SRC_APP) || \
(defined ACPI_XTRACT_APP) || \
- (defined ACPI_EXAMPLE_APP)
+ (defined ACPI_EXAMPLE_APP) || \
+ (defined ACPI_EFI_HELLO)
#define ACPI_APPLICATION
#define ACPI_SINGLE_THREADED
#define USE_NATIVE_ALLOCATE_ZEROED
diff --git a/source/os_specific/efi/oseficlib.c b/source/os_specific/efi/oseficlib.c
index b0956ce90..75d81b797 100644
--- a/source/os_specific/efi/oseficlib.c
+++ b/source/os_specific/efi/oseficlib.c
@@ -125,6 +125,17 @@
#define ACPI_EFI_PRINT_LENGTH 256
+#define ACPI_EFI_KEY_ESC 0x0000
+#define ACPI_EFI_KEY_BACKSPACE 0x0008
+#define ACPI_EFI_KEY_ENTER 0x000D
+#define ACPI_EFI_KEY_CTRL_C 0x0003
+
+#define ACPI_EFI_ASCII_NULL 0x00
+#define ACPI_EFI_ASCII_DEL 0x7F
+#define ACPI_EFI_ASCII_ESC 0x1B
+#define ACPI_EFI_ASCII_CR '\r'
+#define ACPI_EFI_ASCII_NL '\n'
+
/* Local prototypes */
@@ -142,6 +153,11 @@ AcpiEfiConvertArgcv (
char ***ArgvPtr,
char **BufferPtr);
+static int
+AcpiEfiGetFileInfo (
+ FILE *File,
+ ACPI_EFI_FILE_INFO **InfoPtr);
+
static CHAR16 *
AcpiEfiFlushFile (
FILE *File,
@@ -153,6 +169,7 @@ AcpiEfiFlushFile (
/* Local variables */
+FILE *stdin = NULL;
FILE *stdout = NULL;
FILE *stderr = NULL;
static ACPI_EFI_FILE_HANDLE AcpiGbl_EfiCurrentVolume = NULL;
@@ -160,6 +177,7 @@ ACPI_EFI_GUID AcpiGbl_LoadedImageProtocol = ACPI_EFI_LOADED_IMAGE_
ACPI_EFI_GUID AcpiGbl_TextInProtocol = ACPI_SIMPLE_TEXT_INPUT_PROTOCOL;
ACPI_EFI_GUID AcpiGbl_TextOutProtocol = ACPI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
ACPI_EFI_GUID AcpiGbl_FileSystemProtocol = ACPI_SIMPLE_FILE_SYSTEM_PROTOCOL;
+ACPI_EFI_GUID AcpiGbl_GenericFileInfo = ACPI_EFI_FILE_INFO_ID;
int errno = 0;
@@ -324,7 +342,8 @@ fclose (
ACPI_EFI_FILE_HANDLE EfiFile;
- if (File == stdout || File == stderr)
+ if (File == stdin || File == stdout ||
+ File == stderr)
{
return;
}
@@ -337,6 +356,135 @@ fclose (
/*******************************************************************************
*
+ * FUNCTION: fgetc
+ *
+ * PARAMETERS: File - File descriptor
+ *
+ * RETURN: The character read or EOF on the end of the file or error
+ *
+ * DESCRIPTION: Read a character from the file.
+ *
+ ******************************************************************************/
+
+int
+fgetc (
+ FILE *File)
+{
+ UINT8 Byte;
+ int Length;
+
+
+ Length = fread (ACPI_CAST_PTR (void, &Byte), 1, 1, File);
+ if (Length == 0)
+ {
+ Length = EOF;
+ }
+ else if (Length == 1)
+ {
+ Length = (int) Byte;
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: fputc
+ *
+ * PARAMETERS: File - File descriptor
+ * c - Character byte
+ *
+ * RETURN: The character written or EOF on the end of the file or error
+ *
+ * DESCRIPTION: Write a character to the file.
+ *
+ ******************************************************************************/
+
+int
+fputc (
+ FILE *File,
+ char c)
+{
+ UINT8 Byte = (UINT8) c;
+ int Length;
+
+
+ Length = fwrite (ACPI_CAST_PTR (void, &Byte), 1, 1, File);
+ if (Length == 0)
+ {
+ Length = EOF;
+ }
+ else if (Length == 1)
+ {
+ Length = (int) Byte;
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: fgets
+ *
+ * PARAMETERS: File - File descriptor
+ *
+ * RETURN: The string read
+ *
+ * DESCRIPTION: Read a string from the file.
+ *
+ ******************************************************************************/
+
+char *
+fgets (
+ char *s,
+ ACPI_SIZE Size,
+ FILE *File)
+{
+ ACPI_SIZE ReadBytes = 0;
+ int Ret;
+
+
+ if (Size <= 1)
+ {
+ errno = EINVAL;
+ return (NULL);
+ }
+ while (ReadBytes < (Size - 1))
+ {
+ Ret = fgetc (File);
+ if (Ret == EOF)
+ {
+ if (ReadBytes == 0)
+ {
+ return (NULL);
+ }
+ break;
+ }
+ else if (Ret < 0)
+ {
+ errno = EIO;
+ return (NULL);
+ }
+ else if (Ret == '\n')
+ {
+ s[ReadBytes++] = (char) Ret;
+ break;
+ }
+ else
+ {
+ s[ReadBytes++] = (char) Ret;
+ }
+ }
+
+ s[ReadBytes] = '\0';
+ return (s);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: fread
*
* PARAMETERS: Buffer - Data buffer
@@ -357,14 +505,87 @@ fread (
ACPI_SIZE Count,
FILE *File)
{
- int Length = -1;
- ACPI_EFI_FILE_HANDLE EfiFile;
- UINTN ReadSize;
- ACPI_EFI_STATUS EfiStatus;
+ int Length = -EINVAL;
+ ACPI_EFI_FILE_HANDLE EfiFile;
+ ACPI_SIMPLE_INPUT_INTERFACE *In;
+ UINTN ReadSize;
+ ACPI_EFI_STATUS EfiStatus;
+ ACPI_EFI_INPUT_KEY Key;
+ ACPI_SIZE Pos = 0;
+
+ if (!Buffer)
+ {
+ errno = EINVAL;
+ goto ErrorExit;
+ }
+
+ ReadSize = Size * Count;
if (File == stdout || File == stderr)
{
+ /* Do not support read operations on output console */
+ }
+ else if (File == stdin)
+ {
+ In = ACPI_CAST_PTR (ACPI_SIMPLE_INPUT_INTERFACE, File);
+
+ while (Pos < ReadSize)
+ {
+WaitKey:
+ EfiStatus = uefi_call_wrapper (In->ReadKeyStroke, 2, In, &Key);
+ if (ACPI_EFI_ERROR (EfiStatus))
+ {
+ if (EfiStatus == ACPI_EFI_NOT_READY)
+ {
+ goto WaitKey;
+ }
+ errno = EIO;
+ Length = -EIO;
+ fprintf (stderr,
+ "SIMPLE_INPUT_INTERFACE->ReadKeyStroke() failure.\n");
+ goto ErrorExit;
+ }
+
+ switch (Key.UnicodeChar)
+ {
+ case ACPI_EFI_KEY_CTRL_C:
+
+ break;
+
+ case ACPI_EFI_KEY_ENTER:
+
+ *(ACPI_ADD_PTR (UINT8, Buffer, Pos)) = (UINT8) ACPI_EFI_ASCII_CR;
+ if (Pos < ReadSize - 1)
+ {
+ /* Drop CR in case we don't have sufficient buffer */
+
+ Pos++;
+ }
+ *(ACPI_ADD_PTR (UINT8, Buffer, Pos)) = (UINT8) ACPI_EFI_ASCII_NL;
+ Pos++;
+ break;
+
+ case ACPI_EFI_KEY_BACKSPACE:
+
+ *(ACPI_ADD_PTR (UINT8, Buffer, Pos)) = (UINT8) ACPI_EFI_ASCII_DEL;
+ Pos++;
+ break;
+
+ case ACPI_EFI_KEY_ESC:
+
+ *(ACPI_ADD_PTR (UINT8, Buffer, Pos)) = (UINT8) ACPI_EFI_ASCII_ESC;
+ Pos++;
+ break;
+
+ default:
+
+ *(ACPI_ADD_PTR (UINT8, Buffer, Pos)) = (UINT8) Key.UnicodeChar;
+ Pos++;
+ break;
+ }
+ }
+ Length = Pos;
}
else
{
@@ -374,7 +595,6 @@ fread (
errno = EINVAL;
goto ErrorExit;
}
- ReadSize = Size * Count;
EfiStatus = uefi_call_wrapper (AcpiGbl_EfiCurrentVolume->Read, 3,
EfiFile, &ReadSize, Buffer);
@@ -382,6 +602,7 @@ fread (
{
fprintf (stderr, "EFI_FILE_HANDLE->Read() failure.\n");
errno = EIO;
+ Length = -EIO;
goto ErrorExit;
}
Length = ReadSize;
@@ -417,12 +638,19 @@ AcpiEfiFlushFile (
CHAR16 *Pos,
BOOLEAN FlushAll)
{
+ ACPI_SIMPLE_TEXT_OUTPUT_INTERFACE *Out;
+
- if (FlushAll || Pos >= (End - 1))
+ if (File == stdout || File == stderr)
{
- *Pos = 0;
- uefi_call_wrapper (File->OutputString, 2, File, Begin);
- Pos = Begin;
+ Out = ACPI_CAST_PTR (ACPI_SIMPLE_TEXT_OUTPUT_INTERFACE, File);
+
+ if (FlushAll || Pos >= (End - 1))
+ {
+ *Pos = 0;
+ uefi_call_wrapper (Out->OutputString, 2, Out, Begin);
+ Pos = Begin;
+ }
}
return (Pos);
@@ -451,7 +679,7 @@ fwrite (
ACPI_SIZE Count,
FILE *File)
{
- int Length = -1;
+ int Length = -EINVAL;
CHAR16 String[ACPI_EFI_PRINT_LENGTH];
const char *Ascii;
CHAR16 *End;
@@ -462,7 +690,11 @@ fwrite (
ACPI_EFI_STATUS EfiStatus;
- if (File == stdout || File == stderr)
+ if (File == stdin)
+ {
+ /* Do not support write operations on input console */
+ }
+ else if (File == stdout || File == stderr)
{
Pos = String;
End = String + ACPI_EFI_PRINT_LENGTH - 1;
@@ -516,11 +748,68 @@ ErrorExit:
/*******************************************************************************
*
+ * FUNCTION: AcpiEfiGetFileInfo
+ *
+ * PARAMETERS: File - File descriptor
+ * InfoPtr - Pointer to contain file information
+ *
+ * RETURN: Clibrary error code
+ *
+ * DESCRIPTION: Get file information.
+ *
+ ******************************************************************************/
+
+static int
+AcpiEfiGetFileInfo (
+ FILE *File,
+ ACPI_EFI_FILE_INFO **InfoPtr)
+{
+ ACPI_EFI_STATUS EfiStatus = ACPI_EFI_BUFFER_TOO_SMALL;
+ ACPI_EFI_FILE_INFO *Buffer = NULL;
+ UINTN BufferSize = SIZE_OF_ACPI_EFI_FILE_INFO + 200;
+ ACPI_EFI_FILE_HANDLE EfiFile;
+
+
+ if (!InfoPtr)
+ {
+ errno = EINVAL;
+ return (-EINVAL);
+ }
+
+ while (EfiStatus == ACPI_EFI_BUFFER_TOO_SMALL)
+ {
+ EfiFile = (ACPI_EFI_FILE_HANDLE) File;
+ Buffer = AcpiOsAllocate (BufferSize);
+ if (!Buffer)
+ {
+ errno = ENOMEM;
+ return (-ENOMEM);
+ }
+ EfiStatus = uefi_call_wrapper (EfiFile->GetInfo, 4, EfiFile,
+ &AcpiGbl_GenericFileInfo, &BufferSize, Buffer);
+ if (ACPI_EFI_ERROR (EfiStatus))
+ {
+ AcpiOsFree (Buffer);
+ if (EfiStatus != ACPI_EFI_BUFFER_TOO_SMALL)
+ {
+ errno = EIO;
+ return (-EIO);
+ }
+ }
+ }
+
+ *InfoPtr = Buffer;
+ return (0);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: ftell
*
* PARAMETERS: File - File descriptor
*
- * RETURN: Size of current position
+ * RETURN: current position
*
* DESCRIPTION: Get current file offset.
*
@@ -531,8 +820,32 @@ ftell (
FILE *File)
{
long Offset = -1;
+ UINT64 Current;
+ ACPI_EFI_STATUS EfiStatus;
+ ACPI_EFI_FILE_HANDLE EfiFile;
+
+
+ if (File == stdin || File == stdout || File == stderr)
+ {
+ Offset = 0;
+ }
+ else
+ {
+ EfiFile = (ACPI_EFI_FILE_HANDLE) File;
+ EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2,
+ EfiFile, &Current);
+ if (ACPI_EFI_ERROR (EfiStatus))
+ {
+ goto ErrorExit;
+ }
+ else
+ {
+ Offset = (long) Current;
+ }
+ }
+ErrorExit:
return (Offset);
}
@@ -557,8 +870,59 @@ fseek (
long Offset,
int From)
{
+ ACPI_EFI_FILE_INFO *Info;
+ int Error;
+ ACPI_SIZE Size;
+ UINT64 Current;
+ ACPI_EFI_STATUS EfiStatus;
+ ACPI_EFI_FILE_HANDLE EfiFile;
- return (-1);
+
+ if (File == stdin || File == stdout || File == stderr)
+ {
+ return (0);
+ }
+ else
+ {
+ EfiFile = (ACPI_EFI_FILE_HANDLE) File;
+ Error = AcpiEfiGetFileInfo (File, &Info);
+ if (Error)
+ {
+ return (Error);
+ }
+ Size = Info->FileSize;
+ AcpiOsFree (Info);
+
+ if (From == SEEK_CUR)
+ {
+ EfiStatus = uefi_call_wrapper (EfiFile->GetPosition, 2,
+ EfiFile, &Current);
+ if (ACPI_EFI_ERROR (EfiStatus))
+ {
+ errno = ERANGE;
+ return (-ERANGE);
+ }
+ Current += Offset;
+ }
+ else if (From == SEEK_END)
+ {
+ Current = Size - Offset;
+ }
+ else
+ {
+ Current = Offset;
+ }
+
+ EfiStatus = uefi_call_wrapper (EfiFile->SetPosition, 2,
+ EfiFile, Current);
+ if (ACPI_EFI_ERROR (EfiStatus))
+ {
+ errno = ERANGE;
+ return (-ERANGE);
+ }
+ }
+
+ return (0);
}
@@ -829,8 +1193,13 @@ efi_main (
ST = SystemTab;
BS = SystemTab->BootServices;
- stdout = SystemTab->ConOut;
- stderr = SystemTab->ConOut;
+ stdin = ACPI_CAST_PTR (ACPI_EFI_FILE, SystemTab->ConIn);
+ stdout = ACPI_CAST_PTR (ACPI_EFI_FILE, SystemTab->ConOut);
+ stderr = ACPI_CAST_PTR (ACPI_EFI_FILE, SystemTab->ConOut);
+
+ /* Disable the platform watchdog timer if we go interactive */
+
+ uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL);
/* Retrieve image information */
diff --git a/source/tools/efihello/efihello.c b/source/tools/efihello/efihello.c
new file mode 100644
index 000000000..761652dfb
--- /dev/null
+++ b/source/tools/efihello/efihello.c
@@ -0,0 +1,81 @@
+#include "acpi.h"
+#include "accommon.h"
+#include "acapps.h"
+
+
+#define LINE_SIZE 256
+static char LineBuffer[LINE_SIZE];
+
+/******************************************************************************
+ *
+ * FUNCTION: main
+ *
+ * PARAMETERS: argc/argv - Standard argc/argv
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: C main function for acpidump utility
+ *
+ ******************************************************************************/
+
+#ifndef _GNU_EFI
+int ACPI_SYSTEM_XFACE
+main (
+ int argc,
+ char *argv[])
+#else
+int ACPI_SYSTEM_XFACE
+acpi_main (
+ int argc,
+ char *argv[])
+#endif
+{
+ ACPI_FILE File;
+ BOOLEAN DoCloseFile = FALSE;
+ char *Result;
+
+
+ AcpiOsInitialize ();
+
+ printf ("argc=%d\n", argc);
+
+ if (argc > 1)
+ {
+ File = fopen (argv[1], "r");
+ if (!File)
+ {
+ printf ("Failed to open %s.\n", argv[1]);
+ return (-1);
+ }
+ DoCloseFile = TRUE;
+ }
+ else
+ {
+ File = stdin;
+ }
+
+ while (1)
+ {
+ Result = fgets (LineBuffer, LINE_SIZE, File);
+ if (!Result)
+ {
+ printf ("Failed to read %s.\n", argv[1]);
+ fclose (File);
+ return (-2);
+ }
+
+ printf ("%s", LineBuffer);
+
+ if (strncmp (Result, "exit", 4) == 0)
+ {
+ break;
+ }
+ }
+
+
+ if (DoCloseFile)
+ {
+ fclose (File);
+ }
+ return (0);
+}