From 45abee08f2fb85ee8e96f082cb50d6aa58ba69e5 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Thu, 26 Oct 2017 17:48:17 +0200
Subject: [PATCH] WIP

---
 sys/dev/acpica/acpi.c           | 30 ++++++++++++++++++++++++++----
 sys/dev/acpica/acpi_cpu.c       |  2 +-
 sys/dev/acpica/acpi_pcib_acpi.c | 15 +++++++++++++++
 sys/dev/acpica/acpivar.h        | 29 ++++++++++++++++++-----------
 4 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index ad19a68d99..975536d3a4 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -60,6 +60,7 @@
 #include "achware.h"
 #include "acnamesp.h"
 #include "acglobal.h"
+#include "acuuid.h"
 
 #include "pci_if.h"
 #include <bus/pci/pci_cfgreg.h>
@@ -480,6 +481,8 @@ acpi_attach(device_t dev)
     UINT32		flags;
     UINT8		TypeA, TypeB;
     char		*env;
+    uint32_t		cap_set[2];
+    ACPI_HANDLE		sb_handle;
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
@@ -594,6 +597,21 @@ acpi_attach(device_t dev)
 	goto out;
     }
 
+    if (ACPI_SUCCESS(AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &sb_handle))) {
+	cap_set[0] = ACPI_OSC_QUERY_SUPPORT;
+	cap_set[1] = 0x000007ff;
+	status =
+	    acpi_eval_osc(dev, sb_handle, UUID_PLATFORM_CAPABILITIES, 1,
+		cap_set, 2);
+	if (ACPI_FAILURE(status)) {
+	    if (bootverbose)
+		device_printf(dev, "platform-wide _OSC failed\n");
+	} else {
+	    device_printf(dev, "cap_set[0]:%#x cap_set[1]:%#x\n",
+		cap_set[0], cap_set[1]);
+	}
+    }
+
     /*
      * Setup our sysctl tree.
      *
@@ -1299,15 +1317,15 @@ acpi_eval_osc(device_t dev, ACPI_HANDLE handle, const char *uuidstr,
     if (ACPI_FAILURE(status))
 	goto done;
     retobj = retbuf.Pointer;
-    error = ((uint32_t *)retobj->Buffer.Pointer)[0] & ACPI_OSCERR_MASK;
+    error = ((uint32_t *)retobj->Buffer.Pointer)[0] & ACPI_OSC_ERRMASK;
     if (error == 0)
 	goto done;
     status = AE_ERROR;
-    if (error & ACPI_OSCERR_OSCFAIL)
+    if (error & ACPI_OSCERR_FAILURE)
 	device_printf(dev, "_OSC unable to process request\n");
-    if (error & ACPI_OSCERR_UUID)
+    if (error & ACPI_OSCERR_BADUUID)
 	device_printf(dev, "_OSC unrecognized UUID (%s)\n", uuidstr);
-    if (error & ACPI_OSCERR_REVISION)
+    if (error & ACPI_OSCERR_BADREV)
 	device_printf(dev, "_OSC unrecognized revision ID (%d)\n", revision);
     if (error & ACPI_OSCERR_CAPSMASKED) {
 	if ((buf[0] & ACPI_OSC_QUERY_SUPPORT) == 0) {
@@ -1322,6 +1340,10 @@ acpi_eval_osc(device_t dev, ACPI_HANDLE handle, const char *uuidstr,
 	}
     }
 
+    if (buf[0] & ACPI_OSC_QUERY_SUPPORT) {
+	    for (i = 0; i < count; i++)
+		    buf[i] = ((uint32_t *)retobj->Buffer.Pointer)[i];
+    }
 done:
     if (retbuf.Pointer != NULL)
 	AcpiOsFree(retbuf.Pointer);
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index aa4136d4d2..70556e42e4 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -214,7 +214,7 @@ acpi_cpu_attach(device_t dev)
 	    ACPI_OBJECT arg[4];
 
 	    if (bootverbose)
-		device_printf(dev, "_OSC failed, using _PDC\n");
+		device_printf(dev, "Intel CPU _OSC failed, using _PDC\n");
 
 	    arglist.Pointer = arg;
 	    arglist.Count = 1;
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index 886d5f4a6e..2cce1c85a5 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -37,6 +37,7 @@
 #include <sys/sysctl.h>
 
 #include "acpi.h"
+#include "acuuid.h"
 #include <dev/acpica/acpivar.h>
 
 #include <bus/pci/pci_cfgreg.h>
@@ -152,6 +153,7 @@ acpi_pcib_acpi_attach(device_t dev)
     static int bus0_seen = 0;
     u_int addr, slot, func, busok;
     uint8_t busno;
+    uint32_t cap_set[3];
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
@@ -251,6 +253,19 @@ acpi_pcib_acpi_attach(device_t dev)
     if (sc->ap_segment == 0 && sc->ap_bus == 0)
 	    bus0_seen = 1;
 
+    cap_set[0] = ACPI_OSC_QUERY_SUPPORT;
+    cap_set[1] = 0x0000001f;
+    cap_set[2] = 0x0000001f;
+    status =
+	acpi_eval_osc(dev, sc->ap_handle, UUID_PCI_HOST_BRIDGE, 1, cap_set, 3);
+    if (ACPI_FAILURE(status)) {
+	if (bootverbose)
+	    device_printf(dev, "PCI host bridge _OSC failed\n");
+    } else {
+	device_printf(dev, "cap_set[0]:%#x cap_set[1]:%#x cap_set[2]:%#x\n",
+	    cap_set[0], cap_set[1], cap_set[2]);
+    }
+
     return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
 }
 
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index a9b8393da2..6d33e5bf62 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -195,10 +195,19 @@ extern struct lwkt_token acpi_token;
 #define	ACPI_INTR_SAPIC		2
 
 /*
- * Various features and capabilities for the acpi_get_features() method.
- * In particular, these are used for the ACPI 3.0 _PDC and _OSC methods.
- * See the Intel document titled "Intel Processor Vendor-Specific ACPI",
- * number 302223-005.
+ * Various features and capabilities for the acpi_eval_osc() method.
+ */
+#define	ACPI_OSC_QUERY_SUPPORT	(1 << 0) /* Query Support Flag */
+
+#define	ACPI_OSC_ERRMASK	0x0000001e
+#define	ACPI_OSCERR_FAILURE	(1 << 1) /* _OSC failure */
+#define	ACPI_OSCERR_BADUUID	(1 << 2) /* Unrecognized UUID */
+#define	ACPI_OSCERR_BADREV	(1 << 3) /* Unrecognized revision ID */
+#define	ACPI_OSCERR_CAPSMASKED	(1 << 4) /* Capabilities have been cleared */
+
+/*
+ * Intel CPU _OSC capabilities, see "Intel Processor Vendor-Specific ACPI",
+ * number 302223-007.
  */
 #define ACPI_PDC_PX_MSR		(1 << 0) /* Intel SpeedStep PERF_CTL MSRs */
 #define ACPI_PDC_MP_C1_IO_HALT	(1 << 1) /* Intel C1 "IO then halt" sequence */
@@ -212,13 +221,11 @@ extern struct lwkt_token acpi_token;
 #define ACPI_PDC_MP_C2C3_NATIVE	(1 << 9) /* MP C2 and C3 support */
 #define ACPI_PDC_PX_HWCOORD	(1 << 11)/* Hardware coordination of Px */
 
-#define ACPI_OSC_QUERY_SUPPORT	(1 << 0) /* Query Support Flag */
-
-#define ACPI_OSCERR_OSCFAIL	(1 << 1) /* _OSC failure */
-#define ACPI_OSCERR_UUID	(1 << 2) /* Unrecognized UUID */
-#define ACPI_OSCERR_REVISION	(1 << 3) /* Unrecognized revision ID */
-#define ACPI_OSCERR_CAPSMASKED	(1 << 4) /* Capabilities have been cleared */
-#define ACPI_OSCERR_MASK	0x0000001e
+/*
+ * PCI Host Bridge _OSC capabilities
+ */
+#define	ACPI_CAP_PCIB_EXTOPREG	(1 << 0) /* Extended PCI Config regions */
+#define	ACPI_CAP_PCIB_MSI	(1 << 4) /* MSI support */
 
 /*
  * Quirk flags.
-- 
2.18.0

