Changes to support Fuchsia

Adds support for a GN build and imports some changes from previous
ACPICA port to support Fuchsia. This library does not support
building for the kernel.

Change-Id: Iba9914c7b11534a429c35b52560213725afca148
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..b4eb81a
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,248 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("$zx_build/public/gn/config/globals.gni")
+
+declare_args() {
+  # Enable debug output in the ACPI library (used by the ACPI bus driver).
+  acpica_debug_output = false
+}
+
+group("headers") {
+  public_configs = [
+    ":headers.config",
+    ":disable_warnings",
+  ]
+}
+
+config("headers.config") {
+  visibility = [ ":headers" ]
+  include_dirs = [ "include" ]
+
+  # UBSan warns on a few instances of misaligned loads. Define this macro to
+  # perform byte-by-byte accesses.
+  defines = [ "ACPI_MISALIGNMENT_NOT_SUPPORTED" ]
+}
+
+# Disable warnings we won't fix in third-party code.  Putting this in a
+# separate config rather than directly in the target gets these flags
+# correctly ordered after the $zx/public/gn/config:default_warnings flags.
+config("disable_warnings") {
+  visibility = [ ":*" ]
+
+  cflags = [
+    "-Wno-implicit-fallthrough",
+    "-Wno-incompatible-pointer-types-discards-qualifiers",
+    "-Wno-null-pointer-arithmetic",
+  ]
+}
+
+static_library("acpica") {
+  public_deps = [ ":headers" ]
+
+  # Local sources use #include "acpi.h", not #include <acpica/acpi.h>.
+  include_dirs = [ "source/include" ]
+
+  configs += [ ":disable_warnings" ]
+
+  # We need to specify -fno-strict-aliasing, since ACPICA has a habit of
+  # violating strict aliasing rules in some of its macros.  Rewriting this
+  # code would increase the maintenance cost of bringing in the latest
+  # upstream ACPICA, so instead we mitigate the problem with a compile-time
+  # flag.  We take the more conservative approach of disabling
+  # strict-aliasing-based optimizations, rather than disabling warnings.
+  cflags = [ "-fno-strict-aliasing" ]
+
+  sources = [
+    "$zx/system/ulib/acpica/osfuchsia.cc",
+    "source/common/ahids.c",
+    "source/common/ahpredef.c",
+    "source/common/ahtable.c",
+    "source/common/dmtbdump.c",
+    "source/common/dmtbdump1.c",
+    "source/common/dmtbdump2.c",
+    "source/common/dmtbdump3.c",
+    "source/common/dmtbinfo.c",
+    "source/common/dmtbinfo1.c",
+    "source/common/dmtbinfo2.c",
+    "source/common/dmtbinfo3.c",
+    "source/components/dispatcher/dsargs.c",
+    "source/components/dispatcher/dscontrol.c",
+    "source/components/dispatcher/dsdebug.c",
+    "source/components/dispatcher/dsfield.c",
+    "source/components/dispatcher/dsinit.c",
+    "source/components/dispatcher/dsmethod.c",
+    "source/components/dispatcher/dsmthdat.c",
+    "source/components/dispatcher/dsobject.c",
+    "source/components/dispatcher/dsopcode.c",
+    "source/components/dispatcher/dspkginit.c",
+    "source/components/dispatcher/dsutils.c",
+    "source/components/dispatcher/dswexec.c",
+    "source/components/dispatcher/dswload.c",
+    "source/components/dispatcher/dswload2.c",
+    "source/components/dispatcher/dswscope.c",
+    "source/components/dispatcher/dswstate.c",
+    "source/components/events/evevent.c",
+    "source/components/events/evglock.c",
+    "source/components/events/evgpe.c",
+    "source/components/events/evgpeblk.c",
+    "source/components/events/evgpeinit.c",
+    "source/components/events/evgpeutil.c",
+    "source/components/events/evhandler.c",
+    "source/components/events/evmisc.c",
+    "source/components/events/evregion.c",
+    "source/components/events/evrgnini.c",
+    "source/components/events/evsci.c",
+    "source/components/events/evxface.c",
+    "source/components/events/evxfevnt.c",
+    "source/components/events/evxfgpe.c",
+    "source/components/events/evxfregn.c",
+    "source/components/executer/exconcat.c",
+    "source/components/executer/exconfig.c",
+    "source/components/executer/exconvrt.c",
+    "source/components/executer/excreate.c",
+    "source/components/executer/exdebug.c",
+    "source/components/executer/exdump.c",
+    "source/components/executer/exfield.c",
+    "source/components/executer/exfldio.c",
+    "source/components/executer/exmisc.c",
+    "source/components/executer/exmutex.c",
+    "source/components/executer/exnames.c",
+    "source/components/executer/exoparg1.c",
+    "source/components/executer/exoparg2.c",
+    "source/components/executer/exoparg3.c",
+    "source/components/executer/exoparg6.c",
+    "source/components/executer/exprep.c",
+    "source/components/executer/exregion.c",
+    "source/components/executer/exresnte.c",
+    "source/components/executer/exresolv.c",
+    "source/components/executer/exresop.c",
+    "source/components/executer/exserial.c",
+    "source/components/executer/exstore.c",
+    "source/components/executer/exstoren.c",
+    "source/components/executer/exstorob.c",
+    "source/components/executer/exsystem.c",
+    "source/components/executer/extrace.c",
+    "source/components/executer/exutils.c",
+    "source/components/hardware/hwacpi.c",
+    "source/components/hardware/hwesleep.c",
+    "source/components/hardware/hwgpe.c",
+    "source/components/hardware/hwpci.c",
+    "source/components/hardware/hwregs.c",
+    "source/components/hardware/hwsleep.c",
+    "source/components/hardware/hwtimer.c",
+    "source/components/hardware/hwvalid.c",
+    "source/components/hardware/hwxface.c",
+    "source/components/hardware/hwxfsleep.c",
+    "source/components/namespace/nsaccess.c",
+    "source/components/namespace/nsalloc.c",
+    "source/components/namespace/nsarguments.c",
+    "source/components/namespace/nsconvert.c",
+    "source/components/namespace/nsdump.c",
+    "source/components/namespace/nsdumpdv.c",
+    "source/components/namespace/nseval.c",
+    "source/components/namespace/nsinit.c",
+    "source/components/namespace/nsload.c",
+    "source/components/namespace/nsnames.c",
+    "source/components/namespace/nsobject.c",
+    "source/components/namespace/nsparse.c",
+    "source/components/namespace/nspredef.c",
+    "source/components/namespace/nsprepkg.c",
+    "source/components/namespace/nsrepair.c",
+    "source/components/namespace/nsrepair2.c",
+    "source/components/namespace/nssearch.c",
+    "source/components/namespace/nsutils.c",
+    "source/components/namespace/nswalk.c",
+    "source/components/namespace/nsxfeval.c",
+    "source/components/namespace/nsxfname.c",
+    "source/components/namespace/nsxfobj.c",
+    "source/components/parser/psargs.c",
+    "source/components/parser/psloop.c",
+    "source/components/parser/psobject.c",
+    "source/components/parser/psopcode.c",
+    "source/components/parser/psopinfo.c",
+    "source/components/parser/psparse.c",
+    "source/components/parser/psscope.c",
+    "source/components/parser/pstree.c",
+    "source/components/parser/psutils.c",
+    "source/components/parser/pswalk.c",
+    "source/components/parser/psxface.c",
+    "source/components/resources/rsaddr.c",
+    "source/components/resources/rscalc.c",
+    "source/components/resources/rscreate.c",
+    "source/components/resources/rsdumpinfo.c",
+    "source/components/resources/rsinfo.c",
+    "source/components/resources/rsio.c",
+    "source/components/resources/rsirq.c",
+    "source/components/resources/rslist.c",
+    "source/components/resources/rsmemory.c",
+    "source/components/resources/rsmisc.c",
+    "source/components/resources/rsserial.c",
+    "source/components/resources/rsutils.c",
+    "source/components/resources/rsxface.c",
+    "source/components/tables/tbdata.c",
+    "source/components/tables/tbfadt.c",
+    "source/components/tables/tbfind.c",
+    "source/components/tables/tbinstal.c",
+    "source/components/tables/tbprint.c",
+    "source/components/tables/tbutils.c",
+    "source/components/tables/tbxface.c",
+    "source/components/tables/tbxfload.c",
+    "source/components/tables/tbxfroot.c",
+    "source/components/utilities/utaddress.c",
+    "source/components/utilities/utalloc.c",
+    "source/components/utilities/utascii.c",
+    "source/components/utilities/utbuffer.c",
+    "source/components/utilities/utcache.c",
+    "source/components/utilities/utclib.c",
+    "source/components/utilities/utcopy.c",
+    "source/components/utilities/utdebug.c",
+    "source/components/utilities/utdecode.c",
+    "source/components/utilities/utdelete.c",
+    "source/components/utilities/uterror.c",
+    "source/components/utilities/uteval.c",
+    "source/components/utilities/utexcep.c",
+    "source/components/utilities/utglobal.c",
+    "source/components/utilities/uthex.c",
+    "source/components/utilities/utids.c",
+    "source/components/utilities/utinit.c",
+    "source/components/utilities/utlock.c",
+    "source/components/utilities/utmath.c",
+    "source/components/utilities/utmisc.c",
+    "source/components/utilities/utmutex.c",
+    "source/components/utilities/utnonansi.c",
+    "source/components/utilities/utobject.c",
+    "source/components/utilities/utosi.c",
+    "source/components/utilities/utownerid.c",
+    "source/components/utilities/utpredef.c",
+    "source/components/utilities/utresdecode.c",
+    "source/components/utilities/utresrc.c",
+    "source/components/utilities/utstate.c",
+    "source/components/utilities/utstring.c",
+    "source/components/utilities/utstrsuppt.c",
+    "source/components/utilities/utstrtoul64.c",
+    "source/components/utilities/uttrack.c",
+    "source/components/utilities/utuuid.c",
+    "source/components/utilities/utxface.c",
+    "source/components/utilities/utxferror.c",
+    "source/components/utilities/utxfinit.c",
+    "source/components/utilities/utxfmutex.c",
+  ]
+  deps = [
+    "//zircon/public/lib/ddk",
+    "//zircon/public/lib/fbl",
+    "//zircon/public/lib/pci",
+    "//zircon/public/lib/zircon-internal",
+  ]
+  defines = [ "_ALL_SOURCE" ]
+  if (acpica_debug_output) {
+    defines += [ "ACPI_DEBUG_OUTPUT" ]
+  }
+
+  # TODO(41663): UBSan has found an instance of undefined behavior in this target.
+  # Disable UBSan for this target temporarily until it is migrated into CI/CQ.
+  if (!is_gcc) {
+    cflags += [ "-fno-sanitize=undefined" ]
+  }
+}
diff --git a/README.fuchsia b/README.fuchsia
index 8494a16..3527f99 100644
--- a/README.fuchsia
+++ b/README.fuchsia
@@ -6,3 +6,13 @@
 - Added README.fuchsia
 - Removed optional GPL license banner from sources
 - Added LICENSE containing copy of source license banner
