Module Name:    src
Committed By:   jmcneill
Date:           Mon Dec  7 10:57:41 UTC 2020

Modified Files:
        src/sys/arch/arm/acpi: files.acpi
        src/sys/arch/evbarm/conf: GENERIC64
        src/sys/dev/acpi: acpi.c acpi_cpu.c acpi_cpu.h acpi_cpu_cstate.c
            acpi_cpu_pstate.c acpi_cpu_tstate.c files.acpi
Added Files:
        src/sys/arch/arm/acpi: acpi_cpu_md.c
        src/sys/dev/acpi: acpi_pcd.c

Log Message:
acpicpu: Add support for ACPI P-states and T-states on Arm.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/acpi/acpi_cpu_md.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/acpi/files.acpi
cvs rdiff -u -r1.165 -r1.166 src/sys/arch/evbarm/conf/GENERIC64
cvs rdiff -u -r1.286 -r1.287 src/sys/dev/acpi/acpi.c
cvs rdiff -u -r1.52 -r1.53 src/sys/dev/acpi/acpi_cpu.c
cvs rdiff -u -r1.44 -r1.45 src/sys/dev/acpi/acpi_cpu.h
cvs rdiff -u -r1.62 -r1.63 src/sys/dev/acpi/acpi_cpu_cstate.c
cvs rdiff -u -r1.53 -r1.54 src/sys/dev/acpi/acpi_cpu_pstate.c
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/acpi/acpi_cpu_tstate.c
cvs rdiff -u -r0 -r1.1 src/sys/dev/acpi/acpi_pcd.c
cvs rdiff -u -r1.116 -r1.117 src/sys/dev/acpi/files.acpi

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/acpi/files.acpi
diff -u src/sys/arch/arm/acpi/files.acpi:1.11 src/sys/arch/arm/acpi/files.acpi:1.12
--- src/sys/arch/arm/acpi/files.acpi:1.11	Sat Oct 10 15:25:31 2020
+++ src/sys/arch/arm/acpi/files.acpi	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files.acpi,v 1.11 2020/10/10 15:25:31 jmcneill Exp $
+#	$NetBSD: files.acpi,v 1.12 2020/12/07 10:57:41 jmcneill Exp $
 #
 # Configuration info for ACPI compliant ARM boards.
 #
@@ -40,6 +40,14 @@ file	arch/arm/acpi/sbsawdt_acpi.c		sbsaw
 attach	plcom at acpinodebus with plcom_acpi
 file	arch/arm/acpi/plcom_acpi.c		plcom_acpi
 
+device	acpicpu: acpi
+attach	acpicpu at acpinodebus
+file	dev/acpi/acpi_cpu.c			acpicpu
+file	dev/acpi/acpi_cpu_cstate.c		acpicpu
+file	dev/acpi/acpi_cpu_pstate.c		acpicpu
+file	dev/acpi/acpi_cpu_tstate.c		acpicpu
+file	arch/arm/acpi/acpi_cpu_md.c		acpicpu
+
 device	acpipchb: pcibus
 attach	acpipchb at acpinodebus
 file	arch/arm/acpi/acpipchb.c		acpipchb

Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.165 src/sys/arch/evbarm/conf/GENERIC64:1.166
--- src/sys/arch/evbarm/conf/GENERIC64:1.165	Wed Oct 28 07:36:17 2020
+++ src/sys/arch/evbarm/conf/GENERIC64	Mon Dec  7 10:57:41 2020
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: GENERIC64,v 1.165 2020/10/28 07:36:17 rin Exp $
+#	$NetBSD: GENERIC64,v 1.166 2020/12/07 10:57:41 jmcneill Exp $
 #
 #	GENERIC ARM (aarch64) kernel
 #
@@ -90,6 +90,8 @@ acpi*		at acpifdt?
 acpiacad*	at acpi?
 acpibat*	at acpi?
 acpibut*	at acpi?
+acpipcd*	at acpi?
+acpicpu*	at acpi?
 acpifan*	at acpi?
 acpiged*	at acpi?
 acpilid*	at acpi?

