Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Dec 2017 02:49:12 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r326956 - head/sys/dev/acpica
Message-ID:  <201712190249.vBJ2nCeO052965@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Tue Dec 19 02:49:11 2017
New Revision: 326956
URL: https://svnweb.freebsd.org/changeset/base/326956

Log:
  Implement ACPI CPU support when Processor object is not present
  
  By the ACPI standard (ACPI 5 chapter 8.4 Declaring Processors) Processors
  can be implemented in 2 distinct ways:
  
  * Through a Processor object type (which provides P_BLK)
  * Through a Device object type
  
  Prior to this change, the FreeBSD driver only supported the former.  AMD
  Epyc / Poweredge systems we are testing both implement the latter only.  Add
  the missing support.
  
  Because P_BLK is not defined in the device object case, C-states entering
  must be completely controlled via _CST methods rather than P_LVL2/3.
  
  John Baldwin points out that ACPI 6.0 formally deprecates the Processor
  keyword, so eventually processors will only be enumerated as Device objects.
  
  Submitted by:	attilio
  Reviewed by:	jhb, markj, Anton Rang <rang AT acm.org>
  Relnotes:	maybe
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D13457

Modified:
  head/sys/dev/acpica/acpi_cpu.c

Modified: head/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- head/sys/dev/acpica/acpi_cpu.c	Tue Dec 19 01:02:58 2017	(r326955)
+++ head/sys/dev/acpica/acpi_cpu.c	Tue Dec 19 02:49:11 2017	(r326956)
@@ -140,6 +140,8 @@ struct acpi_cpu_device {
 #define	CST_FFH_MWAIT_HW_COORD	0x0001
 #define	CST_FFH_MWAIT_BM_AVOID	0x0002
 
+#define	CPUDEV_DEVICE_ID	"ACPI0007"
+
 /* Allow users to ignore processor orders in MADT. */
 static int cpu_unordered;
 SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN,
@@ -236,44 +238,61 @@ MODULE_DEPEND(cpu, acpi, 1, 1, 1);
 static int
 acpi_cpu_probe(device_t dev)
 {
+    static char		   *cpudev_ids[] = { CPUDEV_DEVICE_ID, NULL };
     int			   acpi_id, cpu_id;
     ACPI_BUFFER		   buf;
     ACPI_HANDLE		   handle;
     ACPI_OBJECT		   *obj;
     ACPI_STATUS		   status;
+    ACPI_OBJECT_TYPE	   type;
 
-    if (acpi_disabled("cpu") || acpi_get_type(dev) != ACPI_TYPE_PROCESSOR ||
-	    acpi_cpu_disabled)
+    if (acpi_disabled("cpu") || acpi_cpu_disabled)
 	return (ENXIO);
+    type = acpi_get_type(dev);
+    if (type != ACPI_TYPE_PROCESSOR && type != ACPI_TYPE_DEVICE)
+	return (ENXIO);
+    if (type == ACPI_TYPE_DEVICE &&
+	ACPI_ID_PROBE(device_get_parent(dev), dev, cpudev_ids) == NULL)
+	return (ENXIO);
 
     handle = acpi_get_handle(dev);
     if (cpu_softc == NULL)
 	cpu_softc = malloc(sizeof(struct acpi_cpu_softc *) *
 	    (mp_maxid + 1), M_TEMP /* XXX */, M_WAITOK | M_ZERO);
 
-    /* Get our Processor object. */
-    buf.Pointer = NULL;
-    buf.Length = ACPI_ALLOCATE_BUFFER;
-    status = AcpiEvaluateObject(handle, NULL, NULL, &buf);
-    if (ACPI_FAILURE(status)) {
-	device_printf(dev, "probe failed to get Processor obj - %s\n",
-		      AcpiFormatException(status));
-	return (ENXIO);
-    }
-    obj = (ACPI_OBJECT *)buf.Pointer;
-    if (obj->Type != ACPI_TYPE_PROCESSOR) {
-	device_printf(dev, "Processor object has bad type %d\n", obj->Type);
+    if (type == ACPI_TYPE_PROCESSOR) {
+	/* Get our Processor object. */
+	buf.Pointer = NULL;
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	status = AcpiEvaluateObject(handle, NULL, NULL, &buf);
+	if (ACPI_FAILURE(status)) {
+	    device_printf(dev, "probe failed to get Processor obj - %s\n",
+		AcpiFormatException(status));
+	    return (ENXIO);
+	}
+	obj = (ACPI_OBJECT *)buf.Pointer;
+	if (obj->Type != ACPI_TYPE_PROCESSOR) {
+	    device_printf(dev, "Processor object has bad type %d\n",
+		obj->Type);
+	    AcpiOsFree(obj);
+	    return (ENXIO);
+	}
+
+	/*
+	 * Find the processor associated with our unit.  We could use the
+	 * ProcId as a key, however, some boxes do not have the same values
+	 * in their Processor object as the ProcId values in the MADT.
+	 */
+	acpi_id = obj->Processor.ProcId;
 	AcpiOsFree(obj);
-	return (ENXIO);
+    } else {
+	status = acpi_GetInteger(handle, "_UID", &acpi_id);
+	if (ACPI_FAILURE(status)) {
+	    device_printf(dev, "Device object has bad value - %s\n",
+		AcpiFormatException(status));
+	    return (ENXIO);
+	}
     }
-
-    /*
-     * Find the processor associated with our unit.  We could use the
-     * ProcId as a key, however, some boxes do not have the same values
-     * in their Processor object as the ProcId values in the MADT.
-     */
-    acpi_id = obj->Processor.ProcId;
-    AcpiOsFree(obj);
     if (acpi_pcpu_get_id(dev, &acpi_id, &cpu_id) != 0)
 	return (ENXIO);
 
@@ -325,19 +344,32 @@ acpi_cpu_attach(device_t dev)
     cpu_smi_cmd = AcpiGbl_FADT.SmiCommand;
     cpu_cst_cnt = AcpiGbl_FADT.CstControl;
 
-    buf.Pointer = NULL;
-    buf.Length = ACPI_ALLOCATE_BUFFER;
-    status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf);
-    if (ACPI_FAILURE(status)) {
-	device_printf(dev, "attach failed to get Processor obj - %s\n",
-		      AcpiFormatException(status));
-	return (ENXIO);
+    if (acpi_get_type(dev) == ACPI_TYPE_PROCESSOR) {
+	buf.Pointer = NULL;
+	buf.Length = ACPI_ALLOCATE_BUFFER;
+	status = AcpiEvaluateObject(sc->cpu_handle, NULL, NULL, &buf);
+	if (ACPI_FAILURE(status)) {
+	    device_printf(dev, "attach failed to get Processor obj - %s\n",
+		AcpiFormatException(status));
+	    return (ENXIO);
+	}
+	obj = (ACPI_OBJECT *)buf.Pointer;
+	sc->cpu_p_blk = obj->Processor.PblkAddress;
+	sc->cpu_p_blk_len = obj->Processor.PblkLength;
+	sc->cpu_acpi_id = obj->Processor.ProcId;
+	AcpiOsFree(obj);
+    } else {
+	KASSERT(acpi_get_type(dev) == ACPI_TYPE_DEVICE,
+	    ("Unexpected ACPI object"));
+	status = acpi_GetInteger(sc->cpu_handle, "_UID", &sc->cpu_acpi_id);
+	if (ACPI_FAILURE(status)) {
+	    device_printf(dev, "Device object has bad value - %s\n",
+		AcpiFormatException(status));
+	    return (ENXIO);
+	}
+	sc->cpu_p_blk = 0;
+	sc->cpu_p_blk_len = 0;
     }
-    obj = (ACPI_OBJECT *)buf.Pointer;
-    sc->cpu_p_blk = obj->Processor.PblkAddress;
-    sc->cpu_p_blk_len = obj->Processor.PblkLength;
-    sc->cpu_acpi_id = obj->Processor.ProcId;
-    AcpiOsFree(obj);
     ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_cpu%d: P_BLK at %#x/%d\n",
 		     device_get_unit(dev), sc->cpu_p_blk, sc->cpu_p_blk_len));
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712190249.vBJ2nCeO052965>