+- Added BUILD.gn
+- Added symlink to wrap source/include as include/acpica
+- Added source/include/platform/acfuchsia.h
+- Modified source/include/platform/acenv.h to use aczircon.h/acfuchsia.h
+- Wrapped source/include/acpica/acpi.h with __BEGIN_CDECLS/__END_CDECLS
+- Modified AcpiHwLegacySleep to extract out a subfunction AcpiHwLegacySleepFinal (needed
+  for Zircon suspend-to-RAM support).
+- Fix instances of undefined behavior reported by UBSan (misaligned pointer
+  accesses, member accesses on nullptrs, and left shifting by 31 on ints)
+- Added workaround for use-after-free on NuC in AcpiNsTerminate
diff --git a/include/acpica b/include/acpica
new file mode 120000
index 0000000..c492e01
--- /dev/null
+++ b/include/acpica
@@ -0,0 +1 @@
+../source/include/
\ No newline at end of file
diff --git a/source/components/hardware/hwsleep.c b/source/components/hardware/hwsleep.c
index d96b57d..b3e7097 100644
--- a/source/components/hardware/hwsleep.c
+++ b/source/components/hardware/hwsleep.c
@@ -41,6 +41,8 @@
 #include "acpi.h"
 #include "accommon.h"
 
+#include <zircon/syscalls/system.h>
+
 #define _COMPONENT          ACPI_HARDWARE
         ACPI_MODULE_NAME    ("hwsleep")
 
