From 2b781bd69aa2568ff754cc1b74ea236f46429568 Mon Sep 17 00:00:00 2001
From: Roger Pau Monne <roger.pau@citrix.com>
Date: Thu, 19 Jun 2014 13:05:56 +0200
Subject: [PATCH v5 09/29] xen: add ACPI bus to xen_nexus when running as Dom0

Also disable a couple of ACPI devices that are not usable under Dom0,
to this end a couple of booleans are added that allow disabling ACPI
specific devices.

Sponsored by: Citrix Systems R&D
Reviewed by: xxx
Approved by: xxx

x86/xen/xen_nexus.c:
 - Return BUS_PROBE_SPECIFIC in the Xen Nexus attachement routine to
   force the usage of the Xen Nexus.
 - Attach the ACPI bus when running as Dom0.

dev/acpica/acpi_cpu.c:
dev/acpica/acpi_hpet.c:
dev/acpica/acpi_timer.c
 - Add a variable that gates the addition of the devices.

x86/include/init.h:
 - Declare variables that control the attachment of ACPI cpu, hpet and
   timer devices.
---
 sys/dev/acpica/acpi_cpu.c   |    6 +++++-
 sys/dev/acpica/acpi_hpet.c  |    5 ++++-
 sys/dev/acpica/acpi_timer.c |    5 ++++-
 sys/x86/include/init.h      |    9 +++++++++
 sys/x86/xen/xen_nexus.c     |   25 +++++++++++++++++++++++--
 5 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index f95510c..776877a 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -134,6 +134,9 @@ SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN,
     &cpu_unordered, 0,
     "Do not use the MADT to match ACPI Processor objects to CPUs.");
 
+/* Knob to disable acpi_cpu devices */
+bool acpi_cpu_disabled = false;
+
 /* Platform hardware resource information. */
 static uint32_t		 cpu_smi_cmd;	/* Value to write to SMI_CMD. */
 static uint8_t		 cpu_cst_cnt;	/* Indicate we are _CST aware. */
@@ -221,7 +224,8 @@ acpi_cpu_probe(device_t dev)
     ACPI_OBJECT		   *obj;
     ACPI_STATUS		   status;
 
-    if (acpi_disabled("cpu") || acpi_get_type(dev) != ACPI_TYPE_PROCESSOR)
+    if (acpi_disabled("cpu") || acpi_get_type(dev) != ACPI_TYPE_PROCESSOR ||
+	    acpi_cpu_disabled)
 	return (ENXIO);
 
     handle = acpi_get_handle(dev);
diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c
index 4d600f5..cd8dcef 100644
--- a/sys/dev/acpica/acpi_hpet.c
+++ b/sys/dev/acpica/acpi_hpet.c
@@ -113,6 +113,9 @@ static void hpet_test(struct hpet_softc *sc);
 
 static char *hpet_ids[] = { "PNP0103", NULL };
 
+/* Knob to disable acpi_hpet device */
+bool acpi_hpet_disabled = false;
+
 static u_int
 hpet_get_timecount(struct timecounter *tc)
 {
@@ -360,7 +363,7 @@ hpet_probe(device_t dev)
 {
 	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
 
-	if (acpi_disabled("hpet"))
+	if (acpi_disabled("hpet") || acpi_hpet_disabled)
 		return (ENXIO);
 	if (acpi_get_handle(dev) != NULL &&
 	    ACPI_ID_PROBE(device_get_parent(dev), dev, hpet_ids) == NULL)
diff --git a/sys/dev/acpica/acpi_timer.c b/sys/dev/acpica/acpi_timer.c
index b974f1f..03ef686 100644
--- a/sys/dev/acpica/acpi_timer.c
+++ b/sys/dev/acpica/acpi_timer.c
@@ -65,6 +65,9 @@ static eventhandler_tag		acpi_timer_eh;
 
 static u_int	acpi_timer_frequency = 14318182 / 4;
 
+/* Knob to disable acpi_timer device */
+bool acpi_timer_disabled = false;
+
 static void	acpi_timer_identify(driver_t *driver, device_t parent);
 static int	acpi_timer_probe(device_t dev);
 static int	acpi_timer_attach(device_t dev);
@@ -125,7 +128,7 @@ acpi_timer_identify(driver_t *driver, device_t parent)
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
     if (acpi_disabled("timer") || (acpi_quirks & ACPI_Q_TIMER) ||
-	acpi_timer_dev)
+	acpi_timer_dev || acpi_timer_disabled)
 	return_VOID;
 
     if ((dev = BUS_ADD_CHILD(parent, 2, "acpi_timer", 0)) == NULL) {
diff --git a/sys/x86/include/init.h b/sys/x86/include/init.h
index e1ff5cf..47dc4f5 100644
--- a/sys/x86/include/init.h
+++ b/sys/x86/include/init.h
@@ -45,4 +45,13 @@ struct init_ops {
 
 extern struct init_ops init_ops;
 
+/* Knob to disable acpi_cpu devices */
+extern bool acpi_cpu_disabled;
+
+/* Knob to disable acpi_hpet device */
+extern bool acpi_hpet_disabled;
+
+/* Knob to disable acpi_timer device */
+extern bool acpi_timer_disabled;
+
 #endif /* __X86_INIT_H__ */
diff --git a/sys/x86/xen/xen_nexus.c b/sys/x86/xen/xen_nexus.c
index bf98ca2..e51e3eb 100644
--- a/sys/x86/xen/xen_nexus.c
+++ b/sys/x86/xen/xen_nexus.c
@@ -35,6 +35,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/smp.h>
 
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+#include <x86/init.h>
 #include <machine/nexusvar.h>
 #include <machine/intr_machdep.h>
 
@@ -51,16 +56,32 @@ nexus_xen_probe(device_t dev)
 	if (!xen_pv_domain())
 		return (ENXIO);
 
-	return (BUS_PROBE_DEFAULT);
+	return (BUS_PROBE_SPECIFIC);
 }
 
 static int
 nexus_xen_attach(device_t dev)
 {
+	int error = 0;
+	device_t acpi_dev;
 
 	nexus_init_resources();
 	bus_generic_probe(dev);
-	bus_generic_attach(dev);
+
+	if (xen_initial_domain()) {
+		/* Disable some ACPI devices that are not usable by Dom0 */
+		acpi_cpu_disabled = true;
+		acpi_hpet_disabled = true;
+		acpi_timer_disabled = true;
+
+		acpi_dev = BUS_ADD_CHILD(dev, 10, "acpi", 0);
+		if (acpi_dev == NULL)
+			panic("Unable to add ACPI bus to Xen Dom0");
+	}
+
+	error = bus_generic_attach(dev);
+	if (xen_initial_domain() && (error == 0))
+		acpi_install_wakeup_handler(device_get_softc(acpi_dev));
 
 	return (0);
 }
-- 
1.7.7.5 (Apple Git-26)