Index: src/sys/dev/acpi/acpi.c
diff -u src/sys/dev/acpi/acpi.c:1.286 src/sys/dev/acpi/acpi.c:1.287
--- src/sys/dev/acpi/acpi.c:1.286	Sun Nov  8 14:16:59 2020
+++ src/sys/dev/acpi/acpi.c	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi.c,v 1.286 2020/11/08 14:16:59 jmcneill Exp $	*/
+/*	$NetBSD: acpi.c,v 1.287 2020/12/07 10:57:41 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.286 2020/11/08 14:16:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.287 2020/12/07 10:57:41 jmcneill Exp $");
 
 #include "pci.h"
 #include "opt_acpi.h"
@@ -178,7 +178,6 @@ static const char * const acpi_ignored_i
 #endif
 #if defined(__aarch64__)
 	"ACPI0004",	/* ACPI module devices are handled internally */
-	"ACPI0007",	/* ACPI CPUs are attached via MADT GICC subtables */
 	"PNP0C0F",	/* ACPI PCI link devices are handled internally */
 #endif
 	NULL

Index: src/sys/dev/acpi/acpi_cpu.c
diff -u src/sys/dev/acpi/acpi_cpu.c:1.52 src/sys/dev/acpi/acpi_cpu.c:1.53
--- src/sys/dev/acpi/acpi_cpu.c:1.52	Mon Mar 16 21:20:09 2020
+++ src/sys/dev/acpi/acpi_cpu.c	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.c,v 1.52 2020/03/16 21:20:09 pgoyette Exp $ */
+/* $NetBSD: acpi_cpu.c,v 1.53 2020/12/07 10:57:41 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.52 2020/03/16 21:20:09 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.53 2020/12/07 10:57:41 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -44,7 +44,10 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v
 #include <dev/acpi/acpi_cpu.h>
 
 #include <machine/acpi_machdep.h>
+
+#if defined(__i386__) || defined(__x86_64__)
 #include <machine/cpuvar.h>
+#endif
 
 #define _COMPONENT	  ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME	  ("acpi_cpu")
@@ -171,7 +174,7 @@ acpicpu_attach(device_t parent, device_t
 
 	rv = acpicpu_object(sc->sc_node->ad_handle, &sc->sc_object);
 
-	if (ACPI_FAILURE(rv))
+	if (ACPI_FAILURE(rv) && rv != AE_TYPE)
 		aprint_verbose_dev(self, "failed to obtain CPU object\n");
 
 	acpicpu_count++;
@@ -187,7 +190,9 @@ acpicpu_attach(device_t parent, device_t
 	sc->sc_node->ad_device = self;
 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
 
+#if defined(__i386__) || defined(__x86_64__)
 	acpicpu_cstate_attach(self);
+#endif
 	acpicpu_pstate_attach(self);
 	acpicpu_tstate_attach(self);
 
@@ -365,10 +370,16 @@ fail:
 static ACPI_STATUS
 acpicpu_object(ACPI_HANDLE hdl, struct acpicpu_object *ao)
 {
+	ACPI_OBJECT_TYPE typ;
 	ACPI_OBJECT *obj;
 	ACPI_BUFFER buf;
 	ACPI_STATUS rv;
 
+	rv = AcpiGetType(hdl, &typ);
+	if (typ != ACPI_TYPE_PROCESSOR) {
+		return AE_TYPE;
+	}
+
 	rv = acpi_eval_struct(hdl, NULL, &buf);
 
 	if (ACPI_FAILURE(rv))
@@ -832,6 +843,8 @@ acpicpu_debug_print_method_c(uint8_t val
 static const char *
 acpicpu_debug_print_method_pt(uint8_t val)
 {
+	if (val == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+		return "MMIO";
 
 	if (val == ACPI_ADR_SPACE_SYSTEM_IO)
 		return "I/O";

Index: src/sys/dev/acpi/acpi_cpu.h
diff -u src/sys/dev/acpi/acpi_cpu.h:1.44 src/sys/dev/acpi/acpi_cpu.h:1.45
--- src/sys/dev/acpi/acpi_cpu.h:1.44	Fri Apr 27 04:38:24 2012
+++ src/sys/dev/acpi/acpi_cpu.h	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.h,v 1.44 2012/04/27 04:38:24 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.45 2020/12/07 10:57:41 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi>
@@ -259,17 +259,97 @@ struct cpu_info *acpicpu_md_match(device
 struct cpu_info *acpicpu_md_attach(device_t, device_t, void *);
 
 uint32_t	 acpicpu_md_flags(void);
-void		 acpicpu_md_quirk_c1e(void);
 int		 acpicpu_md_cstate_start(struct acpicpu_softc *);
 int		 acpicpu_md_cstate_stop(void);
 void		 acpicpu_md_cstate_enter(int, int);
 int		 acpicpu_md_pstate_start(struct acpicpu_softc *);
 int		 acpicpu_md_pstate_stop(void);
 int		 acpicpu_md_pstate_init(struct acpicpu_softc *);
-uint8_t		 acpicpu_md_pstate_hwf(struct cpu_info *);
 int		 acpicpu_md_pstate_get(struct acpicpu_softc *, uint32_t *);
 int		 acpicpu_md_pstate_set(struct acpicpu_pstate *);
 int		 acpicpu_md_tstate_get(struct acpicpu_softc *, uint32_t *);
 int		 acpicpu_md_tstate_set(struct acpicpu_tstate *);
 
+#if defined(__i386__) || defined(__x86_64__)
+void		 acpicpu_md_quirk_c1e(void);
+uint8_t		 acpicpu_md_pstate_hwf(struct cpu_info *);
+#endif
+
+/*
+ * acpicpu_readreg --
+ *
+ * 	Read data from an I/O or memory address defined by 'reg'. The data
+ * 	returned is shifted out and masked based on the bit offset and
+ * 	width defined by the 'reg' parameter.
+ *
+ */
+static inline uint32_t
+acpicpu_readreg(struct acpicpu_reg *reg)
+{
+	union {
+		uint64_t u64;
+		uint32_t u32;
+	} val;
+
+	KASSERT(reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_IO ||
+		reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_MEMORY);
+
+	const uint64_t reg_mask =
+	    __BITS(reg->reg_bitoffset + reg->reg_bitwidth - 1,
+		   reg->reg_bitoffset);
+
+	val.u64 = 0;
+	if (reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_IO) {
+		AcpiOsReadPort(reg->reg_addr, &val.u32,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	} else {
+		AcpiOsReadMemory(reg->reg_addr, &val.u64,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	}
+
+	return (uint32_t)__SHIFTOUT(val.u64, reg_mask);
+}
+
+/*
+ * acpicpu_writereg --
+ *
+ * 	Write data to an I/O or memory address defined by 'reg'. The register
+ * 	is updated using a read-modify-write cycle and is shifted in based on
+ * 	the bit offset and width defined by the 'reg' parameter.
+ *
+ */
+static inline void
+acpicpu_writereg(struct acpicpu_reg *reg, uint32_t newval)
+{
+	union {
+		uint64_t u64;
+		uint32_t u32;
+	} val;
+
+	KASSERT(reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_IO ||
+		reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_MEMORY);
+
+	const uint64_t reg_mask =
+	    __BITS(reg->reg_bitoffset + reg->reg_bitwidth - 1,
+		   reg->reg_bitoffset);
+
+	val.u64 = 0;
+	if (reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_IO) {
+		AcpiOsReadPort(reg->reg_addr, &val.u32,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	} else {
+		AcpiOsReadMemory(reg->reg_addr, &val.u64,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	}
+	val.u64 &= ~reg_mask;
+	val.u64 |= __SHIFTIN(newval, reg_mask);
+	if (reg->reg_spaceid == ACPI_ADR_SPACE_SYSTEM_IO) {
+		AcpiOsWritePort(reg->reg_addr, val.u32,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	} else {
+		AcpiOsWriteMemory(reg->reg_addr, val.u64,
+		    ACPI_ACCESS_BIT_WIDTH(reg->reg_accesssize));
+	}
+}
+
 #endif	/* !_SYS_DEV_ACPI_ACPI_CPU_H */

Index: src/sys/dev/acpi/acpi_cpu_cstate.c
diff -u src/sys/dev/acpi/acpi_cpu_cstate.c:1.62 src/sys/dev/acpi/acpi_cpu_cstate.c:1.63
--- src/sys/dev/acpi/acpi_cpu_cstate.c:1.62	Thu Jun  4 03:14:36 2020
+++ src/sys/dev/acpi/acpi_cpu_cstate.c	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_cstate.c,v 1.62 2020/06/04 03:14:36 riastradh Exp $ */
+/* $NetBSD: acpi_cpu_cstate.c,v 1.63 2020/12/07 10:57:41 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.62 2020/06/04 03:14:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.63 2020/12/07 10:57:41 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -160,7 +160,6 @@ acpicpu_cstate_callback(void *aux)
 static ACPI_STATUS
 acpicpu_cstate_cst(struct acpicpu_softc *sc)
 {
-	struct acpicpu_cstate *cs = sc->sc_cstate;
 	ACPI_OBJECT *elm, *obj;
 	ACPI_BUFFER buf;
 	ACPI_STATUS rv;
@@ -208,7 +207,7 @@ acpicpu_cstate_cst(struct acpicpu_softc 
 	/*
 	 * All x86 processors should support C1 (a.k.a. HALT).
 	 */
-	cs[ACPI_STATE_C1].cs_method = ACPICPU_C_STATE_HALT;
+	sc->sc_cstate[ACPI_STATE_C1].cs_method = ACPICPU_C_STATE_HALT;
 
 	CTASSERT(ACPI_STATE_C0 == 0 && ACPI_STATE_C1 == 1);
 	CTASSERT(ACPI_STATE_C2 == 2 && ACPI_STATE_C3 == 3);
@@ -661,7 +660,11 @@ acpicpu_cstate_idle(void)
 	if (__predict_false(sc == NULL))
 		return;
 
+#if defined(__i386__) || defined(__x86_64__)
 	KASSERT(ci->ci_ilevel == IPL_NONE);
+#elif defined(__aarch64__)
+	KASSERT(ci->ci_cpl == IPL_NONE);
+#endif
 	KASSERT((sc->sc_flags & ACPICPU_FLAG_C) != 0);
 
 	if (__predict_false(sc->sc_cold != false))
@@ -673,11 +676,13 @@ acpicpu_cstate_idle(void)
 	state = acpicpu_cstate_latency(sc);
 	mutex_exit(&sc->sc_mtx);
 
+#if defined(__i386__) || defined(__x86_64__)
 	/*
 	 * Apply AMD C1E quirk.
 	 */
 	if ((sc->sc_flags & ACPICPU_FLAG_C_C1E) != 0)
 		acpicpu_md_quirk_c1e();
+#endif
 
 	/*
 	 * Check for bus master activity. Note that particularly usb(4)

Index: src/sys/dev/acpi/acpi_cpu_pstate.c
diff -u src/sys/dev/acpi/acpi_cpu_pstate.c:1.53 src/sys/dev/acpi/acpi_cpu_pstate.c:1.54
--- src/sys/dev/acpi/acpi_cpu_pstate.c:1.53	Tue Nov 15 07:43:37 2011
+++ src/sys/dev/acpi/acpi_cpu_pstate.c	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_pstate.c,v 1.53 2011/11/15 07:43:37 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_pstate.c,v 1.54 2020/12/07 10:57:41 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,10 +27,11 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.53 2011/11/15 07:43:37 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.54 2020/12/07 10:57:41 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/cpufreq.h>
+#include <sys/cpu.h>
 #include <sys/kmem.h>
 
 #include <dev/acpi/acpireg.h>
@@ -515,6 +516,7 @@ acpicpu_pstate_pct(struct acpicpu_softc 
 
 		switch (reg[i]->reg_spaceid) {
 
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 		case ACPI_ADR_SPACE_SYSTEM_IO:
 
 			if (reg[i]->reg_addr == 0) {
@@ -809,8 +811,6 @@ acpicpu_pstate_get(void *aux, void *cpu_
 	struct cpu_info *ci = curcpu();
 	struct acpicpu_softc *sc;
 	uint32_t freq, i, val = 0;
-	uint64_t addr;
-	uint8_t width;
 	int rv;
 
 	sc = acpicpu_sc[ci->ci_acpiid];
@@ -849,12 +849,10 @@ acpicpu_pstate_get(void *aux, void *cpu_
 
 		break;
 
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		addr  = sc->sc_pstate_status.reg_addr;
-		width = sc->sc_pstate_status.reg_bitwidth;
-
-		(void)AcpiOsReadPort(addr, &val, width);
+		val = acpicpu_readreg(&sc->sc_pstate_status);
 
 		if (val == 0) {
 			rv = EIO;
@@ -909,8 +907,6 @@ acpicpu_pstate_set(void *aux, void *cpu_
 	struct cpu_info *ci = curcpu();
 	struct acpicpu_softc *sc;
 	uint32_t freq, i, val;
-	uint64_t addr;
-	uint8_t width;
 	int rv;
 
 	freq = *(uint32_t *)cpu_freq;
@@ -968,15 +964,10 @@ acpicpu_pstate_set(void *aux, void *cpu_
 
 		break;
 
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		addr  = sc->sc_pstate_control.reg_addr;
-		width = sc->sc_pstate_control.reg_bitwidth;
-
-		(void)AcpiOsWritePort(addr, ps->ps_control, width);
-
-		addr  = sc->sc_pstate_status.reg_addr;
-		width = sc->sc_pstate_status.reg_bitwidth;
+		acpicpu_writereg(&sc->sc_pstate_control, ps->ps_control);
 
 		/*
 		 * Some systems take longer to respond
@@ -984,7 +975,7 @@ acpicpu_pstate_set(void *aux, void *cpu_
 		 */
 		for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) {
 
-			(void)AcpiOsReadPort(addr, &val, width);
+			val = acpicpu_readreg(&sc->sc_pstate_status);
 
 			if (val == ps->ps_status)
 				break;

Index: src/sys/dev/acpi/acpi_cpu_tstate.c
diff -u src/sys/dev/acpi/acpi_cpu_tstate.c:1.33 src/sys/dev/acpi/acpi_cpu_tstate.c:1.34
--- src/sys/dev/acpi/acpi_cpu_tstate.c:1.33	Thu Jun  1 02:45:09 2017
+++ src/sys/dev/acpi/acpi_cpu_tstate.c	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_tstate.c,v 1.33 2017/06/01 02:45:09 chs Exp $ */
+/* $NetBSD: acpi_cpu_tstate.c,v 1.34 2020/12/07 10:57:41 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
@@ -27,11 +27,12 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.33 2017/06/01 02:45:09 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.34 2020/12/07 10:57:41 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
 #include <sys/xcall.h>
+#include <sys/cpu.h>
 
 #include <dev/acpi/acpireg.h>
 #include <dev/acpi/acpivar.h>
@@ -390,6 +391,15 @@ acpicpu_tstate_ptc(struct acpicpu_softc 
 
 		switch (reg[i]->reg_spaceid) {
 
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+
+			if (reg[i]->reg_addr == 0) {
+				rv = AE_AML_ILLEGAL_ADDRESS;
+				goto out;
+			}
+
+			break;
+
 		case ACPI_ADR_SPACE_SYSTEM_IO:
 
 			if (reg[i]->reg_addr == 0) {
@@ -397,6 +407,7 @@ acpicpu_tstate_ptc(struct acpicpu_softc 
 				goto out;
 			}
 
+#if defined(__i386__) || defined(__x86_64__)
 			/*
 			 * Check that the values match the IA32 clock
 			 * modulation MSR, where the bit 0 is reserved,
@@ -412,6 +423,7 @@ acpicpu_tstate_ptc(struct acpicpu_softc 
 				rv = AE_AML_BAD_RESOURCE_VALUE;
 				goto out;
 			}
+#endif
 
 			break;
 
@@ -649,8 +661,6 @@ acpicpu_tstate_get(struct cpu_info *ci, 
 	struct acpicpu_tstate *ts = NULL;
 	struct acpicpu_softc *sc;
 	uint32_t i, val = 0;
-	uint8_t offset;
-	uint64_t addr;
 	int rv;
 
 	sc = acpicpu_sc[ci->ci_acpiid];
@@ -692,13 +702,9 @@ acpicpu_tstate_get(struct cpu_info *ci, 
 		break;
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		addr   = sc->sc_tstate_status.reg_addr;
-		offset = sc->sc_tstate_status.reg_bitoffset;
-
-		(void)AcpiOsReadPort(addr, &val, 8);
-
-		val = (val >> offset) & 0x0F;
+		val = acpicpu_readreg(&sc->sc_tstate_status);
 
 		for (i = 0; i < sc->sc_tstate_count; i++) {
 
@@ -757,8 +763,6 @@ acpicpu_tstate_set_xcall(void *arg1, voi
 	struct cpu_info *ci = curcpu();
 	struct acpicpu_softc *sc;
 	uint32_t i, percent, val;
-	uint8_t offset;
-	uint64_t addr;
 	int rv;
 
 	percent = *(uint32_t *)arg1;
@@ -816,18 +820,9 @@ acpicpu_tstate_set_xcall(void *arg1, voi
 		break;
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
+	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		addr   = sc->sc_tstate_control.reg_addr;
-		offset = sc->sc_tstate_control.reg_bitoffset;
-
-		val = (ts->ts_control & 0x0F) << offset;
-
-		if (ts->ts_percent != 100 && (val & __BIT(4)) == 0) {
-			rv = EINVAL;
-			goto fail;
-		}
-
-		(void)AcpiOsWritePort(addr, val, 8);
+		acpicpu_writereg(&sc->sc_tstate_control, ts->ts_control);
 
 		/*
 		 * If the status field is zero, the transition is
@@ -837,14 +832,9 @@ acpicpu_tstate_set_xcall(void *arg1, voi
 		if (ts->ts_status == 0)
 			break;
 
-		addr   = sc->sc_tstate_status.reg_addr;
-		offset = sc->sc_tstate_status.reg_bitoffset;
-
-		for (i = val = 0; i < ACPICPU_T_STATE_RETRY; i++) {
-
-			(void)AcpiOsReadPort(addr, &val, 8);
+		for (i = 0; i < ACPICPU_T_STATE_RETRY; i++) {
 
-			val = (val >> offset) & 0x0F;
+			val = acpicpu_readreg(&sc->sc_tstate_status);
 
 			if (val == ts->ts_status)
 				break;

Index: src/sys/dev/acpi/files.acpi
diff -u src/sys/dev/acpi/files.acpi:1.116 src/sys/dev/acpi/files.acpi:1.117
--- src/sys/dev/acpi/files.acpi:1.116	Sun Dec  6 02:57:30 2020
+++ src/sys/dev/acpi/files.acpi	Mon Dec  7 10:57:41 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: files.acpi,v 1.116 2020/12/06 02:57:30 jmcneill Exp $
+#	$NetBSD: files.acpi,v 1.117 2020/12/07 10:57:41 jmcneill Exp $
 
 include "dev/acpi/acpica/files.acpica"
 
@@ -101,6 +101,11 @@ device	acpiwdrt: sysmon_wdog
 attach	acpiwdrt at acpiwdrtbus
 file	dev/acpi/acpi_wdrt.c		acpiwdrt
 
+# ACPI Processor Container Device
+device	acpipcd
+attach	acpipcd at acpinodebus
+file	dev/acpi/acpi_pcd.c		acpipcd
+
 # Serial interface
 attach	com at acpinodebus with com_acpi
 file	dev/acpi/com_acpi.c		com_acpi

Added files:

Index: src/sys/arch/arm/acpi/acpi_cpu_md.c
diff -u /dev/null src/sys/arch/arm/acpi/acpi_cpu_md.c:1.1
--- /dev/null	Mon Dec  7 10:57:41 2020
+++ src/sys/arch/arm/acpi/acpi_cpu_md.c	Mon Dec  7 10:57:41 2020
@@ -0,0 +1,365 @@
+/* $NetBSD: acpi_cpu_md.c,v 1.1 2020/12/07 10:57:41 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.1 2020/12/07 10:57:41 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/cpufreq.h>
+#include <sys/device.h>
+#include <sys/sysctl.h>
+
+#include <dev/acpi/acpica.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_cpu.h>
+#include <dev/acpi/acpi_util.h>
+
+static struct sysctllog *acpicpu_log = NULL;
+
+/*
+ * acpicpu_md_match --
+ *
+ * 	Match against an ACPI processor device node (either a device
+ * 	with HID "ACPI0007" or a processor node) and return a pointer
+ * 	to the corresponding CPU device's 'cpu_info' struct.
+ *
+ */
+struct cpu_info *
+acpicpu_md_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct acpi_attach_args * const aa = aux;
+
+	return acpi_match_cpu_handle(aa->aa_node->ad_handle);
+}
+
+/*
+ * acpicpu_md_attach --
+ *
+ * 	Return a pointer to the CPU device's 'cpu_info' struct
+ * 	corresponding with this device.
+ *
+ */
+struct cpu_info *
+acpicpu_md_attach(device_t parent, device_t self, void *aux)
+{
+	struct acpi_attach_args * const aa = aux;
+
+	return acpi_match_cpu_handle(aa->aa_node->ad_handle);
+}
+
+/*
+ * acpicpu_md_flags --
+ *
+ * 	Return a bitmask of ACPICPU_FLAG_* platform specific quirks.
+ *
+ */
+uint32_t
+acpicpu_md_flags(void)
+{
+	return 0;
+}
+
+/*
+ * acpicpu_md_cstate_start --
+ *
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_cstate_start(struct acpicpu_softc *sc)
+{
+	return EINVAL;
+}
+
+/*
+ * acpicpu_md_cstate_stop --
+ *
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_cstate_stop(void)
+{
+	return EALREADY;
+}
+
+/*
+ * acpicpu_md_cstate_enter --
+ *
+ * 	Not implemented.
+ *
+ */
+void
+acpicpu_md_cstate_enter(int method, int state)
+{
+}
+
+/*
+ * acpicpu_md_pstate_init --
+ *
+ * 	MD initialization for P-state support. Nothing to do here.
+ *
+ */
+int
+acpicpu_md_pstate_init(struct acpicpu_softc *sc)
+{
+	return 0;
+}
+
+/*
+ * acpicpu_md_pstate_sysctl_current --
+ *
+ * 	sysctl(9) callback for retrieving the current CPU frequency.
+ *
+ */
+static int
+acpicpu_md_pstate_sysctl_current(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node;
+	uint32_t freq;
+	int error;
+
+	freq = cpufreq_get(curcpu());
+	if (freq == 0)
+		return ENXIO;
+
+	node = *rnode;
+	node.sysctl_data = &freq;
+
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	return 0;
+}
+
+/*
+ * acpicpu_md_pstate_sysctl_target --
+ *
+ * 	sysctl(9) callback for setting the target CPU frequency.
+ *
+ */
+static int
+acpicpu_md_pstate_sysctl_target(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node;
+	uint32_t freq;
+	int error;
+
+	freq = cpufreq_get(curcpu());
+	if (freq == 0)
+		return ENXIO;
+
+	node = *rnode;
+	node.sysctl_data = &freq;
+
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	cpufreq_set_all(freq);
+
+	return 0;
+}
+
+/*
+ * acpicpu_md_pstate_sysctl_available --
+ *
+ * 	sysctl(9) callback for returning a list of supported CPU frequencies.
+ *
+ */
+static int
+acpicpu_md_pstate_sysctl_available(SYSCTLFN_ARGS)
+{
+	struct acpicpu_softc * const sc = rnode->sysctl_data;
+	struct sysctlnode node;
+	char buf[1024];
+	size_t len;
+	uint32_t i;
+	int error;
+
+	memset(buf, 0, sizeof(buf));
+
+	mutex_enter(&sc->sc_mtx);
+	for (len = 0, i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) {
+		if (sc->sc_pstate[i].ps_freq == 0)
+			continue;
+		if (len >= sizeof(buf))
+			break;
+		len += snprintf(buf + len, sizeof(buf) - len, "%u%s",
+		    sc->sc_pstate[i].ps_freq,
+		    i < (sc->sc_pstate_count - 1) ? " " : "");
+	}
+	mutex_exit(&sc->sc_mtx);
+
+	node = *rnode;
+	node.sysctl_data = buf;
+
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	return 0;
+}
+
+/*
+ * acpicpu_md_pstate_start --
+ *
+ * 	MD startup for P-state support. Create sysctls here.
+ *
+ */
+int
+acpicpu_md_pstate_start(struct acpicpu_softc *sc)
+{
+	const struct sysctlnode *mnode, *cnode, *fnode, *node;
+	int error;
+
+	error = sysctl_createv(&acpicpu_log, 0, NULL, &mnode,
+	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
+	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	error = sysctl_createv(&acpicpu_log, 0, &mnode, &cnode,
+	    0, CTLTYPE_NODE, "cpu", NULL,
+	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	error = sysctl_createv(&acpicpu_log, 0, &cnode, &fnode,
+	    0, CTLTYPE_NODE, "frequency", NULL,
+	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	error = sysctl_createv(&acpicpu_log, 0, &fnode, &node,
+	    CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL,
+	    acpicpu_md_pstate_sysctl_target, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	error = sysctl_createv(&acpicpu_log, 0, &fnode, &node,
+	    CTLFLAG_READONLY, CTLTYPE_INT, "current", NULL,
+	    acpicpu_md_pstate_sysctl_current, 0, NULL, 0, CTL_CREATE, CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	error = sysctl_createv(&acpicpu_log, 0, &fnode, &node,
+	    CTLFLAG_READONLY, CTLTYPE_STRING, "available", NULL,
+	    acpicpu_md_pstate_sysctl_available, 0, (void *)sc, 0, CTL_CREATE,
+	    CTL_EOL);
+	if (error) {
+		goto teardown;
+	}
+
+	return 0;
+
+teardown:
+	if (acpicpu_log != NULL) {
+		sysctl_teardown(&acpicpu_log);
+		acpicpu_log = NULL;
+	}
+
+	return error;
+}
+
+/*
+ * acpicpu_md_pstate_stop --
+ *
+ * 	MD shutdown for P-state support. Destroy sysctls here.
+ *
+ */
+int
+acpicpu_md_pstate_stop(void)
+{
+	if (acpicpu_log != NULL) {
+		sysctl_teardown(&acpicpu_log);
+		acpicpu_log = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * acpicpu_md_pstate_get --
+ *
+ * 	Fixed hardware access method for getting current processor P-state.
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq)
+{
+	return EINVAL;
+}
+
+/*
+ * acpicpu_md_pstate_set --
+ *
+ * 	Fixed hardware access method for setting current processor P-state.
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_pstate_set(struct acpicpu_pstate *ps)
+{
+	return EINVAL;
+}
+
+/*
+ * acpicpu_md_tstate_get --
+ *
+ * 	Fixed hardware access method for getting current processor T-state.
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_tstate_get(struct acpicpu_softc *sc, uint32_t *percent)
+{
+	return EINVAL;
+}
+
+/*
+ * acpicpu_md_tstate_set --
+ *
+ * 	Fixed hardware access method for setting current processor T-state.
+ * 	Not implemented.
+ *
+ */
+int
+acpicpu_md_tstate_set(struct acpicpu_tstate *ts)
+{
+	return EINVAL;
+}

Index: src/sys/dev/acpi/acpi_pcd.c
diff -u /dev/null src/sys/dev/acpi/acpi_pcd.c:1.1
--- /dev/null	Mon Dec  7 10:57:41 2020
+++ src/sys/dev/acpi/acpi_pcd.c	Mon Dec  7 10:57:41 2020
@@ -0,0 +1,81 @@
+/* $NetBSD: acpi_pcd.c,v 1.1 2020/12/07 10:57:41 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This is a driver for the Processor Container Device. The device acts
+ * like a bus in the node namespace. Child nodes can be either processor
+ * devices or other processor containers.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: acpi_pcd.c,v 1.1 2020/12/07 10:57:41 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+
+static const char * const compatible[] = {
+	"ACPI0010",	/* Processor Container Device */
+	NULL
+};
+
+static int	acpi_pcd_match(device_t, cfdata_t, void *);
+static void	acpi_pcd_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(acpipcd, 0, acpi_pcd_match, acpi_pcd_attach, NULL, NULL);
+
+static int
+acpi_pcd_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct acpi_attach_args *aa = aux;
+
+	if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
+		return 0;
+
+	return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
+}
+
+static void
+acpi_pcd_attach(device_t parent, device_t self, void *aux)
+{
+	struct acpi_attach_args * const aa = aux;
+
+	aprint_naive("\n");
+	aprint_normal(": Processor Container Device\n");
+
+	/*
+	 * Initialize the container device. ACPICA should have done this
+	 * for us, but may have done so before a node that this one depends
+	 * on had been initialized.
+	 */
+	AcpiEvaluateObject(aa->aa_node->ad_handle, "_INI", NULL, NULL);
+}

Reply via email to