@@ -65,9 +67,6 @@
 {
     ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
     ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
-    UINT32                  Pm1aControl;
-    UINT32                  Pm1bControl;
-    UINT32                  InValue;
     ACPI_STATUS             Status;
 
 
@@ -108,6 +107,53 @@
         return_ACPI_STATUS (Status);
     }
 
+    /* The upstream ACPICA code expects that AcpiHwLegacySleep() is invoked with interrupts
+    /* disabled.  It requires this because the last steps of going to sleep is writing to a few
+    /* registers, flushing the caches (so we don't lose data if the caches are dropped), and then
+    /* writing to a register to enter the sleep.  If we were to take an interrupt after the cache
+    /* flush but before entering sleep, we could have inconsistent memory after waking up.*/
+
+    /* In Fuchsia, ACPICA runs in usermode and we don't expose a mechanism for it to disable
+    /* interrupts.  To ensure a consistent sleep, we split AcpiHwLegacySleep into two parts, the
+    /* part that doesn't need interrupts disabled, and then the final part (AcpiHwLegacySleepFinal)
+    /* that does.  We execute the first half in usermode, and then make a syscall into the kernel to
+    /* execute the final steps. */
+
+#if defined(__Fuchsia__) && !defined(_KERNEL)
+    extern zx_handle_t get_root_resource(void);
+
+    zx_system_powerctl_arg_t arg;
+    arg.acpi_transition_s_state.target_s_state = SleepState;
+    arg.acpi_transition_s_state.sleep_type_a = AcpiGbl_SleepTypeA;
+    arg.acpi_transition_s_state.sleep_type_b = AcpiGbl_SleepTypeB;
+    zx_status_t zx_status = zx_system_powerctl(get_root_resource(),
+                                               ZX_SYSTEM_POWERCTL_ACPI_TRANSITION_S_STATE,
+                                               &arg);
+    if (zx_status == ZX_OK) {
+        Status = AE_OK;
+    } else {
+        Status = AE_ERROR;
+    }
+#else
+    Status = AcpiHwLegacySleepFinal(SleepState, AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB);
+#endif
+    return_ACPI_STATUS (Status);
+}
+
+ACPI_STATUS
+AcpiHwLegacySleepFinal(UINT8 SleepState, UINT8 SleepTypeA, UINT8 SleepTypeB) {
+    ACPI_STATUS             Status;
+    UINT32                  Pm1aControl;
+    UINT32                  Pm1bControl;
+    UINT32                  InValue;
+    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
+    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
+
+    ACPI_FUNCTION_TRACE (HwLegacySleepFinal);
+
+    SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
+    SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
+
     /* Get current value of PM1A control */
 
     Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL,
diff --git a/source/components/namespace/nsutils.c b/source/components/namespace/nsutils.c
index 8c2b7b8..51004de 100644
--- a/source/components/namespace/nsutils.c
+++ b/source/components/namespace/nsutils.c
@@ -694,6 +694,46 @@
 
     ACPI_FUNCTION_TRACE (NsTerminate);
 
+    {
+        /* Prior to deleting the entire namespace we want to manually check for and delete some top
+         * level nodes. On some NuC devices, these nodes are mistakenly placed under the root,
+         * despite referencing regions in a different sub tree. This results in a use after free
+         * due to the sub tree being deleted before these root level objects.
+         * This is described in the github issue https://github.com/acpica/acpica/issues/416
+         * There is no correctness requirement to deleting the tree in any particular order,
+         * AcpiNsDeleteNamespaceSubtree is simply doing the most optimal traversal. Therefore if we
+         * are not on a NuC and manage to find these nodes there is no harm to performing this early
+         * deletion.
+         * TODO(32590)
+         */
+        const char *EarlyDeleteList[] = {
+          "\\CARN",
+          "\\CBDR",
+          "\\LTDR",
+          "\\FDDR",
+          "\\CALE",
+          "\\CBLE",
+          "\\LTLE",
+          "\\FDLE",
+          "\\GLLE",
+          "\\GHLE",
+          "\\KCLE",
+          "\\MCLE",
+          "\\C1LE",
+          "\\C2LE",
+          NULL,
+        };
+        int Index;
+        for (Index = 0; EarlyDeleteList[Index] != NULL; Index++) {
+            ACPI_NAMESPACE_NODE *Node;
+            Status = AcpiNsGetNode(AcpiGbl_RootNode, EarlyDeleteList[Index], ACPI_NS_NO_UPSEARCH, &Node);
+            if (Status == AE_OK) {
+                AcpiNsDeleteChildren(Node);
+                AcpiUtRemoveReference(Node->Object);
+                AcpiNsRemoveNode(Node);
+            }
+        }
+    }
 
     /*
      * Free the entire namespace -- all nodes and all objects
diff --git a/source/components/resources/rsaddr.c b/source/components/resources/rsaddr.c
index cc98a67..2f08732 100644
--- a/source/components/resources/rsaddr.c
+++ b/source/components/resources/rsaddr.c
@@ -324,8 +324,15 @@
 
     /* Validate the Resource Type */
 
-    if ((Aml->Address.ResourceType > 2) &&
-        (Aml->Address.ResourceType < 0xC0))
+    // Copy the value using memcpy() to safely access a misaligned pointer.
+    // We explicitely cast to AML_RESOURCE_ADDRESS instead of using
+    // `&Aml->Address` because the latter still results in a misaligned access
+    // that UBSan catches. We can safely do this cast since AML_RESOURCE is a
+    // union.
+    UINT8 ResourceType;
+    memcpy(&ResourceType, &((AML_RESOURCE_ADDRESS *)Aml)->ResourceType,
+           sizeof(ResourceType));
+    if (ResourceType > 2 && ResourceType < 0xC0)
     {
         return (FALSE);
     }
diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c
index 39bf181..18fff11 100644
--- a/source/components/tables/tbutils.c
+++ b/source/components/tables/tbutils.c
@@ -224,8 +224,11 @@
          * 32-bit platform, RSDT: Return 32-bit table entry
          * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
          */
-        return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (
-            UINT32, TableEntry)));
+        // Copy the value using memcpy() to safely handle a load on a misaligned
+        // pointer.
+        UINT32 result;
+        ACPI_MOVE_32_TO_32(&result, TableEntry);
+        return result;
     }
     else
     {
diff --git a/source/include/achware.h b/source/include/achware.h
index 51186b7..1396c3a 100644
--- a/source/include/achware.h
+++ b/source/include/achware.h
@@ -113,6 +113,9 @@
     UINT8                   SleepState);
 
 ACPI_STATUS
