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); +}