v4.19.13 snapshot.
diff --git a/tools/power/acpi/.gitignore b/tools/power/acpi/.gitignore
new file mode 100644
index 0000000..cba3d99
--- /dev/null
+++ b/tools/power/acpi/.gitignore
@@ -0,0 +1,4 @@
+acpidbg
+acpidump
+ec
+include
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
new file mode 100644
index 0000000..a8bf908
--- /dev/null
+++ b/tools/power/acpi/Makefile
@@ -0,0 +1,27 @@
+# tools/power/acpi/Makefile - ACPI tool Makefile
+#
+# Copyright (c) 2013, Intel Corporation
+#   Author: Lv Zheng <lv.zheng@intel.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License.
+
+include ../../scripts/Makefile.include
+
+all: acpidbg acpidump ec
+clean: acpidbg_clean acpidump_clean ec_clean
+install: acpidbg_install acpidump_install ec_install
+uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall
+
+acpidbg acpidump ec: FORCE
+	$(call descend,tools/$@,all)
+acpidbg_clean acpidump_clean ec_clean:
+	$(call descend,tools/$(@:_clean=),clean)
+acpidbg_install acpidump_install ec_install:
+	$(call descend,tools/$(@:_install=),install)
+acpidbg_uninstall acpidump_uninstall ec_uninstall:
+	$(call descend,tools/$(@:_uninstall=),uninstall)
+
+.PHONY: FORCE
diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config
new file mode 100644
index 0000000..f304be7
--- /dev/null
+++ b/tools/power/acpi/Makefile.config
@@ -0,0 +1,92 @@
+# tools/power/acpi/Makefile.config - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <lv.zheng@intel.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License.
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+#$(info Determined 'srctree' to be $(srctree))
+endif
+
+include $(srctree)/../../scripts/Makefile.include
+
+OUTPUT=$(srctree)/
+ifeq ("$(origin O)", "command line")
+	OUTPUT := $(O)/power/acpi/
+endif
+#$(info Determined 'OUTPUT' to be $(OUTPUT))
+
+# --- CONFIGURATION BEGIN ---
+
+# Set the following to `true' to make a unstripped, unoptimized
+# binary. Leave this set to `false' for production use.
+DEBUG ?=	true
+
+# make the build silent. Set this to something else to make it noisy again.
+V ?=		false
+
+# Prefix to the directories we're installing to
+DESTDIR ?=
+
+# --- CONFIGURATION END ---
+
+# Directory definitions. These are default and most probably
+# do not need to be changed. Please note that DESTDIR is
+# added in front of any of them
+
+bindir ?=	/usr/bin
+sbindir ?=	/usr/sbin
+mandir ?=	/usr/man
+
+# Toolchain: what tools do we use, and what options do they need:
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+# If you are running a cross compiler, you may want to set this
+# to something more interesting, like "arm-linux-".  If you want
+# to compile vs uClibc, that can be done here as well.
+CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
+CROSS_COMPILE ?= $(CROSS)
+LD = $(CC)
+HOSTCC = gcc
+
+# check if compiler option is supported
+cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+
+# use '-Os' optimization if available, else use -O2
+OPTIMIZATION := $(call cc-supports,-Os,-O2)
+
+WARNINGS := -Wall
+WARNINGS += $(call cc-supports,-Wstrict-prototypes)
+WARNINGS += $(call cc-supports,-Wdeclaration-after-statement)
+
+KERNEL_INCLUDE := $(OUTPUT)include
+ACPICA_INCLUDE := $(srctree)/../../../drivers/acpi/acpica
+CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE)
+CFLAGS += $(WARNINGS)
+
+ifeq ($(strip $(V)),false)
+	QUIET=@
+	ECHO=@echo
+else
+	QUIET=
+	ECHO=@\#
+endif
+
+# if DEBUG is enabled, then we do not strip or optimize
+ifeq ($(strip $(DEBUG)),true)
+	CFLAGS += -O1 -g -DDEBUG
+	STRIPCMD = /bin/true -Since_we_are_debugging
+else
+	CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer
+	STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
+endif
diff --git a/tools/power/acpi/Makefile.rules b/tools/power/acpi/Makefile.rules
new file mode 100644
index 0000000..3737383
--- /dev/null
+++ b/tools/power/acpi/Makefile.rules
@@ -0,0 +1,51 @@
+# tools/power/acpi/Makefile.rules - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <lv.zheng@intel.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License.
+
+objdir := $(OUTPUT)tools/$(TOOL)/
+toolobjs := $(addprefix $(objdir),$(TOOL_OBJS))
+$(OUTPUT)$(TOOL): $(toolobjs) FORCE
+	$(ECHO) "  LD      " $(subst $(OUTPUT),,$@)
+	$(QUIET) $(LD) $(CFLAGS) $(LDFLAGS) $(toolobjs) -L$(OUTPUT) -o $@
+	$(ECHO) "  STRIP   " $(subst $(OUTPUT),,$@)
+	$(QUIET) $(STRIPCMD) $@
+
+$(KERNEL_INCLUDE):
+	$(ECHO) "  MKDIR   " $(subst $(OUTPUT),,$@)
+	$(QUIET) mkdir -p $(KERNEL_INCLUDE)
+	$(ECHO) "  CP      " $(subst $(OUTPUT),,$@)
+	$(QUIET) cp -rf $(srctree)/../../../include/acpi $(KERNEL_INCLUDE)/
+
+$(objdir)%.o: %.c $(KERNEL_INCLUDE)
+	$(ECHO) "  CC      " $(subst $(OUTPUT),,$@)
+	$(QUIET) $(CC) -c $(CFLAGS) -o $@ $<
+
+all: $(OUTPUT)$(TOOL)
+clean:
+	$(ECHO) "  RMOBJ   " $(subst $(OUTPUT),,$(objdir))
+	$(QUIET) find $(objdir) \( -not -type d \)\
+		 -and \( -name '*~' -o -name '*.[oas]' \)\
+		 -type f -print | xargs rm -f
+	$(ECHO) "  RM      " $(TOOL)
+	$(QUIET) rm -f $(OUTPUT)$(TOOL)
+	$(ECHO) "  RMINC   " $(subst $(OUTPUT),,$(KERNEL_INCLUDE))
+	$(QUIET) rm -rf $(KERNEL_INCLUDE)
+
+install-tools:
+	$(ECHO) "  INST    " $(TOOL)
+	$(QUIET) $(INSTALL) -d $(DESTDIR)$(sbindir)
+	$(QUIET) $(INSTALL_PROGRAM) $(OUTPUT)$(TOOL) $(DESTDIR)$(sbindir)
+uninstall-tools:
+	$(ECHO) "  UNINST  " $(TOOL)
+	$(QUIET) rm -f $(DESTDIR)$(sbindir)/$(TOOL)
+
+install: all install-tools $(EXTRA_INSTALL)
+uninstall: uninstall-tools $(EXTRA_UNINSTALL)
+
+.PHONY: FORCE
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
new file mode 100644
index 0000000..ff8025d
--- /dev/null
+++ b/tools/power/acpi/common/cmfsize.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: cfsize - Common get file size function
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acapps.h"
+
+#define _COMPONENT          ACPI_TOOLS
+ACPI_MODULE_NAME("cmfsize")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    cm_get_file_size
+ *
+ * PARAMETERS:  file                    - Open file descriptor
+ *
+ * RETURN:      File Size. On error, -1 (ACPI_UINT32_MAX)
+ *
+ * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
+ *              Does not disturb the current file pointer.
+ *
+ ******************************************************************************/
+u32 cm_get_file_size(ACPI_FILE file)
+{
+	long file_size;
+	long current_offset;
+	acpi_status status;
+
+	/* Save the current file pointer, seek to EOF to obtain file size */
+
+	current_offset = ftell(file);
+	if (current_offset < 0) {
+		goto offset_error;
+	}
+
+	status = fseek(file, 0, SEEK_END);
+	if (ACPI_FAILURE(status)) {
+		goto seek_error;
+	}
+
+	file_size = ftell(file);
+	if (file_size < 0) {
+		goto offset_error;
+	}
+
+	/* Restore original file pointer */
+
+	status = fseek(file, current_offset, SEEK_SET);
+	if (ACPI_FAILURE(status)) {
+		goto seek_error;
+	}
+
+	return ((u32)file_size);
+
+offset_error:
+	fprintf(stderr, "Could not get file offset\n");
+	return (ACPI_UINT32_MAX);
+
+seek_error:
+	fprintf(stderr, "Could not set file offset\n");
+	return (ACPI_UINT32_MAX);
+}
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
new file mode 100644
index 0000000..7be89b8
--- /dev/null
+++ b/tools/power/acpi/common/getopt.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: getopt
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+/*
+ * ACPICA getopt() implementation
+ *
+ * Option strings:
+ *    "f"       - Option has no arguments
+ *    "f:"      - Option requires an argument
+ *    "f+"      - Option has an optional argument
+ *    "f^"      - Option has optional single-char sub-options
+ *    "f|"      - Option has required single-char sub-options
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acapps.h"
+
+#define ACPI_OPTION_ERROR(msg, badchar) \
+	if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
+
+int acpi_gbl_opterr = 1;
+int acpi_gbl_optind = 1;
+int acpi_gbl_sub_opt_char = 0;
+char *acpi_gbl_optarg;
+
+static int current_char_ptr = 1;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_getopt_argument
+ *
+ * PARAMETERS:  argc, argv          - from main
+ *
+ * RETURN:      0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
+ *              to point to the next argument.
+ *
+ * DESCRIPTION: Get the next argument. Used to obtain arguments for the
+ *              two-character options after the original call to acpi_getopt.
+ *              Note: Either the argument starts at the next character after
+ *              the option, or it is pointed to by the next argv entry.
+ *              (After call to acpi_getopt, we need to backup to the previous
+ *              argv entry).
+ *
+ ******************************************************************************/
+
+int acpi_getopt_argument(int argc, char **argv)
+{
+
+	acpi_gbl_optind--;
+	current_char_ptr++;
+
+	if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
+		acpi_gbl_optarg =
+		    &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
+	} else if (++acpi_gbl_optind >= argc) {
+		ACPI_OPTION_ERROR("\nOption requires an argument", 0);
+
+		current_char_ptr = 1;
+		return (-1);
+	} else {
+		acpi_gbl_optarg = argv[acpi_gbl_optind++];
+	}
+
+	current_char_ptr = 1;
+	return (0);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_getopt
+ *
+ * PARAMETERS:  argc, argv          - from main
+ *              opts                - options info list
+ *
+ * RETURN:      Option character or ACPI_OPT_END
+ *
+ * DESCRIPTION: Get the next option
+ *
+ ******************************************************************************/
+
+int acpi_getopt(int argc, char **argv, char *opts)
+{
+	int current_char;
+	char *opts_ptr;
+
+	if (current_char_ptr == 1) {
+		if (acpi_gbl_optind >= argc ||
+		    argv[acpi_gbl_optind][0] != '-' ||
+		    argv[acpi_gbl_optind][1] == '\0') {
+			return (ACPI_OPT_END);
+		} else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
+			acpi_gbl_optind++;
+			return (ACPI_OPT_END);
+		}
+	}
+
+	/* Get the option */
+
+	current_char = argv[acpi_gbl_optind][current_char_ptr];
+
+	/* Make sure that the option is legal */
+
+	if (current_char == ':' ||
+	    (opts_ptr = strchr(opts, current_char)) == NULL) {
+		ACPI_OPTION_ERROR("Illegal option: -", current_char);
+
+		if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
+			acpi_gbl_optind++;
+			current_char_ptr = 1;
+		}
+
+		return ('?');
+	}
+
+	/* Option requires an argument? */
+
+	if (*++opts_ptr == ':') {
+		if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
+			acpi_gbl_optarg =
+			    &argv[acpi_gbl_optind++][(int)
+						     (current_char_ptr + 1)];
+		} else if (++acpi_gbl_optind >= argc) {
+			ACPI_OPTION_ERROR("Option requires an argument: -",
+					  current_char);
+
+			current_char_ptr = 1;
+			return ('?');
+		} else {
+			acpi_gbl_optarg = argv[acpi_gbl_optind++];
+		}
+
+		current_char_ptr = 1;
+	}
+
+	/* Option has an optional argument? */
+
+	else if (*opts_ptr == '+') {
+		if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
+			acpi_gbl_optarg =
+			    &argv[acpi_gbl_optind++][(int)
+						     (current_char_ptr + 1)];
+		} else if (++acpi_gbl_optind >= argc) {
+			acpi_gbl_optarg = NULL;
+		} else {
+			acpi_gbl_optarg = argv[acpi_gbl_optind++];
+		}
+
+		current_char_ptr = 1;
+	}
+
+	/* Option has optional single-char arguments? */
+
+	else if (*opts_ptr == '^') {
+		if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
+			acpi_gbl_optarg =
+			    &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
+		} else {
+			acpi_gbl_optarg = "^";
+		}
+
+		acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
+		acpi_gbl_optind++;
+		current_char_ptr = 1;
+	}
+
+	/* Option has a required single-char argument? */
+
+	else if (*opts_ptr == '|') {
+		if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
+			acpi_gbl_optarg =
+			    &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
+		} else {
+			ACPI_OPTION_ERROR
+			    ("Option requires a single-character suboption: -",
+			     current_char);
+
+			current_char_ptr = 1;
+			return ('?');
+		}
+
+		acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
+		acpi_gbl_optind++;
+		current_char_ptr = 1;
+	}
+
+	/* Option with no arguments */
+
+	else {
+		if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
+			current_char_ptr = 1;
+			acpi_gbl_optind++;
+		}
+
+		acpi_gbl_optarg = NULL;
+	}
+
+	return (current_char);
+}
diff --git a/tools/power/acpi/man/acpidump.8 b/tools/power/acpi/man/acpidump.8
new file mode 100644
index 0000000..79e2d1d
--- /dev/null
+++ b/tools/power/acpi/man/acpidump.8
@@ -0,0 +1,127 @@
+.TH ACPIDUMP 8
+.SH NAME
+acpidump \- dump a system's ACPI tables to an ASCII file
+
+.SH SYNOPSIS
+.B acpidump
+.RI [ options ]
+.br
+
+.SH DESCRIPTION
+.B acpidump
+dumps the systems ACPI tables to an ASCII file appropriate for
+attaching to a bug report.
+
+Subsequently, they can be processed by utilities in the ACPICA package.
+
+.SH OPTIONS
+acpidump options are as follow:
+.TP
+.B Options
+.TP
+.B \-b
+Dump tables to binary files
+.TP
+.B \-h \-?
+This help message
+.TP
+.B \-o <File>
+Redirect output to file
+.TP
+.B \-r <Address>
+Dump tables from specified RSDP
+.TP
+.B \-s
+Print table summaries only
+.TP
+.B \-v
+Display version information
+.TP
+.B \-z
+Verbose mode
+.TP
+.B Table Options
+.TP
+.B \-a <Address>
+Get table via a physical address
+.TP
+.B \-c <on|off>
+Turning on/off customized table dumping
+.TP
+.B \-f <BinaryFile>
+Get table via a binary file
+.TP
+.B \-n <Signature>
+Get table via a name/signature
+.TP
+.B \-x
+Do not use but dump XSDT
+.TP
+.B \-x \-x
+Do not use or dump XSDT
+.TP
+.fi
+Invocation without parameters dumps all available tables.
+.TP
+Multiple mixed instances of -a, -f, and -n are supported.
+
+.SH EXAMPLES
+
+.nf
+# acpidump > acpidump.out
+
+$ acpixtract -a acpidump.out
+        Acpi table [DSDT] -  15974 bytes written to DSDT.dat
+        Acpi table [FACS] -     64 bytes written to FACS.dat
+        Acpi table [FACP] -    116 bytes written to FACP.dat
+        Acpi table [APIC] -    120 bytes written to APIC.dat
+        Acpi table [MCFG] -     60 bytes written to MCFG.dat
+        Acpi table [SSDT] -    444 bytes written to SSDT1.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT2.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT3.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT4.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT5.dat
+        Acpi table [RSDT] -     76 bytes written to RSDT.dat
+        Acpi table [RSDP] -     20 bytes written to RSDP.dat
+
+$ iasl -d *.dat
+...
+.fi
+creates *.dsl, a human readable form which can be edited
+and compiled using iasl.
+
+
+.SH NOTES
+
+.B "acpidump "
+must be run as root.
+
+.SH REFERENCES
+ACPICA: https://acpica.org/
+
+.SH FILES
+.ta
+.nf
+/dev/mem
+/sys/firmware/acpi/tables/*
+/sys/firmware/acpi/tables/dynamic/*
+/sys/firmware/efi/systab
+.fi
+
+.SH AUTHOR
+.TP
+Original by:
+ Len Brown <len.brown@intel.com>
+.TP
+Written by:
+ Chao Guan <chao.guan@intel.com>
+.TP
+Updated by:
+ Bob Moore <robert.moore@intel.com>
+ Lv Zheng <lv.zheng@intel.com>
+
+.SH SEE ALSO
+\&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8).
+
+.SH COPYRIGHT
+COPYRIGHT (c) 2013, Intel Corporation.
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
new file mode 100644
index 0000000..a20c703
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
@@ -0,0 +1,1372 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+#include "acpidump.h"
+
+#define _COMPONENT          ACPI_OS_SERVICES
+ACPI_MODULE_NAME("oslinuxtbl")
+
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+/* List of information about obtained ACPI tables */
+typedef struct osl_table_info {
+	struct osl_table_info *next;
+	u32 instance;
+	char signature[ACPI_NAME_SIZE];
+
+} osl_table_info;
+
+/* Local prototypes */
+
+static acpi_status osl_table_initialize(void);
+
+static acpi_status
+osl_table_name_from_file(char *filename, char *signature, u32 *instance);
+
+static acpi_status osl_add_table_to_list(char *signature, u32 instance);
+
+static acpi_status
+osl_read_table_from_file(char *filename,
+			 acpi_size file_offset,
+			 char *signature, struct acpi_table_header **table);
+
+static acpi_status
+osl_map_table(acpi_size address,
+	      char *signature, struct acpi_table_header **table);
+
+static void osl_unmap_table(struct acpi_table_header *table);
+
+static acpi_physical_address
+osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword);
+
+static acpi_physical_address osl_find_rsdp_via_efi(void);
+
+static acpi_status osl_load_rsdp(void);
+
+static acpi_status osl_list_customized_tables(char *directory);
+
+static acpi_status
+osl_get_customized_table(char *pathname,
+			 char *signature,
+			 u32 instance,
+			 struct acpi_table_header **table,
+			 acpi_physical_address *address);
+
+static acpi_status osl_list_bios_tables(void);
+
+static acpi_status
+osl_get_bios_table(char *signature,
+		   u32 instance,
+		   struct acpi_table_header **table,
+		   acpi_physical_address *address);
+
+static acpi_status osl_get_last_status(acpi_status default_status);
+
+/* File locations */
+
+#define DYNAMIC_TABLE_DIR   "/sys/firmware/acpi/tables/dynamic"
+#define STATIC_TABLE_DIR    "/sys/firmware/acpi/tables"
+#define EFI_SYSTAB          "/sys/firmware/efi/systab"
+
+/* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
+
+u8 gbl_dump_dynamic_tables = TRUE;
+
+/* Initialization flags */
+
+u8 gbl_table_list_initialized = FALSE;
+
+/* Local copies of main ACPI tables */
+
+struct acpi_table_rsdp gbl_rsdp;
+struct acpi_table_fadt *gbl_fadt = NULL;
+struct acpi_table_rsdt *gbl_rsdt = NULL;
+struct acpi_table_xsdt *gbl_xsdt = NULL;
+
+/* Table addresses */
+
+acpi_physical_address gbl_fadt_address = 0;
+acpi_physical_address gbl_rsdp_address = 0;
+
+/* Revision of RSD PTR */
+
+u8 gbl_revision = 0;
+
+struct osl_table_info *gbl_table_list_head = NULL;
+u32 gbl_table_count = 0;
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_get_last_status
+ *
+ * PARAMETERS:  default_status  - Default error status to return
+ *
+ * RETURN:      Status; Converted from errno.
+ *
+ * DESCRIPTION: Get last errno and conver it to acpi_status.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_get_last_status(acpi_status default_status)
+{
+
+	switch (errno) {
+	case EACCES:
+	case EPERM:
+
+		return (AE_ACCESS);
+
+	case ENOENT:
+
+		return (AE_NOT_FOUND);
+
+	case ENOMEM:
+
+		return (AE_NO_MEMORY);
+
+	default:
+
+		return (default_status);
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_table_by_address
+ *
+ * PARAMETERS:  address         - Physical address of the ACPI table
+ *              table           - Where a pointer to the table is returned
+ *
+ * RETURN:      Status; Table buffer is returned if AE_OK.
+ *              AE_NOT_FOUND: A valid table was not found at the address
+ *
+ * DESCRIPTION: Get an ACPI table via a physical memory address.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_get_table_by_address(acpi_physical_address address,
+			     struct acpi_table_header **table)
+{
+	u32 table_length;
+	struct acpi_table_header *mapped_table;
+	struct acpi_table_header *local_table = NULL;
+	acpi_status status = AE_OK;
+
+	/* Get main ACPI tables from memory on first invocation of this function */
+
+	status = osl_table_initialize();
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Map the table and validate it */
+
+	status = osl_map_table(address, NULL, &mapped_table);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Copy table to local buffer and return it */
+
+	table_length = ap_get_table_length(mapped_table);
+	if (table_length == 0) {
+		status = AE_BAD_HEADER;
+		goto exit;
+	}
+
+	local_table = calloc(1, table_length);
+	if (!local_table) {
+		status = AE_NO_MEMORY;
+		goto exit;
+	}
+
+	memcpy(local_table, mapped_table, table_length);
+
+exit:
+	osl_unmap_table(mapped_table);
+	*table = local_table;
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_table_by_name
+ *
+ * PARAMETERS:  signature       - ACPI Signature for desired table. Must be
+ *                                a null terminated 4-character string.
+ *              instance        - Multiple table support for SSDT/UEFI (0...n)
+ *                                Must be 0 for other tables.
+ *              table           - Where a pointer to the table is returned
+ *              address         - Where the table physical address is returned
+ *
+ * RETURN:      Status; Table buffer and physical address returned if AE_OK.
+ *              AE_LIMIT: Instance is beyond valid limit
+ *              AE_NOT_FOUND: A table with the signature was not found
+ *
+ * NOTE:        Assumes the input signature is uppercase.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_get_table_by_name(char *signature,
+			  u32 instance,
+			  struct acpi_table_header **table,
+			  acpi_physical_address *address)
+{
+	acpi_status status;
+
+	/* Get main ACPI tables from memory on first invocation of this function */
+
+	status = osl_table_initialize();
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
+
+	if (!gbl_dump_customized_tables) {
+
+		/* Attempt to get the table from the memory */
+
+		status =
+		    osl_get_bios_table(signature, instance, table, address);
+	} else {
+		/* Attempt to get the table from the static directory */
+
+		status = osl_get_customized_table(STATIC_TABLE_DIR, signature,
+						  instance, table, address);
+	}
+
+	if (ACPI_FAILURE(status) && status == AE_LIMIT) {
+		if (gbl_dump_dynamic_tables) {
+
+			/* Attempt to get a dynamic table */
+
+			status =
+			    osl_get_customized_table(DYNAMIC_TABLE_DIR,
+						     signature, instance, table,
+						     address);
+		}
+	}
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_add_table_to_list
+ *
+ * PARAMETERS:  signature       - Table signature
+ *              instance        - Table instance
+ *
+ * RETURN:      Status; Successfully added if AE_OK.
+ *              AE_NO_MEMORY: Memory allocation error
+ *
+ * DESCRIPTION: Insert a table structure into OSL table list.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_add_table_to_list(char *signature, u32 instance)
+{
+	struct osl_table_info *new_info;
+	struct osl_table_info *next;
+	u32 next_instance = 0;
+	u8 found = FALSE;
+
+	new_info = calloc(1, sizeof(struct osl_table_info));
+	if (!new_info) {
+		return (AE_NO_MEMORY);
+	}
+
+	ACPI_MOVE_NAME(new_info->signature, signature);
+
+	if (!gbl_table_list_head) {
+		gbl_table_list_head = new_info;
+	} else {
+		next = gbl_table_list_head;
+		while (1) {
+			if (ACPI_COMPARE_NAME(next->signature, signature)) {
+				if (next->instance == instance) {
+					found = TRUE;
+				}
+				if (next->instance >= next_instance) {
+					next_instance = next->instance + 1;
+				}
+			}
+
+			if (!next->next) {
+				break;
+			}
+			next = next->next;
+		}
+		next->next = new_info;
+	}
+
+	if (found) {
+		if (instance) {
+			fprintf(stderr,
+				"%4.4s: Warning unmatched table instance %d, expected %d\n",
+				signature, instance, next_instance);
+		}
+		instance = next_instance;
+	}
+
+	new_info->instance = instance;
+	gbl_table_count++;
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_table_by_index
+ *
+ * PARAMETERS:  index           - Which table to get
+ *              table           - Where a pointer to the table is returned
+ *              instance        - Where a pointer to the table instance no. is
+ *                                returned
+ *              address         - Where the table physical address is returned
+ *
+ * RETURN:      Status; Table buffer and physical address returned if AE_OK.
+ *              AE_LIMIT: Index is beyond valid limit
+ *
+ * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
+ *              AE_LIMIT when an invalid index is reached. Index is not
+ *              necessarily an index into the RSDT/XSDT.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_get_table_by_index(u32 index,
+			   struct acpi_table_header **table,
+			   u32 *instance, acpi_physical_address *address)
+{
+	struct osl_table_info *info;
+	acpi_status status;
+	u32 i;
+
+	/* Get main ACPI tables from memory on first invocation of this function */
+
+	status = osl_table_initialize();
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Validate Index */
+
+	if (index >= gbl_table_count) {
+		return (AE_LIMIT);
+	}
+
+	/* Point to the table list entry specified by the Index argument */
+
+	info = gbl_table_list_head;
+	for (i = 0; i < index; i++) {
+		info = info->next;
+	}
+
+	/* Now we can just get the table via the signature */
+
+	status = acpi_os_get_table_by_name(info->signature, info->instance,
+					   table, address);
+
+	if (ACPI_SUCCESS(status)) {
+		*instance = info->instance;
+	}
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_find_rsdp_via_efi_by_keyword
+ *
+ * PARAMETERS:  keyword         - Character string indicating ACPI GUID version
+ *                                in the EFI table
+ *
+ * RETURN:      RSDP address if found
+ *
+ * DESCRIPTION: Find RSDP address via EFI using keyword indicating the ACPI
+ *              GUID version.
+ *
+ *****************************************************************************/
+
+static acpi_physical_address
+osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword)
+{
+	char buffer[80];
+	unsigned long long address = 0;
+	char format[32];
+
+	snprintf(format, 32, "%s=%s", keyword, "%llx");
+	fseek(file, 0, SEEK_SET);
+	while (fgets(buffer, 80, file)) {
+		if (sscanf(buffer, format, &address) == 1) {
+			break;
+		}
+	}
+
+	return ((acpi_physical_address)(address));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_find_rsdp_via_efi
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      RSDP address if found
+ *
+ * DESCRIPTION: Find RSDP address via EFI.
+ *
+ *****************************************************************************/
+
+static acpi_physical_address osl_find_rsdp_via_efi(void)
+{
+	FILE *file;
+	acpi_physical_address address = 0;
+
+	file = fopen(EFI_SYSTAB, "r");
+	if (file) {
+		address = osl_find_rsdp_via_efi_by_keyword(file, "ACPI20");
+		if (!address) {
+			address =
+			    osl_find_rsdp_via_efi_by_keyword(file, "ACPI");
+		}
+		fclose(file);
+	}
+
+	return (address);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_load_rsdp
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Scan and load RSDP.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_load_rsdp(void)
+{
+	struct acpi_table_header *mapped_table;
+	u8 *rsdp_address;
+	acpi_physical_address rsdp_base;
+	acpi_size rsdp_size;
+
+	/* Get RSDP from memory */
+
+	rsdp_size = sizeof(struct acpi_table_rsdp);
+	if (gbl_rsdp_base) {
+		rsdp_base = gbl_rsdp_base;
+	} else {
+		rsdp_base = osl_find_rsdp_via_efi();
+	}
+
+	if (!rsdp_base) {
+		rsdp_base = ACPI_HI_RSDP_WINDOW_BASE;
+		rsdp_size = ACPI_HI_RSDP_WINDOW_SIZE;
+	}
+
+	rsdp_address = acpi_os_map_memory(rsdp_base, rsdp_size);
+	if (!rsdp_address) {
+		return (osl_get_last_status(AE_BAD_ADDRESS));
+	}
+
+	/* Search low memory for the RSDP */
+
+	mapped_table = ACPI_CAST_PTR(struct acpi_table_header,
+				     acpi_tb_scan_memory_for_rsdp(rsdp_address,
+								  rsdp_size));
+	if (!mapped_table) {
+		acpi_os_unmap_memory(rsdp_address, rsdp_size);
+		return (AE_NOT_FOUND);
+	}
+
+	gbl_rsdp_address =
+	    rsdp_base + (ACPI_CAST8(mapped_table) - rsdp_address);
+
+	memcpy(&gbl_rsdp, mapped_table, sizeof(struct acpi_table_rsdp));
+	acpi_os_unmap_memory(rsdp_address, rsdp_size);
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_can_use_xsdt
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      TRUE if XSDT is allowed to be used.
+ *
+ * DESCRIPTION: This function collects logic that can be used to determine if
+ *              XSDT should be used instead of RSDT.
+ *
+ *****************************************************************************/
+
+static u8 osl_can_use_xsdt(void)
+{
+	if (gbl_revision && !acpi_gbl_do_not_use_xsdt) {
+		return (TRUE);
+	} else {
+		return (FALSE);
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_table_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
+ *              local variables. Main ACPI tables include RSDT, FADT, RSDT,
+ *              and/or XSDT.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_table_initialize(void)
+{
+	acpi_status status;
+	acpi_physical_address address;
+
+	if (gbl_table_list_initialized) {
+		return (AE_OK);
+	}
+
+	if (!gbl_dump_customized_tables) {
+
+		/* Get RSDP from memory */
+
+		status = osl_load_rsdp();
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		/* Get XSDT from memory */
+
+		if (gbl_rsdp.revision && !gbl_do_not_dump_xsdt) {
+			if (gbl_xsdt) {
+				free(gbl_xsdt);
+				gbl_xsdt = NULL;
+			}
+
+			gbl_revision = 2;
+			status = osl_get_bios_table(ACPI_SIG_XSDT, 0,
+						    ACPI_CAST_PTR(struct
+								  acpi_table_header
+								  *, &gbl_xsdt),
+						    &address);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		}
+
+		/* Get RSDT from memory */
+
+		if (gbl_rsdp.rsdt_physical_address) {
+			if (gbl_rsdt) {
+				free(gbl_rsdt);
+				gbl_rsdt = NULL;
+			}
+
+			status = osl_get_bios_table(ACPI_SIG_RSDT, 0,
+						    ACPI_CAST_PTR(struct
+								  acpi_table_header
+								  *, &gbl_rsdt),
+						    &address);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		}
+
+		/* Get FADT from memory */
+
+		if (gbl_fadt) {
+			free(gbl_fadt);
+			gbl_fadt = NULL;
+		}
+
+		status = osl_get_bios_table(ACPI_SIG_FADT, 0,
+					    ACPI_CAST_PTR(struct
+							  acpi_table_header *,
+							  &gbl_fadt),
+					    &gbl_fadt_address);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		/* Add mandatory tables to global table list first */
+
+		status = osl_add_table_to_list(ACPI_RSDP_NAME, 0);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		status = osl_add_table_to_list(ACPI_SIG_RSDT, 0);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		if (gbl_revision == 2) {
+			status = osl_add_table_to_list(ACPI_SIG_XSDT, 0);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+		}
+
+		status = osl_add_table_to_list(ACPI_SIG_DSDT, 0);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		status = osl_add_table_to_list(ACPI_SIG_FACS, 0);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		/* Add all tables found in the memory */
+
+		status = osl_list_bios_tables();
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	} else {
+		/* Add all tables found in the static directory */
+
+		status = osl_list_customized_tables(STATIC_TABLE_DIR);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
+	if (gbl_dump_dynamic_tables) {
+
+		/* Add all dynamically loaded tables in the dynamic directory */
+
+		status = osl_list_customized_tables(DYNAMIC_TABLE_DIR);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
+	gbl_table_list_initialized = TRUE;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_list_bios_tables
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status; Table list is initialized if AE_OK.
+ *
+ * DESCRIPTION: Add ACPI tables to the table list from memory.
+ *
+ * NOTE:        This works on Linux as table customization does not modify the
+ *              addresses stored in RSDP/RSDT/XSDT/FADT.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_list_bios_tables(void)
+{
+	struct acpi_table_header *mapped_table = NULL;
+	u8 *table_data;
+	u8 number_of_tables;
+	u8 item_size;
+	acpi_physical_address table_address = 0;
+	acpi_status status = AE_OK;
+	u32 i;
+
+	if (osl_can_use_xsdt()) {
+		item_size = sizeof(u64);
+		table_data =
+		    ACPI_CAST8(gbl_xsdt) + sizeof(struct acpi_table_header);
+		number_of_tables =
+		    (u8)((gbl_xsdt->header.length -
+			  sizeof(struct acpi_table_header))
+			 / item_size);
+	} else {		/* Use RSDT if XSDT is not available */
+
+		item_size = sizeof(u32);
+		table_data =
+		    ACPI_CAST8(gbl_rsdt) + sizeof(struct acpi_table_header);
+		number_of_tables =
+		    (u8)((gbl_rsdt->header.length -
+			  sizeof(struct acpi_table_header))
+			 / item_size);
+	}
+
+	/* Search RSDT/XSDT for the requested table */
+
+	for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
+		if (osl_can_use_xsdt()) {
+			table_address =
+			    (acpi_physical_address)(*ACPI_CAST64(table_data));
+		} else {
+			table_address =
+			    (acpi_physical_address)(*ACPI_CAST32(table_data));
+		}
+
+		/* Skip NULL entries in RSDT/XSDT */
+
+		if (table_address == 0) {
+			continue;
+		}
+
+		status = osl_map_table(table_address, NULL, &mapped_table);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		osl_add_table_to_list(mapped_table->signature, 0);
+		osl_unmap_table(mapped_table);
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_get_bios_table
+ *
+ * PARAMETERS:  signature       - ACPI Signature for common table. Must be
+ *                                a null terminated 4-character string.
+ *              instance        - Multiple table support for SSDT/UEFI (0...n)
+ *                                Must be 0 for other tables.
+ *              table           - Where a pointer to the table is returned
+ *              address         - Where the table physical address is returned
+ *
+ * RETURN:      Status; Table buffer and physical address returned if AE_OK.
+ *              AE_LIMIT: Instance is beyond valid limit
+ *              AE_NOT_FOUND: A table with the signature was not found
+ *
+ * DESCRIPTION: Get a BIOS provided ACPI table
+ *
+ * NOTE:        Assumes the input signature is uppercase.
+ *
+ *****************************************************************************/
+
+static acpi_status
+osl_get_bios_table(char *signature,
+		   u32 instance,
+		   struct acpi_table_header **table,
+		   acpi_physical_address *address)
+{
+	struct acpi_table_header *local_table = NULL;
+	struct acpi_table_header *mapped_table = NULL;
+	u8 *table_data;
+	u8 number_of_tables;
+	u8 item_size;
+	u32 current_instance = 0;
+	acpi_physical_address table_address;
+	acpi_physical_address first_table_address = 0;
+	u32 table_length = 0;
+	acpi_status status = AE_OK;
+	u32 i;
+
+	/* Handle special tables whose addresses are not in RSDT/XSDT */
+
+	if (ACPI_COMPARE_NAME(signature, ACPI_RSDP_NAME) ||
+	    ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT) ||
+	    ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) ||
+	    ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) ||
+	    ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
+
+find_next_instance:
+
+		table_address = 0;
+
+		/*
+		 * Get the appropriate address, either 32-bit or 64-bit. Be very
+		 * careful about the FADT length and validate table addresses.
+		 * Note: The 64-bit addresses have priority.
+		 */
+		if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) {
+			if (current_instance < 2) {
+				if ((gbl_fadt->header.length >=
+				     MIN_FADT_FOR_XDSDT) && gbl_fadt->Xdsdt
+				    && current_instance == 0) {
+					table_address =
+					    (acpi_physical_address)gbl_fadt->
+					    Xdsdt;
+				} else
+				    if ((gbl_fadt->header.length >=
+					 MIN_FADT_FOR_DSDT)
+					&& gbl_fadt->dsdt !=
+					first_table_address) {
+					table_address =
+					    (acpi_physical_address)gbl_fadt->
+					    dsdt;
+				}
+			}
+		} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
+			if (current_instance < 2) {
+				if ((gbl_fadt->header.length >=
+				     MIN_FADT_FOR_XFACS) && gbl_fadt->Xfacs
+				    && current_instance == 0) {
+					table_address =
+					    (acpi_physical_address)gbl_fadt->
+					    Xfacs;
+				} else
+				    if ((gbl_fadt->header.length >=
+					 MIN_FADT_FOR_FACS)
+					&& gbl_fadt->facs !=
+					first_table_address) {
+					table_address =
+					    (acpi_physical_address)gbl_fadt->
+					    facs;
+				}
+			}
+		} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) {
+			if (!gbl_revision) {
+				return (AE_BAD_SIGNATURE);
+			}
+			if (current_instance == 0) {
+				table_address =
+				    (acpi_physical_address)gbl_rsdp.
+				    xsdt_physical_address;
+			}
+		} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) {
+			if (current_instance == 0) {
+				table_address =
+				    (acpi_physical_address)gbl_rsdp.
+				    rsdt_physical_address;
+			}
+		} else {
+			if (current_instance == 0) {
+				table_address =
+				    (acpi_physical_address)gbl_rsdp_address;
+				signature = ACPI_SIG_RSDP;
+			}
+		}
+
+		if (table_address == 0) {
+			goto exit_find_table;
+		}
+
+		/* Now we can get the requested special table */
+
+		status = osl_map_table(table_address, signature, &mapped_table);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+
+		table_length = ap_get_table_length(mapped_table);
+		if (first_table_address == 0) {
+			first_table_address = table_address;
+		}
+
+		/* Match table instance */
+
+		if (current_instance != instance) {
+			osl_unmap_table(mapped_table);
+			mapped_table = NULL;
+			current_instance++;
+			goto find_next_instance;
+		}
+	} else {		/* Case for a normal ACPI table */
+
+		if (osl_can_use_xsdt()) {
+			item_size = sizeof(u64);
+			table_data =
+			    ACPI_CAST8(gbl_xsdt) +
+			    sizeof(struct acpi_table_header);
+			number_of_tables =
+			    (u8)((gbl_xsdt->header.length -
+				  sizeof(struct acpi_table_header))
+				 / item_size);
+		} else {	/* Use RSDT if XSDT is not available */
+
+			item_size = sizeof(u32);
+			table_data =
+			    ACPI_CAST8(gbl_rsdt) +
+			    sizeof(struct acpi_table_header);
+			number_of_tables =
+			    (u8)((gbl_rsdt->header.length -
+				  sizeof(struct acpi_table_header))
+				 / item_size);
+		}
+
+		/* Search RSDT/XSDT for the requested table */
+
+		for (i = 0; i < number_of_tables; ++i, table_data += item_size) {
+			if (osl_can_use_xsdt()) {
+				table_address =
+				    (acpi_physical_address)(*ACPI_CAST64
+							    (table_data));
+			} else {
+				table_address =
+				    (acpi_physical_address)(*ACPI_CAST32
+							    (table_data));
+			}
+
+			/* Skip NULL entries in RSDT/XSDT */
+
+			if (table_address == 0) {
+				continue;
+			}
+
+			status =
+			    osl_map_table(table_address, NULL, &mapped_table);
+			if (ACPI_FAILURE(status)) {
+				return (status);
+			}
+			table_length = mapped_table->length;
+
+			/* Does this table match the requested signature? */
+
+			if (!ACPI_COMPARE_NAME
+			    (mapped_table->signature, signature)) {
+				osl_unmap_table(mapped_table);
+				mapped_table = NULL;
+				continue;
+			}
+
+			/* Match table instance (for SSDT/UEFI tables) */
+
+			if (current_instance != instance) {
+				osl_unmap_table(mapped_table);
+				mapped_table = NULL;
+				current_instance++;
+				continue;
+			}
+
+			break;
+		}
+	}
+
+exit_find_table:
+
+	if (!mapped_table) {
+		return (AE_LIMIT);
+	}
+
+	if (table_length == 0) {
+		status = AE_BAD_HEADER;
+		goto exit;
+	}
+
+	/* Copy table to local buffer and return it */
+
+	local_table = calloc(1, table_length);
+	if (!local_table) {
+		status = AE_NO_MEMORY;
+		goto exit;
+	}
+
+	memcpy(local_table, mapped_table, table_length);
+	*address = table_address;
+	*table = local_table;
+
+exit:
+	osl_unmap_table(mapped_table);
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_list_customized_tables
+ *
+ * PARAMETERS:  directory           - Directory that contains the tables
+ *
+ * RETURN:      Status; Table list is initialized if AE_OK.
+ *
+ * DESCRIPTION: Add ACPI tables to the table list from a directory.
+ *
+ *****************************************************************************/
+
+static acpi_status osl_list_customized_tables(char *directory)
+{
+	void *table_dir;
+	u32 instance;
+	char temp_name[ACPI_NAME_SIZE];
+	char *filename;
+	acpi_status status = AE_OK;
+
+	/* Open the requested directory */
+
+	table_dir = acpi_os_open_directory(directory, "*", REQUEST_FILE_ONLY);
+	if (!table_dir) {
+		return (osl_get_last_status(AE_NOT_FOUND));
+	}
+
+	/* Examine all entries in this directory */
+
+	while ((filename = acpi_os_get_next_filename(table_dir))) {
+
+		/* Extract table name and instance number */
+
+		status =
+		    osl_table_name_from_file(filename, temp_name, &instance);
+
+		/* Ignore meaningless files */
+
+		if (ACPI_FAILURE(status)) {
+			continue;
+		}
+
+		/* Add new info node to global table list */
+
+		status = osl_add_table_to_list(temp_name, instance);
+		if (ACPI_FAILURE(status)) {
+			break;
+		}
+	}
+
+	acpi_os_close_directory(table_dir);
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_map_table
+ *
+ * PARAMETERS:  address             - Address of the table in memory
+ *              signature           - Optional ACPI Signature for desired table.
+ *                                    Null terminated 4-character string.
+ *              table               - Where a pointer to the mapped table is
+ *                                    returned
+ *
+ * RETURN:      Status; Mapped table is returned if AE_OK.
+ *              AE_NOT_FOUND: A valid table was not found at the address
+ *
+ * DESCRIPTION: Map entire ACPI table into caller's address space.
+ *
+ *****************************************************************************/
+
+static acpi_status
+osl_map_table(acpi_size address,
+	      char *signature, struct acpi_table_header **table)
+{
+	struct acpi_table_header *mapped_table;
+	u32 length;
+
+	if (!address) {
+		return (AE_BAD_ADDRESS);
+	}
+
+	/*
+	 * Map the header so we can get the table length.
+	 * Use sizeof (struct acpi_table_header) as:
+	 * 1. it is bigger than 24 to include RSDP->Length
+	 * 2. it is smaller than sizeof (struct acpi_table_rsdp)
+	 */
+	mapped_table =
+	    acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!mapped_table) {
+		fprintf(stderr, "Could not map table header at 0x%8.8X%8.8X\n",
+			ACPI_FORMAT_UINT64(address));
+		return (osl_get_last_status(AE_BAD_ADDRESS));
+	}
+
+	/* If specified, signature must match */
+
+	if (signature) {
+		if (ACPI_VALIDATE_RSDP_SIG(signature)) {
+			if (!ACPI_VALIDATE_RSDP_SIG(mapped_table->signature)) {
+				acpi_os_unmap_memory(mapped_table,
+						     sizeof(struct
+							    acpi_table_header));
+				return (AE_BAD_SIGNATURE);
+			}
+		} else
+		    if (!ACPI_COMPARE_NAME(signature, mapped_table->signature))
+		{
+			acpi_os_unmap_memory(mapped_table,
+					     sizeof(struct acpi_table_header));
+			return (AE_BAD_SIGNATURE);
+		}
+	}
+
+	/* Map the entire table */
+
+	length = ap_get_table_length(mapped_table);
+	acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
+	if (length == 0) {
+		return (AE_BAD_HEADER);
+	}
+
+	mapped_table = acpi_os_map_memory(address, length);
+	if (!mapped_table) {
+		fprintf(stderr,
+			"Could not map table at 0x%8.8X%8.8X length %8.8X\n",
+			ACPI_FORMAT_UINT64(address), length);
+		return (osl_get_last_status(AE_INVALID_TABLE_LENGTH));
+	}
+
+	(void)ap_is_valid_checksum(mapped_table);
+
+	*table = mapped_table;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_unmap_table
+ *
+ * PARAMETERS:  table               - A pointer to the mapped table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Unmap entire ACPI table.
+ *
+ *****************************************************************************/
+
+static void osl_unmap_table(struct acpi_table_header *table)
+{
+	if (table) {
+		acpi_os_unmap_memory(table, ap_get_table_length(table));
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_table_name_from_file
+ *
+ * PARAMETERS:  filename            - File that contains the desired table
+ *              signature           - Pointer to 4-character buffer to store
+ *                                    extracted table signature.
+ *              instance            - Pointer to integer to store extracted
+ *                                    table instance number.
+ *
+ * RETURN:      Status; Table name is extracted if AE_OK.
+ *
+ * DESCRIPTION: Extract table signature and instance number from a table file
+ *              name.
+ *
+ *****************************************************************************/
+
+static acpi_status
+osl_table_name_from_file(char *filename, char *signature, u32 *instance)
+{
+
+	/* Ignore meaningless files */
+
+	if (strlen(filename) < ACPI_NAME_SIZE) {
+		return (AE_BAD_SIGNATURE);
+	}
+
+	/* Extract instance number */
+
+	if (isdigit((int)filename[ACPI_NAME_SIZE])) {
+		sscanf(&filename[ACPI_NAME_SIZE], "%u", instance);
+	} else if (strlen(filename) != ACPI_NAME_SIZE) {
+		return (AE_BAD_SIGNATURE);
+	} else {
+		*instance = 0;
+	}
+
+	/* Extract signature */
+
+	ACPI_MOVE_NAME(signature, filename);
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_read_table_from_file
+ *
+ * PARAMETERS:  filename            - File that contains the desired table
+ *              file_offset         - Offset of the table in file
+ *              signature           - Optional ACPI Signature for desired table.
+ *                                    A null terminated 4-character string.
+ *              table               - Where a pointer to the table is returned
+ *
+ * RETURN:      Status; Table buffer is returned if AE_OK.
+ *
+ * DESCRIPTION: Read a ACPI table from a file.
+ *
+ *****************************************************************************/
+
+static acpi_status
+osl_read_table_from_file(char *filename,
+			 acpi_size file_offset,
+			 char *signature, struct acpi_table_header **table)
+{
+	FILE *table_file;
+	struct acpi_table_header header;
+	struct acpi_table_header *local_table = NULL;
+	u32 table_length;
+	s32 count;
+	acpi_status status = AE_OK;
+
+	/* Open the file */
+
+	table_file = fopen(filename, "rb");
+	if (table_file == NULL) {
+		fprintf(stderr, "Could not open table file: %s\n", filename);
+		return (osl_get_last_status(AE_NOT_FOUND));
+	}
+
+	fseek(table_file, file_offset, SEEK_SET);
+
+	/* Read the Table header to get the table length */
+
+	count = fread(&header, 1, sizeof(struct acpi_table_header), table_file);
+	if (count != sizeof(struct acpi_table_header)) {
+		fprintf(stderr, "Could not read table header: %s\n", filename);
+		status = AE_BAD_HEADER;
+		goto exit;
+	}
+
+	/* If signature is specified, it must match the table */
+
+	if (signature) {
+		if (ACPI_VALIDATE_RSDP_SIG(signature)) {
+			if (!ACPI_VALIDATE_RSDP_SIG(header.signature)) {
+				fprintf(stderr,
+					"Incorrect RSDP signature: found %8.8s\n",
+					header.signature);
+				status = AE_BAD_SIGNATURE;
+				goto exit;
+			}
+		} else if (!ACPI_COMPARE_NAME(signature, header.signature)) {
+			fprintf(stderr,
+				"Incorrect signature: Expecting %4.4s, found %4.4s\n",
+				signature, header.signature);
+			status = AE_BAD_SIGNATURE;
+			goto exit;
+		}
+	}
+
+	table_length = ap_get_table_length(&header);
+	if (table_length == 0) {
+		status = AE_BAD_HEADER;
+		goto exit;
+	}
+
+	/* Read the entire table into a local buffer */
+
+	local_table = calloc(1, table_length);
+	if (!local_table) {
+		fprintf(stderr,
+			"%4.4s: Could not allocate buffer for table of length %X\n",
+			header.signature, table_length);
+		status = AE_NO_MEMORY;
+		goto exit;
+	}
+
+	fseek(table_file, file_offset, SEEK_SET);
+
+	count = fread(local_table, 1, table_length, table_file);
+	if (count != table_length) {
+		fprintf(stderr, "%4.4s: Could not read table content\n",
+			header.signature);
+		status = AE_INVALID_TABLE_LENGTH;
+		goto exit;
+	}
+
+	/* Validate checksum */
+
+	(void)ap_is_valid_checksum(local_table);
+
+exit:
+	fclose(table_file);
+	*table = local_table;
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    osl_get_customized_table
+ *
+ * PARAMETERS:  pathname        - Directory to find Linux customized table
+ *              signature       - ACPI Signature for desired table. Must be
+ *                                a null terminated 4-character string.
+ *              instance        - Multiple table support for SSDT/UEFI (0...n)
+ *                                Must be 0 for other tables.
+ *              table           - Where a pointer to the table is returned
+ *              address         - Where the table physical address is returned
+ *
+ * RETURN:      Status; Table buffer is returned if AE_OK.
+ *              AE_LIMIT: Instance is beyond valid limit
+ *              AE_NOT_FOUND: A table with the signature was not found
+ *
+ * DESCRIPTION: Get an OS customized table.
+ *
+ *****************************************************************************/
+
+static acpi_status
+osl_get_customized_table(char *pathname,
+			 char *signature,
+			 u32 instance,
+			 struct acpi_table_header **table,
+			 acpi_physical_address *address)
+{
+	void *table_dir;
+	u32 current_instance = 0;
+	char temp_name[ACPI_NAME_SIZE];
+	char table_filename[PATH_MAX];
+	char *filename;
+	acpi_status status;
+
+	/* Open the directory for customized tables */
+
+	table_dir = acpi_os_open_directory(pathname, "*", REQUEST_FILE_ONLY);
+	if (!table_dir) {
+		return (osl_get_last_status(AE_NOT_FOUND));
+	}
+
+	/* Attempt to find the table in the directory */
+
+	while ((filename = acpi_os_get_next_filename(table_dir))) {
+
+		/* Ignore meaningless files */
+
+		if (!ACPI_COMPARE_NAME(filename, signature)) {
+			continue;
+		}
+
+		/* Extract table name and instance number */
+
+		status =
+		    osl_table_name_from_file(filename, temp_name,
+					     &current_instance);
+
+		/* Ignore meaningless files */
+
+		if (ACPI_FAILURE(status) || current_instance != instance) {
+			continue;
+		}
+
+		/* Create the table pathname */
+
+		if (instance != 0) {
+			sprintf(table_filename, "%s/%4.4s%d", pathname,
+				temp_name, instance);
+		} else {
+			sprintf(table_filename, "%s/%4.4s", pathname,
+				temp_name);
+		}
+		break;
+	}
+
+	acpi_os_close_directory(table_dir);
+
+	if (!filename) {
+		return (AE_LIMIT);
+	}
+
+	/* There is no physical address saved for customized tables, use zero */
+
+	*address = 0;
+	status = osl_read_table_from_file(table_filename, 0, NULL, table);
+
+	return (status);
+}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c
new file mode 100644
index 0000000..4fd44e2
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: osunixdir - Unix directory access interfaces
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+#include <acpi/acpi.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+/*
+ * Allocated structure returned from os_open_directory
+ */
+typedef struct external_find_info {
+	char *dir_pathname;
+	DIR *dir_ptr;
+	char temp_buffer[256];
+	char *wildcard_spec;
+	char requested_file_type;
+
+} external_find_info;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_open_directory
+ *
+ * PARAMETERS:  dir_pathname        - Full pathname to the directory
+ *              wildcard_spec       - string of the form "*.c", etc.
+ *
+ * RETURN:      A directory "handle" to be used in subsequent search operations.
+ *              NULL returned on failure.
+ *
+ * DESCRIPTION: Open a directory in preparation for a wildcard search
+ *
+ ******************************************************************************/
+
+void *acpi_os_open_directory(char *dir_pathname,
+			     char *wildcard_spec, char requested_file_type)
+{
+	struct external_find_info *external_info;
+	DIR *dir;
+
+	/* Allocate the info struct that will be returned to the caller */
+
+	external_info = calloc(1, sizeof(struct external_find_info));
+	if (!external_info) {
+		return (NULL);
+	}
+
+	/* Get the directory stream */
+
+	dir = opendir(dir_pathname);
+	if (!dir) {
+		fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
+		free(external_info);
+		return (NULL);
+	}
+
+	/* Save the info in the return structure */
+
+	external_info->wildcard_spec = wildcard_spec;
+	external_info->requested_file_type = requested_file_type;
+	external_info->dir_pathname = dir_pathname;
+	external_info->dir_ptr = dir;
+	return (external_info);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_next_filename
+ *
+ * PARAMETERS:  dir_handle          - Created via acpi_os_open_directory
+ *
+ * RETURN:      Next filename matched. NULL if no more matches.
+ *
+ * DESCRIPTION: Get the next file in the directory that matches the wildcard
+ *              specification.
+ *
+ ******************************************************************************/
+
+char *acpi_os_get_next_filename(void *dir_handle)
+{
+	struct external_find_info *external_info = dir_handle;
+	struct dirent *dir_entry;
+	char *temp_str;
+	int str_len;
+	struct stat temp_stat;
+	int err;
+
+	while ((dir_entry = readdir(external_info->dir_ptr))) {
+		if (!fnmatch
+		    (external_info->wildcard_spec, dir_entry->d_name, 0)) {
+			if (dir_entry->d_name[0] == '.') {
+				continue;
+			}
+
+			str_len = strlen(dir_entry->d_name) +
+			    strlen(external_info->dir_pathname) + 2;
+
+			temp_str = calloc(str_len, 1);
+			if (!temp_str) {
+				fprintf(stderr,
+					"Could not allocate buffer for temporary string\n");
+				return (NULL);
+			}
+
+			strcpy(temp_str, external_info->dir_pathname);
+			strcat(temp_str, "/");
+			strcat(temp_str, dir_entry->d_name);
+
+			err = stat(temp_str, &temp_stat);
+			if (err == -1) {
+				fprintf(stderr,
+					"Cannot stat file (should not happen) - %s\n",
+					temp_str);
+				free(temp_str);
+				return (NULL);
+			}
+
+			free(temp_str);
+
+			if ((S_ISDIR(temp_stat.st_mode)
+			     && (external_info->requested_file_type ==
+				 REQUEST_DIR_ONLY))
+			    || ((!S_ISDIR(temp_stat.st_mode)
+				 && external_info->requested_file_type ==
+				 REQUEST_FILE_ONLY))) {
+
+				/* copy to a temp buffer because dir_entry struct is on the stack */
+
+				strcpy(external_info->temp_buffer,
+				       dir_entry->d_name);
+				return (external_info->temp_buffer);
+			}
+		}
+	}
+
+	return (NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_close_directory
+ *
+ * PARAMETERS:  dir_handle          - Created via acpi_os_open_directory
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Close the open directory and cleanup.
+ *
+ ******************************************************************************/
+
+void acpi_os_close_directory(void *dir_handle)
+{
+	struct external_find_info *external_info = dir_handle;
+
+	/* Close the directory and free allocations */
+
+	closedir(external_info->dir_ptr);
+	free(dir_handle);
+}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c
new file mode 100644
index 0000000..93d8359
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: osunixmap - Unix OSL for file mappings
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+#include "acpidump.h"
+#include <unistd.h>
+#include <sys/mman.h>
+#ifdef _free_BSD
+#include <sys/param.h>
+#endif
+
+#define _COMPONENT          ACPI_OS_SERVICES
+ACPI_MODULE_NAME("osunixmap")
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#if defined(_dragon_fly) || defined(_free_BSD) || defined(_QNX)
+#define MMAP_FLAGS          MAP_SHARED
+#else
+#define MMAP_FLAGS          MAP_PRIVATE
+#endif
+#define SYSTEM_MEMORY       "/dev/mem"
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_page_size
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Page size of the platform.
+ *
+ * DESCRIPTION: Obtain page size of the platform.
+ *
+ ******************************************************************************/
+static acpi_size acpi_os_get_page_size(void)
+{
+
+#ifdef PAGE_SIZE
+	return PAGE_SIZE;
+#else
+	return sysconf(_SC_PAGESIZE);
+#endif
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_map_memory
+ *
+ * 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 local address space.
+ *
+ *****************************************************************************/
+
+void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
+{
+	u8 *mapped_memory;
+	acpi_physical_address offset;
+	acpi_size page_size;
+	int fd;
+
+	fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
+	if (fd < 0) {
+		fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
+		return (NULL);
+	}
+
+	/* Align the offset to use mmap */
+
+	page_size = acpi_os_get_page_size();
+	offset = where % page_size;
+
+	/* Map the table header to get the length of the full table */
+
+	mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
+			     fd, (where - offset));
+	if (mapped_memory == MAP_FAILED) {
+		fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
+		close(fd);
+		return (NULL);
+	}
+
+	close(fd);
+	return (ACPI_CAST8(mapped_memory + offset));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_unmap_memory
+ *
+ * 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 acpi_os_unmap_memory(void *where, acpi_size length)
+{
+	acpi_physical_address offset;
+	acpi_size page_size;
+
+	page_size = acpi_os_get_page_size();
+	offset = ACPI_TO_INTEGER(where) % page_size;
+	munmap((u8 *)where - offset, (length + offset));
+}
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c
new file mode 100644
index 0000000..8a88e87
--- /dev/null
+++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c
@@ -0,0 +1,1317 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/******************************************************************************
+ *
+ * Module Name: osunixxf - UNIX OSL interfaces
+ *
+ * Copyright (C) 2000 - 2018, Intel Corp.
+ *
+ *****************************************************************************/
+
+/*
+ * These interfaces are required in order to compile the ASL compiler and the
+ * various ACPICA tools under Linux or other Unix-like system.
+ */
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "amlcode.h"
+#include "acparser.h"
+#include "acdebug.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <errno.h>
+
+#define _COMPONENT          ACPI_OS_SERVICES
+ACPI_MODULE_NAME("osunixxf")
+
+/* Upcalls to acpi_exec */
+void
+ae_table_override(struct acpi_table_header *existing_table,
+		  struct acpi_table_header **new_table);
+
+typedef void *(*PTHREAD_CALLBACK) (void *);
+
+/* Buffer used by acpi_os_vprintf */
+
+#define ACPI_VPRINTF_BUFFER_SIZE    512
+#define _ASCII_NEWLINE              '\n'
+
+/* Terminal support for acpi_exec only */
+
+#ifdef ACPI_EXEC_APP
+#include <termios.h>
+
+struct termios original_term_attributes;
+int term_attributes_were_set = 0;
+
+acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read);
+
+static void os_enter_line_edit_mode(void);
+
+static void os_exit_line_edit_mode(void);
+
+/******************************************************************************
+ *
+ * FUNCTION:    os_enter_line_edit_mode, os_exit_line_edit_mode
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
+ *
+ * Interactive line-editing support for the AML debugger. Used with the
+ * common/acgetline module.
+ *
+ * readline() is not used because of non-portability. It is not available
+ * on all systems, and if it is, often the package must be manually installed.
+ *
+ * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
+ * editing that we need in acpi_os_get_line.
+ *
+ * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
+ * calls will also work:
+ *     For os_enter_line_edit_mode: system ("stty cbreak -echo")
+ *     For os_exit_line_edit_mode: system ("stty cooked echo")
+ *
+ *****************************************************************************/
+
+static void os_enter_line_edit_mode(void)
+{
+	struct termios local_term_attributes;
+
+	term_attributes_were_set = 0;
+
+	/* STDIN must be a terminal */
+
+	if (!isatty(STDIN_FILENO)) {
+		return;
+	}
+
+	/* Get and keep the original attributes */
+
+	if (tcgetattr(STDIN_FILENO, &original_term_attributes)) {
+		fprintf(stderr, "Could not get terminal attributes!\n");
+		return;
+	}
+
+	/* Set the new attributes to enable raw character input */
+
+	memcpy(&local_term_attributes, &original_term_attributes,
+	       sizeof(struct termios));
+
+	local_term_attributes.c_lflag &= ~(ICANON | ECHO);
+	local_term_attributes.c_cc[VMIN] = 1;
+	local_term_attributes.c_cc[VTIME] = 0;
+
+	if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) {
+		fprintf(stderr, "Could not set terminal attributes!\n");
+		return;
+	}
+
+	term_attributes_were_set = 1;
+}
+
+static void os_exit_line_edit_mode(void)
+{
+
+	if (!term_attributes_were_set) {
+		return;
+	}
+
+	/* Set terminal attributes back to the original values */
+
+	if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) {
+		fprintf(stderr, "Could not restore terminal attributes!\n");
+	}
+}
+
+#else
+
+/* These functions are not needed for other ACPICA utilities */
+
+#define os_enter_line_edit_mode()
+#define os_exit_line_edit_mode()
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_initialize, acpi_os_terminate
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize and terminate this module.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_initialize(void)
+{
+	acpi_status status;
+
+	acpi_gbl_output_file = stdout;
+
+	os_enter_line_edit_mode();
+
+	status = acpi_os_create_lock(&acpi_gbl_print_lock);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	return (AE_OK);
+}
+
+acpi_status acpi_os_terminate(void)
+{
+
+	os_exit_line_edit_mode();
+	return (AE_OK);
+}
+
+#ifndef ACPI_USE_NATIVE_RSDP_POINTER
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_root_pointer
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      RSDP physical address
+ *
+ * DESCRIPTION: Gets the ACPI root pointer (RSDP)
+ *
+ *****************************************************************************/
+
+acpi_physical_address acpi_os_get_root_pointer(void)
+{
+
+	return (0);
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_predefined_override
+ *
+ * PARAMETERS:  init_val            - Initial value of the predefined object
+ *              new_val             - The new value for the object
+ *
+ * RETURN:      Status, pointer to value. Null pointer returned if not
+ *              overriding.
+ *
+ * DESCRIPTION: Allow the OS to override predefined names
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
+			    acpi_string *new_val)
+{
+
+	if (!init_val || !new_val) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	*new_val = NULL;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_table_override
+ *
+ * PARAMETERS:  existing_table      - Header of current table (probably
+ *                                    firmware)
+ *              new_table           - Where an entire new table is returned.
+ *
+ * RETURN:      Status, pointer to new table. Null pointer returned if no
+ *              table is available to override
+ *
+ * DESCRIPTION: Return a different version of a table if one is available
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_table_override(struct acpi_table_header *existing_table,
+		       struct acpi_table_header **new_table)
+{
+
+	if (!existing_table || !new_table) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	*new_table = NULL;
+
+#ifdef ACPI_EXEC_APP
+
+	ae_table_override(existing_table, new_table);
+	return (AE_OK);
+#else
+
+	return (AE_NO_ACPI_TABLES);
+#endif
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_physical_table_override
+ *
+ * PARAMETERS:  existing_table      - Header of current table (probably firmware)
+ *              new_address         - Where new table address is returned
+ *                                    (Physical address)
+ *              new_table_length    - Where new table length is returned
+ *
+ * RETURN:      Status, address/length of new table. Null pointer returned
+ *              if no table is available to override.
+ *
+ * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_physical_table_override(struct acpi_table_header *existing_table,
+				acpi_physical_address *new_address,
+				u32 *new_table_length)
+{
+
+	return (AE_SUPPORT);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_enter_sleep
+ *
+ * PARAMETERS:  sleep_state         - Which sleep state to enter
+ *              rega_value          - Register A value
+ *              regb_value          - Register B value
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: A hook before writing sleep registers to enter the sleep
+ *              state. Return AE_CTRL_TERMINATE to skip further sleep register
+ *              writes.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_enter_sleep(u8 sleep_state, u32 rega_value, u32 regb_value)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_redirect_output
+ *
+ * PARAMETERS:  destination         - An open file handle/pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf
+ *
+ *****************************************************************************/
+
+void acpi_os_redirect_output(void *destination)
+{
+
+	acpi_gbl_output_file = destination;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_printf
+ *
+ * PARAMETERS:  fmt, ...            - Standard printf format
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf
+ *              (performance), changes should be tracked in both functions.
+ *
+ *****************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
+{
+	va_list args;
+	u8 flags;
+
+	flags = acpi_gbl_db_output_flags;
+	if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
+
+		/* Output is directable to either a file (if open) or the console */
+
+		if (acpi_gbl_debug_file) {
+
+			/* Output file is open, send the output there */
+
+			va_start(args, fmt);
+			vfprintf(acpi_gbl_debug_file, fmt, args);
+			va_end(args);
+		} else {
+			/* No redirection, send output to console (once only!) */
+
+			flags |= ACPI_DB_CONSOLE_OUTPUT;
+		}
+	}
+
+	if (flags & ACPI_DB_CONSOLE_OUTPUT) {
+		va_start(args, fmt);
+		vfprintf(acpi_gbl_output_file, fmt, args);
+		va_end(args);
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_vprintf
+ *
+ * PARAMETERS:  fmt                 - Standard printf format
+ *              args                - Argument list
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Formatted output with argument list pointer. Note: very
+ *              similar to acpi_os_printf, changes should be tracked in both
+ *              functions.
+ *
+ *****************************************************************************/
+
+void acpi_os_vprintf(const char *fmt, va_list args)
+{
+	u8 flags;
+	char buffer[ACPI_VPRINTF_BUFFER_SIZE];
+
+	/*
+	 * We build the output string in a local buffer because we may be
+	 * outputting the buffer twice. Using vfprintf is problematic because
+	 * some implementations modify the args pointer/structure during
+	 * execution. Thus, we use the local buffer for portability.
+	 *
+	 * Note: Since this module is intended for use by the various ACPICA
+	 * utilities/applications, we can safely declare the buffer on the stack.
+	 * Also, This function is used for relatively small error messages only.
+	 */
+	vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args);
+
+	flags = acpi_gbl_db_output_flags;
+	if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
+
+		/* Output is directable to either a file (if open) or the console */
+
+		if (acpi_gbl_debug_file) {
+
+			/* Output file is open, send the output there */
+
+			fputs(buffer, acpi_gbl_debug_file);
+		} else {
+			/* No redirection, send output to console (once only!) */
+
+			flags |= ACPI_DB_CONSOLE_OUTPUT;
+		}
+	}
+
+	if (flags & ACPI_DB_CONSOLE_OUTPUT) {
+		fputs(buffer, acpi_gbl_output_file);
+	}
+}
+
+#ifndef ACPI_EXEC_APP
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_line
+ *
+ * PARAMETERS:  buffer              - Where to return the command line
+ *              buffer_length       - Maximum length of Buffer
+ *              bytes_read          - Where the actual byte count is returned
+ *
+ * RETURN:      Status and actual bytes read
+ *
+ * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
+ *              acpi_exec utility, we use the acgetline module instead to
+ *              provide line-editing and history support.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
+{
+	int input_char;
+	u32 end_of_line;
+
+	/* Standard acpi_os_get_line for all utilities except acpi_exec */
+
+	for (end_of_line = 0;; end_of_line++) {
+		if (end_of_line >= buffer_length) {
+			return (AE_BUFFER_OVERFLOW);
+		}
+
+		if ((input_char = getchar()) == EOF) {
+			return (AE_ERROR);
+		}
+
+		if (!input_char || input_char == _ASCII_NEWLINE) {
+			break;
+		}
+
+		buffer[end_of_line] = (char)input_char;
+	}
+
+	/* Null terminate the buffer */
+
+	buffer[end_of_line] = 0;
+
+	/* Return the number of bytes in the string */
+
+	if (bytes_read) {
+		*bytes_read = end_of_line;
+	}
+
+	return (AE_OK);
+}
+#endif
+
+#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_map_memory
+ *
+ * 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 *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
+{
+
+	return (ACPI_TO_POINTER((acpi_size)where));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_unmap_memory
+ *
+ * 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 acpi_os_unmap_memory(void *where, acpi_size length)
+{
+
+	return;
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_allocate
+ *
+ * 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 *acpi_os_allocate(acpi_size size)
+{
+	void *mem;
+
+	mem = (void *)malloc((size_t) size);
+	return (mem);
+}
+
+#ifdef USE_NATIVE_ALLOCATE_ZEROED
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_allocate_zeroed
+ *
+ * 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 *acpi_os_allocate_zeroed(acpi_size size)
+{
+	void *mem;
+
+	mem = (void *)calloc(1, (size_t) size);
+	return (mem);
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_free
+ *
+ * PARAMETERS:  mem                 - Pointer to previously allocated memory
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free memory allocated via acpi_os_allocate
+ *
+ *****************************************************************************/
+
+void acpi_os_free(void *mem)
+{
+
+	free(mem);
+}
+
+#ifdef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION:    Semaphore stub functions
+ *
+ * DESCRIPTION: Stub functions used for single-thread applications that do
+ *              not require semaphore synchronization. Full implementations
+ *              of these functions appear after the stubs.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_create_semaphore(u32 max_units,
+			 u32 initial_units, acpi_handle *out_handle)
+{
+	*out_handle = (acpi_handle)1;
+	return (AE_OK);
+}
+
+acpi_status acpi_os_delete_semaphore(acpi_handle handle)
+{
+	return (AE_OK);
+}
+
+acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
+{
+	return (AE_OK);
+}
+
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+{
+	return (AE_OK);
+}
+
+#else
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_create_semaphore
+ *
+ * PARAMETERS:  initial_units       - Units to be assigned to the new semaphore
+ *              out_handle          - Where a handle will be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an OS semaphore
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_create_semaphore(u32 max_units,
+			 u32 initial_units, acpi_handle *out_handle)
+{
+	sem_t *sem;
+
+	if (!out_handle) {
+		return (AE_BAD_PARAMETER);
+	}
+#ifdef __APPLE__
+	{
+		static int semaphore_count = 0;
+		char semaphore_name[32];
+
+		snprintf(semaphore_name, sizeof(semaphore_name), "acpi_sem_%d",
+			 semaphore_count++);
+		printf("%s\n", semaphore_name);
+		sem =
+		    sem_open(semaphore_name, O_EXCL | O_CREAT, 0755,
+			     initial_units);
+		if (!sem) {
+			return (AE_NO_MEMORY);
+		}
+		sem_unlink(semaphore_name);	/* This just deletes the name */
+	}
+
+#else
+	sem = acpi_os_allocate(sizeof(sem_t));
+	if (!sem) {
+		return (AE_NO_MEMORY);
+	}
+
+	if (sem_init(sem, 0, initial_units) == -1) {
+		acpi_os_free(sem);
+		return (AE_BAD_PARAMETER);
+	}
+#endif
+
+	*out_handle = (acpi_handle)sem;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_delete_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete an OS semaphore
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_delete_semaphore(acpi_handle handle)
+{
+	sem_t *sem = (sem_t *) handle;
+
+	if (!sem) {
+		return (AE_BAD_PARAMETER);
+	}
+#ifdef __APPLE__
+	if (sem_close(sem) == -1) {
+		return (AE_BAD_PARAMETER);
+	}
+#else
+	if (sem_destroy(sem) == -1) {
+		return (AE_BAD_PARAMETER);
+	}
+#endif
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_wait_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *              units               - How many units to wait for
+ *              msec_timeout        - How long to wait (milliseconds)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Wait for units
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout)
+{
+	acpi_status status = AE_OK;
+	sem_t *sem = (sem_t *) handle;
+	int ret_val;
+#ifndef ACPI_USE_ALTERNATE_TIMEOUT
+	struct timespec time;
+#endif
+
+	if (!sem) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	switch (msec_timeout) {
+		/*
+		 * No Wait:
+		 * --------
+		 * A zero timeout value indicates that we shouldn't wait - just
+		 * acquire the semaphore if available otherwise return AE_TIME
+		 * (a.k.a. 'would block').
+		 */
+	case 0:
+
+		if (sem_trywait(sem) == -1) {
+			status = (AE_TIME);
+		}
+		break;
+
+		/* Wait Indefinitely */
+
+	case ACPI_WAIT_FOREVER:
+
+		while (((ret_val = sem_wait(sem)) == -1) && (errno == EINTR)) {
+			continue;	/* Restart if interrupted */
+		}
+		if (ret_val != 0) {
+			status = (AE_TIME);
+		}
+		break;
+
+		/* Wait with msec_timeout */
+
+	default:
+
+#ifdef ACPI_USE_ALTERNATE_TIMEOUT
+		/*
+		 * Alternate timeout mechanism for environments where
+		 * sem_timedwait is not available or does not work properly.
+		 */
+		while (msec_timeout) {
+			if (sem_trywait(sem) == 0) {
+
+				/* Got the semaphore */
+				return (AE_OK);
+			}
+
+			if (msec_timeout >= 10) {
+				msec_timeout -= 10;
+				usleep(10 * ACPI_USEC_PER_MSEC);	/* ten milliseconds */
+			} else {
+				msec_timeout--;
+				usleep(ACPI_USEC_PER_MSEC);	/* one millisecond */
+			}
+		}
+		status = (AE_TIME);
+#else
+		/*
+		 * The interface to sem_timedwait is an absolute time, so we need to
+		 * get the current time, then add in the millisecond Timeout value.
+		 */
+		if (clock_gettime(CLOCK_REALTIME, &time) == -1) {
+			perror("clock_gettime");
+			return (AE_TIME);
+		}
+
+		time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC);
+		time.tv_nsec +=
+		    ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
+
+		/* Handle nanosecond overflow (field must be less than one second) */
+
+		if (time.tv_nsec >= ACPI_NSEC_PER_SEC) {
+			time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC);
+			time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC);
+		}
+
+		while (((ret_val = sem_timedwait(sem, &time)) == -1)
+		       && (errno == EINTR)) {
+			continue;	/* Restart if interrupted */
+
+		}
+
+		if (ret_val != 0) {
+			if (errno != ETIMEDOUT) {
+				perror("sem_timedwait");
+			}
+			status = (AE_TIME);
+		}
+#endif
+		break;
+	}
+
+	return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_signal_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *              units               - Number of units to send
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Send units
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+{
+	sem_t *sem = (sem_t *) handle;
+
+	if (!sem) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (sem_post(sem) == -1) {
+		return (AE_LIMIT);
+	}
+
+	return (AE_OK);
+}
+
+#endif				/* ACPI_SINGLE_THREADED */
+
+/******************************************************************************
+ *
+ * FUNCTION:    Spinlock interfaces
+ *
+ * DESCRIPTION: Map these interfaces to semaphore interfaces
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_create_lock(acpi_spinlock * out_handle)
+{
+
+	return (acpi_os_create_semaphore(1, 1, out_handle));
+}
+
+void acpi_os_delete_lock(acpi_spinlock handle)
+{
+	acpi_os_delete_semaphore(handle);
+}
+
+acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)
+{
+	acpi_os_wait_semaphore(handle, 1, 0xFFFF);
+	return (0);
+}
+
+void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags)
+{
+	acpi_os_signal_semaphore(handle, 1);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_install_interrupt_handler
+ *
+ * PARAMETERS:  interrupt_number    - Level handler should respond to.
+ *              isr                 - Address of the ACPI interrupt handler
+ *              except_ptr          - Where status is returned
+ *
+ * RETURN:      Handle to the newly installed handler.
+ *
+ * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
+ *              OS-independent handler.
+ *
+ *****************************************************************************/
+
+u32
+acpi_os_install_interrupt_handler(u32 interrupt_number,
+				  acpi_osd_handler service_routine,
+				  void *context)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_remove_interrupt_handler
+ *
+ * PARAMETERS:  handle              - Returned when handler was installed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Uninstalls an interrupt handler.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_remove_interrupt_handler(u32 interrupt_number,
+				 acpi_osd_handler service_routine)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_stall
+ *
+ * PARAMETERS:  microseconds        - Time to sleep
+ *
+ * RETURN:      Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at microsecond granularity
+ *
+ *****************************************************************************/
+
+void acpi_os_stall(u32 microseconds)
+{
+
+	if (microseconds) {
+		usleep(microseconds);
+	}
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_sleep
+ *
+ * PARAMETERS:  milliseconds        - Time to sleep
+ *
+ * RETURN:      Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at millisecond granularity
+ *
+ *****************************************************************************/
+
+void acpi_os_sleep(u64 milliseconds)
+{
+
+	/* Sleep for whole seconds */
+
+	sleep(milliseconds / ACPI_MSEC_PER_SEC);
+
+	/*
+	 * Sleep for remaining microseconds.
+	 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
+	 */
+	usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_timer
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Current time in 100 nanosecond units
+ *
+ * DESCRIPTION: Get the current system time
+ *
+ *****************************************************************************/
+
+u64 acpi_os_get_timer(void)
+{
+	struct timeval time;
+
+	/* This timer has sufficient resolution for user-space application code */
+
+	gettimeofday(&time, NULL);
+
+	/* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
+
+	return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) +
+		((u64)time.tv_usec * ACPI_100NSEC_PER_USEC));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_pci_configuration
+ *
+ * PARAMETERS:  pci_id              - Seg/Bus/Dev
+ *              pci_register        - Device Register
+ *              value               - Buffer where value is placed
+ *              width               - Number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read data from PCI configuration space
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
+			       u32 pci_register, u64 *value, u32 width)
+{
+
+	*value = 0;
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_pci_configuration
+ *
+ * PARAMETERS:  pci_id              - Seg/Bus/Dev
+ *              pci_register        - Device Register
+ *              value               - Value to be written
+ *              width               - Number of bits
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Write data to PCI configuration space
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
+				u32 pci_register, u64 value, u32 width)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_port
+ *
+ * PARAMETERS:  address             - Address of I/O port/register to read
+ *              value               - Where value is placed
+ *              width               - Number of bits
+ *
+ * RETURN:      Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+
+	switch (width) {
+	case 8:
+
+		*value = 0xFF;
+		break;
+
+	case 16:
+
+		*value = 0xFFFF;
+		break;
+
+	case 32:
+
+		*value = 0xFFFFFFFF;
+		break;
+
+	default:
+
+		return (AE_BAD_PARAMETER);
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_port
+ *
+ * PARAMETERS:  address             - Address of I/O port/register to write
+ *              value               - Value to write
+ *              width               - Number of bits
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to an I/O port or register
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_memory
+ *
+ * PARAMETERS:  address             - Physical Memory Address to read
+ *              value               - Where value is placed
+ *              width               - Number of bits (8,16,32, or 64)
+ *
+ * RETURN:      Value read from physical memory address. Always returned
+ *              as a 64-bit integer, regardless of the read width.
+ *
+ * DESCRIPTION: Read data from a physical memory address
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width)
+{
+
+	switch (width) {
+	case 8:
+	case 16:
+	case 32:
+	case 64:
+
+		*value = 0;
+		break;
+
+	default:
+
+		return (AE_BAD_PARAMETER);
+	}
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_memory
+ *
+ * PARAMETERS:  address             - Physical Memory Address to write
+ *              value               - Value to write
+ *              width               - Number of bits (8,16,32, or 64)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to a physical memory address
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width)
+{
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_readable
+ *
+ * PARAMETERS:  pointer             - Area to be verified
+ *              length              - Size of area
+ *
+ * RETURN:      TRUE if readable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for reading
+ *
+ *****************************************************************************/
+
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+
+	return (TRUE);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_writable
+ *
+ * PARAMETERS:  pointer             - Area to be verified
+ *              length              - Size of area
+ *
+ * RETURN:      TRUE if writable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for writing
+ *
+ *****************************************************************************/
+
+u8 acpi_os_writable(void *pointer, acpi_size length)
+{
+
+	return (TRUE);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_signal
+ *
+ * PARAMETERS:  function            - ACPI A signal function code
+ *              info                - Pointer to function-dependent structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Miscellaneous functions. Example implementation only.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_signal(u32 function, void *info)
+{
+
+	switch (function) {
+	case ACPI_SIGNAL_FATAL:
+
+		break;
+
+	case ACPI_SIGNAL_BREAKPOINT:
+
+		break;
+
+	default:
+
+		break;
+	}
+
+	return (AE_OK);
+}
+
+/* Optional multi-thread support */
+
+#ifndef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_thread_id
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Id of the running thread
+ *
+ * DESCRIPTION: Get the ID of the current (running) thread
+ *
+ *****************************************************************************/
+
+acpi_thread_id acpi_os_get_thread_id(void)
+{
+	pthread_t thread;
+
+	thread = pthread_self();
+	return (ACPI_CAST_PTHREAD_T(thread));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_execute
+ *
+ * PARAMETERS:  type                - Type of execution
+ *              function            - Address of the function to execute
+ *              context             - Passed as a parameter to the function
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Execute a new thread
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_execute(acpi_execute_type type,
+		acpi_osd_exec_callback function, void *context)
+{
+	pthread_t thread;
+	int ret;
+
+	ret =
+	    pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context);
+	if (ret) {
+		acpi_os_printf("Create thread failed");
+	}
+	return (0);
+}
+
+#else				/* ACPI_SINGLE_THREADED */
+acpi_thread_id acpi_os_get_thread_id(void)
+{
+	return (1);
+}
+
+acpi_status
+acpi_os_execute(acpi_execute_type type,
+		acpi_osd_exec_callback function, void *context)
+{
+
+	function(context);
+
+	return (AE_OK);
+}
+
+#endif				/* ACPI_SINGLE_THREADED */
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_wait_events_complete
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Wait for all asynchronous events to complete. This
+ *              implementation does nothing.
+ *
+ *****************************************************************************/
+
+void acpi_os_wait_events_complete(void)
+{
+	return;
+}