+AcpiHwLegacySleepFinal(UINT8 SleepState, UINT8 SleepTypeA, UINT8 SleepTypeB);
+
+ACPI_STATUS
 AcpiHwLegacyWakePrep (
     UINT8                   SleepState);
 
diff --git a/source/include/acpi.h b/source/include/acpi.h
index 1418d13..dc025b8 100644
--- a/source/include/acpi.h
+++ b/source/include/acpi.h
@@ -50,6 +50,8 @@
  * Note: The order of these include files is important.
  */
 #include "platform/acenv.h"     /* Environment-specific items */
+__BEGIN_CDECLS
+
 #include "actypes.h"            /* ACPICA data types and structures */
 #include "platform/acenvex.h"   /* Extra environment-specific items */
 #include "acnames.h"            /* Common ACPI names and strings */
@@ -59,5 +61,6 @@
 #include "acrestyp.h"           /* Resource Descriptor structs */
 #include "acpiosxf.h"           /* OSL interfaces (ACPICA-to-OS) */
 #include "acpixf.h"             /* ACPI core subsystem external interfaces */
+__END_CDECLS
 
 #endif /* __ACPI_H__ */
diff --git a/source/include/actypes.h b/source/include/actypes.h
index 803fd47..a8f5c6b 100644
--- a/source/include/actypes.h
+++ b/source/include/actypes.h
@@ -547,7 +547,9 @@
 
 #define ACPI_TO_POINTER(i)              ACPI_CAST_PTR (void, (ACPI_SIZE) (i))
 #define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p, (void *) 0)
