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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * 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 <[email protected]>
+ * 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);
+}