-#define ACPI_OFFSET(d, f)               ACPI_PTR_DIFF (&(((d *) 0)->f), (void *) 0)
+// Use offsetof() to avoid taking the offset of a nullptr, which is undefined
+// behavior.
+#define ACPI_OFFSET(d, f)               offsetof(d, f)
 #define ACPI_PHYSADDR_TO_PTR(i)         ACPI_TO_POINTER(i)
 #define ACPI_PTR_TO_PHYSADDR(i)         ACPI_TO_INTEGER(i)
 
diff --git a/source/include/platform/acenv.h b/source/include/platform/acenv.h
index a650736..ee737a6 100644
--- a/source/include/platform/acenv.h
+++ b/source/include/platform/acenv.h
@@ -238,6 +238,9 @@
 #elif defined(__QNX__)
 #include "acqnx.h"
 
+#elif defined(__Fuchsia__)
+#include "acfuchsia.h"
+
 /*
  * EFI applications can be built with -nostdlib, in this case, it must be
  * included after including all other host environmental definitions, in
diff --git a/source/include/platform/acfuchsia.h b/source/include/platform/acfuchsia.h
new file mode 100644
index 0000000..6379cb3
--- /dev/null
+++ b/source/include/platform/acfuchsia.h
@@ -0,0 +1,64 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <stdbool.h>
+#include <threads.h>
+
+#include <zircon/assert.h>
+#include <zircon/syscalls.h>
+#include <semaphore.h>
+
+/*
+ * Settings described in section 7 of
+ * https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
+ */
+
+
+#if __x86_64__
+#define ACPI_MACHINE_WIDTH 64
+#elif __x86__
+#define ACPI_MACHINE_WIDTH 32
+#define ACPI_USE_NATIVE_DIVIDE
+#else
+#error Unexpected architecture
+#endif
+
+extern zx_handle_t root_resource_handle;
+
+// Make this a no-op.  The only codepath we use it for is ACPI poweroff, in
+// which case we don't care about the cache state.
+#define ACPI_FLUSH_CPU_CACHE()
+
+// Use the standard library headers
+#define ACPI_USE_STANDARD_HEADERS
+#define ACPI_USE_SYSTEM_CLIBRARY
+
+// Use the builtin cache implementation
+#define ACPI_USE_LOCAL_CACHE
+
+#define ACPI_MUTEX_TYPE     ACPI_OSL_MUTEX
+
+// Specify the types Fuchsia uses for various common objects
+#define ACPI_CPU_FLAGS int
+#define ACPI_SPINLOCK mtx_t*
+#define ACPI_MUTEX mtx_t*
+#define ACPI_SEMAPHORE sem_t*
+
+// Borrowed from aclinuxex.h
+
+// Include the gcc header since we're compiling on gcc
+#include "acgcc.h"
+
+__BEGIN_CDECLS
+bool _acpica_acquire_global_lock(void *FacsPtr);
+bool _acpica_release_global_lock(void *FacsPtr);
+
+void acpica_enable_noncontested_mode(void);
+void acpica_disable_noncontested_mode(void);
+__END_CDECLS
+
+#define ACPI_ACQUIRE_GLOBAL_LOCK(FacsPtr, Acq) Acq = _acpica_acquire_global_lock(FacsPtr)
+#define ACPI_RELEASE_GLOBAL_LOCK(FacsPtr, Pnd) Pnd = _acpica_release_global_lock(FacsPtr)