xref: /dragonfly/sys/dev/acpica/acpi_cpu_pstate.c (revision de5eb4c5)
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Sepherosa Ziehau <sepherosa@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include "opt_acpi.h"
36 
37 #include <sys/param.h>
38 #include <sys/bus.h>
39 #include <sys/cpuhelper.h>
40 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/queue.h>
43 #include <sys/rman.h>
44 #include <sys/sysctl.h>
45 #include <sys/msgport2.h>
46 #include <sys/cpu_topology.h>
47 
48 #include "acpi.h"
49 #include "acpivar.h"
50 #include "acpi_cpu.h"
51 #include "acpi_cpu_pstate.h"
52 
53 #define ACPI_NPSTATE_MAX	32
54 
55 #define ACPI_PSS_PX_NENTRY	6
56 
57 #define ACPI_PSD_COORD_SWALL	0xfc
58 #define ACPI_PSD_COORD_SWANY	0xfd
59 #define ACPI_PSD_COORD_HWALL	0xfe
60 #define ACPI_PSD_COORD_VALID(coord) \
61 	((coord) == ACPI_PSD_COORD_SWALL || \
62 	 (coord) == ACPI_PSD_COORD_SWANY || \
63 	 (coord) == ACPI_PSD_COORD_HWALL)
64 
65 struct acpi_pst_softc;
66 LIST_HEAD(acpi_pst_list, acpi_pst_softc);
67 
68 struct acpi_pst_chmsg {
69 	struct cpuhelper_msg	ch_msg;
70 	const struct acpi_pst_res *ch_ctrl;
71 	const struct acpi_pst_res *ch_status;
72 };
73 
74 struct acpi_pst_domain {
75 	uint32_t		pd_dom;
76 	uint32_t		pd_coord;
77 	uint32_t		pd_nproc;
78 	LIST_ENTRY(acpi_pst_domain) pd_link;
79 
80 	uint32_t		pd_flags;
81 
82 	struct lwkt_serialize	pd_serialize;
83 
84 	int			pd_state;
85 	struct acpi_pst_list	pd_pstlist;
86 
87 	struct sysctl_ctx_list	pd_sysctl_ctx;
88 	struct sysctl_oid	*pd_sysctl_tree;
89 };
90 LIST_HEAD(acpi_pst_domlist, acpi_pst_domain);
91 
92 #define ACPI_PSTDOM_FLAG_STUB	0x1	/* stub domain, no _PSD */
93 #define ACPI_PSTDOM_FLAG_DEAD	0x2	/* domain can't be started */
94 #define ACPI_PSTDOM_FLAG_INT	0x4	/* domain created from Integer _PSD */
95 
96 struct acpi_pst_softc {
97 	device_t		pst_dev;
98 	struct acpi_cpu_softc	*pst_parent;
99 	struct acpi_pst_domain	*pst_domain;
100 	struct acpi_pst_res	pst_creg;
101 	struct acpi_pst_res	pst_sreg;
102 
103 	int			pst_state;
104 	int			pst_cpuid;
105 
106 	uint32_t		pst_flags;
107 
108 	ACPI_HANDLE		pst_handle;
109 
110 	LIST_ENTRY(acpi_pst_softc) pst_link;
111 };
112 
113 #define ACPI_PST_FLAG_PPC	0x1
114 #define ACPI_PST_FLAG_PDL	0x2
115 
116 static int	acpi_pst_probe(device_t dev);
117 static int	acpi_pst_attach(device_t dev);
118 static void	acpi_pst_notify(device_t dev);
119 
120 static void	acpi_pst_postattach(void *);
121 static struct acpi_pst_domain *
122 		acpi_pst_domain_create_int(device_t, uint32_t);
123 static struct acpi_pst_domain *
124 		acpi_pst_domain_create_pkg(device_t, ACPI_OBJECT *);
125 static struct acpi_pst_domain *
126 		acpi_pst_domain_find(uint32_t);
127 static struct acpi_pst_domain *
128 		acpi_pst_domain_alloc(uint32_t, uint32_t, uint32_t);
129 static void	acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *,
130 		    int, int *);
131 static void	acpi_pst_domain_set_pstate(struct acpi_pst_domain *, int,
132 		    int *);
133 static void	acpi_pst_domain_check_nproc(device_t, struct acpi_pst_domain *);
134 static void	acpi_pst_global_set_pstate(int);
135 static void	acpi_pst_global_fixup_pstate(void);
136 
137 static int	acpi_pst_check_csr(struct acpi_pst_softc *);
138 static int	acpi_pst_check_pstates(struct acpi_pst_softc *);
139 static int	acpi_pst_init(struct acpi_pst_softc *);
140 static int	acpi_pst_set_pstate(struct acpi_pst_softc *,
141 		    const struct acpi_pstate *);
142 static const struct acpi_pstate *
143 		acpi_pst_get_pstate(struct acpi_pst_softc *);
144 static int	acpi_pst_alloc_resource(device_t, ACPI_OBJECT *, int,
145 		    struct acpi_pst_res *);
146 static int	acpi_pst_eval_ppc(struct acpi_pst_softc *, int *);
147 static int	acpi_pst_eval_pdl(struct acpi_pst_softc *, int *);
148 
149 static void	acpi_pst_check_csr_handler(struct cpuhelper_msg *);
150 static void	acpi_pst_check_pstates_handler(struct cpuhelper_msg *);
151 static void	acpi_pst_init_handler(struct cpuhelper_msg *);
152 static void	acpi_pst_set_pstate_handler(struct cpuhelper_msg *);
153 static void	acpi_pst_get_pstate_handler(struct cpuhelper_msg *);
154 
155 static int	acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS);
156 static int	acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS);
157 static int	acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS);
158 static int	acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS);
159 static int	acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS);
160 static int	acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS);
161 
162 static struct acpi_pst_domlist	acpi_pst_domains =
163 	LIST_HEAD_INITIALIZER(acpi_pst_domains);
164 static int			acpi_pst_domain_id;
165 
166 static int			acpi_pst_global_state;
167 
168 static int			acpi_pstate_start = -1;
169 static int			acpi_pstate_count;
170 static int			acpi_npstates;
171 static struct acpi_pstate	*acpi_pstates;
172 
173 static const struct acpi_pst_md	*acpi_pst_md;
174 
175 static int			acpi_pst_pdl = -1;
176 TUNABLE_INT("hw.acpi.cpu.pst.pdl", &acpi_pst_pdl);
177 
178 static int			acpi_pst_ht_reuse_domain = 1;
179 TUNABLE_INT("hw.acpi.cpu.pst.ht_reuse_domain", &acpi_pst_ht_reuse_domain);
180 
181 static int			acpi_pst_force_pkg_domain = 0;
182 TUNABLE_INT("hw.acpi.cpu.pst.force_pkg_domain", &acpi_pst_force_pkg_domain);
183 
184 static int			acpi_pst_handle_notify = 1;
185 TUNABLE_INT("hw.acpi.cpu.pst.handle_notify", &acpi_pst_handle_notify);
186 
187 /*
188  * Force CPU package power domain for Intel CPUs.
189  *
190  * As of this write (14 July 2015), all Intel CPUs only have CPU package
191  * power domain.
192  */
193 static int			acpi_pst_intel_pkg_domain = 1;
194 TUNABLE_INT("hw.acpi.cpu.pst.intel_pkg_domain", &acpi_pst_intel_pkg_domain);
195 
196 static device_method_t acpi_pst_methods[] = {
197 	/* Device interface */
198 	DEVMETHOD(device_probe,			acpi_pst_probe),
199 	DEVMETHOD(device_attach,		acpi_pst_attach),
200 	DEVMETHOD(device_detach,		bus_generic_detach),
201 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
202 	DEVMETHOD(device_suspend,		bus_generic_suspend),
203 	DEVMETHOD(device_resume,		bus_generic_resume),
204 
205 	/* Bus interface */
206 	DEVMETHOD(bus_add_child,		bus_generic_add_child),
207 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
208 	DEVMETHOD(bus_read_ivar,		bus_generic_read_ivar),
209 	DEVMETHOD(bus_write_ivar,		bus_generic_write_ivar),
210 	DEVMETHOD(bus_get_resource_list,	bus_generic_get_resource_list),
211 	DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
212 	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
213 	DEVMETHOD(bus_alloc_resource,		bus_generic_alloc_resource),
214 	DEVMETHOD(bus_release_resource,		bus_generic_release_resource),
215 	DEVMETHOD(bus_driver_added,		bus_generic_driver_added),
216 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
217 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
218 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
219 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
220 
221 	DEVMETHOD_END
222 };
223 
224 static driver_t acpi_pst_driver = {
225 	"cpu_pst",
226 	acpi_pst_methods,
227 	sizeof(struct acpi_pst_softc)
228 };
229 
230 static devclass_t acpi_pst_devclass;
231 DRIVER_MODULE(cpu_pst, cpu, acpi_pst_driver, acpi_pst_devclass, NULL, NULL);
232 MODULE_DEPEND(cpu_pst, acpi, 1, 1, 1);
233 
234 static __inline int
235 acpi_pst_freq2index(int freq)
236 {
237 	int i;
238 
239 	for (i = 0; i < acpi_npstates; ++i) {
240 		if (acpi_pstates[i].st_freq == freq)
241 			return i;
242 	}
243 	return -1;
244 }
245 
246 static int
247 acpi_pst_probe(device_t dev)
248 {
249 	ACPI_BUFFER buf;
250 	ACPI_HANDLE handle;
251 	ACPI_STATUS status;
252 	ACPI_OBJECT *obj;
253 
254 	if (acpi_disabled("cpu_pst") ||
255 	    acpi_get_type(dev) != ACPI_TYPE_PROCESSOR)
256 		return ENXIO;
257 
258 	if (acpi_pst_md == NULL)
259 		acpi_pst_md = acpi_pst_md_probe();
260 
261 	handle = acpi_get_handle(dev);
262 
263 	/*
264 	 * Check _PSD package
265 	 *
266 	 * NOTE:
267 	 * Some BIOSes do not expose _PCT for the second thread of
268 	 * CPU cores.  In this case, _PSD should be enough to get the
269 	 * P-state of the second thread working, since it must have
270 	 * the same _PCT and _PSS as the first thread in the same
271 	 * core.
272 	 */
273 	buf.Pointer = NULL;
274 	buf.Length = ACPI_ALLOCATE_BUFFER;
275 	status = AcpiEvaluateObject(handle, "_PSD", NULL, &buf);
276 	if (!ACPI_FAILURE(status)) {
277 		AcpiOsFree((ACPI_OBJECT *)buf.Pointer);
278 		goto done;
279 	}
280 
281 	/*
282 	 * Check _PCT package
283 	 */
284 	buf.Pointer = NULL;
285 	buf.Length = ACPI_ALLOCATE_BUFFER;
286 	status = AcpiEvaluateObject(handle, "_PCT", NULL, &buf);
287 	if (ACPI_FAILURE(status)) {
288 		if (bootverbose) {
289 			device_printf(dev, "Can't get _PCT package - %s\n",
290 				      AcpiFormatException(status));
291 		}
292 		return ENXIO;
293 	}
294 
295 	obj = (ACPI_OBJECT *)buf.Pointer;
296 	if (!ACPI_PKG_VALID_EQ(obj, 2)) {
297 		device_printf(dev, "Invalid _PCT package\n");
298 		AcpiOsFree(obj);
299 		return ENXIO;
300 	}
301 	AcpiOsFree(obj);
302 
303 	/*
304 	 * Check _PSS package
305 	 */
306 	buf.Pointer = NULL;
307 	buf.Length = ACPI_ALLOCATE_BUFFER;
308 	status = AcpiEvaluateObject(handle, "_PSS", NULL, &buf);
309 	if (ACPI_FAILURE(status)) {
310 		device_printf(dev, "Can't get _PSS package - %s\n",
311 			      AcpiFormatException(status));
312 		return ENXIO;
313 	}
314 
315 	obj = (ACPI_OBJECT *)buf.Pointer;
316 	if (!ACPI_PKG_VALID(obj, 1)) {
317 		device_printf(dev, "Invalid _PSS package\n");
318 		AcpiOsFree(obj);
319 		return ENXIO;
320 	}
321 	AcpiOsFree(obj);
322 
323 done:
324 	device_set_desc(dev, "ACPI CPU P-State");
325 	return 0;
326 }
327 
328 static int
329 acpi_pst_attach(device_t dev)
330 {
331 	struct acpi_pst_softc *sc = device_get_softc(dev);
332 	struct acpi_pst_domain *dom = NULL;
333 	ACPI_BUFFER buf;
334 	ACPI_STATUS status;
335 	ACPI_OBJECT *obj;
336 	struct acpi_pstate *pstate, *p;
337 	int i, npstate, error, sstart, scount;
338 
339 	sc->pst_dev = dev;
340 	sc->pst_parent = device_get_softc(device_get_parent(dev));
341 	sc->pst_handle = acpi_get_handle(dev);
342 	sc->pst_cpuid = acpi_get_magic(dev);
343 
344 	/*
345 	 * If there is a _PSD, then we create procossor domain
346 	 * accordingly.  If there is no _PSD, we just fake a
347 	 * default processor domain0.
348 	 */
349 	buf.Pointer = NULL;
350 	buf.Length = ACPI_ALLOCATE_BUFFER;
351 	status = AcpiEvaluateObject(sc->pst_handle, "_PSD", NULL, &buf);
352 	if (!ACPI_FAILURE(status)) {
353 		obj = (ACPI_OBJECT *)buf.Pointer;
354 
355 		if (acpi_pst_domain_id > 0) {
356 			device_printf(dev, "Missing _PSD for certain CPUs\n");
357 			AcpiOsFree(obj);
358 			return ENXIO;
359 		}
360 		acpi_pst_domain_id = -1;
361 
362 		if (ACPI_PKG_VALID_EQ(obj, 1)) {
363 			dom = acpi_pst_domain_create_pkg(dev,
364 				&obj->Package.Elements[0]);
365 			if (dom == NULL) {
366 				AcpiOsFree(obj);
367 				return ENXIO;
368 			}
369 		} else {
370 			if (obj->Type != ACPI_TYPE_INTEGER) {
371 				device_printf(dev,
372 				    "Invalid _PSD package, Type 0x%x\n",
373 				    obj->Type);
374 				AcpiOsFree(obj);
375 				return ENXIO;
376 			} else {
377 				device_printf(dev, "Integer _PSD %ju\n",
378 				    (uintmax_t)obj->Integer.Value);
379 				dom = acpi_pst_domain_create_int(dev,
380 				    obj->Integer.Value);
381 				if (dom == NULL) {
382 					AcpiOsFree(obj);
383 					return ENXIO;
384 				}
385 			}
386 		}
387 
388 		/* Free _PSD */
389 		AcpiOsFree(buf.Pointer);
390 	} else {
391 		if (acpi_pst_domain_id < 0) {
392 			device_printf(dev, "Missing _PSD for cpu%d\n",
393 			    sc->pst_cpuid);
394 			return ENXIO;
395 		}
396 
397 		/*
398 		 * Create a stub one processor domain for each processor
399 		 */
400 		dom = acpi_pst_domain_alloc(acpi_pst_domain_id,
401 			ACPI_PSD_COORD_SWANY, 1);
402 		dom->pd_flags |= ACPI_PSTDOM_FLAG_STUB;
403 
404 		++acpi_pst_domain_id;
405 	}
406 
407 	/* Make sure that adding us will not overflow our domain */
408 	acpi_pst_domain_check_nproc(dev, dom);
409 
410 	/*
411 	 * Get control/status registers from _PCT
412 	 */
413 	buf.Pointer = NULL;
414 	buf.Length = ACPI_ALLOCATE_BUFFER;
415 	status = AcpiEvaluateObject(sc->pst_handle, "_PCT", NULL, &buf);
416 	if (ACPI_FAILURE(status)) {
417 		struct acpi_pst_softc *pst;
418 
419 		/*
420 		 * No _PCT.  See the comment in acpi_pst_probe() near
421 		 * _PSD check.
422 		 *
423 		 * Use control/status registers of another CPU in the
424 		 * same domain, or in the same core, if the type of
425 		 * these registers are "Fixed Hardware", e.g. on most
426 		 * of the model Intel CPUs.
427 		 */
428 		pst = LIST_FIRST(&dom->pd_pstlist);
429 		if (pst == NULL) {
430 			cpumask_t mask;
431 
432 			mask = get_cpumask_from_level(sc->pst_cpuid,
433 			    CORE_LEVEL);
434 			if (CPUMASK_TESTNZERO(mask)) {
435 				struct acpi_pst_domain *dom1;
436 
437 				LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) {
438 					LIST_FOREACH(pst, &dom1->pd_pstlist,
439 					    pst_link) {
440 						if (CPUMASK_TESTBIT(mask,
441 						    pst->pst_cpuid))
442 							break;
443 					}
444 					if (pst != NULL)
445 						break;
446 				}
447 				if (pst != NULL && acpi_pst_ht_reuse_domain) {
448 					/*
449 					 * Use the same domain for CPUs in the
450 					 * same core.
451 					 */
452 					device_printf(dev, "Destroy domain%u, "
453 					    "reuse domain%u\n",
454 					    dom->pd_dom, dom1->pd_dom);
455 					LIST_REMOVE(dom, pd_link);
456 					kfree(dom, M_DEVBUF);
457 					dom = dom1;
458 					/*
459 					 * Make sure that adding us will not
460 					 * overflow the domain containing
461 					 * siblings in the same core.
462 					 */
463 					acpi_pst_domain_check_nproc(dev, dom);
464 				}
465 			}
466 		}
467 		if (pst != NULL &&
468 		    pst->pst_creg.pr_res == NULL &&
469 		    pst->pst_creg.pr_rid == 0 &&
470 		    pst->pst_creg.pr_gas.SpaceId ==
471 		    ACPI_ADR_SPACE_FIXED_HARDWARE &&
472 		    pst->pst_sreg.pr_res == NULL &&
473 		    pst->pst_sreg.pr_rid == 0 &&
474 		    pst->pst_sreg.pr_gas.SpaceId ==
475 		    ACPI_ADR_SPACE_FIXED_HARDWARE) {
476 			sc->pst_creg = pst->pst_creg;
477 			sc->pst_sreg = pst->pst_sreg;
478 			device_printf(dev,
479 			    "No _PCT; reuse %s control/status regs\n",
480 			    device_get_nameunit(pst->pst_dev));
481 			goto fetch_pss;
482 		}
483 		device_printf(dev, "Can't get _PCT package - %s\n",
484 			      AcpiFormatException(status));
485 		return ENXIO;
486 	}
487 
488 	obj = (ACPI_OBJECT *)buf.Pointer;
489 	if (!ACPI_PKG_VALID_EQ(obj, 2)) {
490 		device_printf(dev, "Invalid _PCT package\n");
491 		AcpiOsFree(obj);
492 		return ENXIO;
493 	}
494 
495 	/* Save and try allocating control register */
496 	error = acpi_pst_alloc_resource(dev, obj, 0, &sc->pst_creg);
497 	if (error) {
498 		AcpiOsFree(obj);
499 		return error;
500 	}
501 	if (bootverbose) {
502 		device_printf(dev, "control reg %d %jx\n",
503 			      sc->pst_creg.pr_gas.SpaceId,
504 			      (uintmax_t)sc->pst_creg.pr_gas.Address);
505 	}
506 
507 	/* Save and try allocating status register */
508 	error = acpi_pst_alloc_resource(dev, obj, 1, &sc->pst_sreg);
509 	if (error) {
510 		AcpiOsFree(obj);
511 		return error;
512 	}
513 	if (bootverbose) {
514 		device_printf(dev, "status reg %d %jx\n",
515 			      sc->pst_sreg.pr_gas.SpaceId,
516 			      (uintmax_t)sc->pst_sreg.pr_gas.Address);
517 	}
518 
519 	/* Free _PCT */
520 	AcpiOsFree(obj);
521 
522 fetch_pss:
523 	/*
524 	 * Create P-State table according to _PSS
525 	 */
526 	buf.Pointer = NULL;
527 	buf.Length = ACPI_ALLOCATE_BUFFER;
528 	status = AcpiEvaluateObject(sc->pst_handle, "_PSS", NULL, &buf);
529 	if (ACPI_FAILURE(status)) {
530 		/*
531 		 * No _PSS.  See the comment in acpi_pst_probe() near
532 		 * _PSD check.
533 		 *
534 		 * Assume _PSS are same across all CPUs; well, they
535 		 * should/have to be so.
536 		 */
537 		if (acpi_npstates > 0 && acpi_pstates != NULL) {
538 			device_printf(dev, "No _PSS\n");
539 			goto fetch_ppc;
540 		}
541 		device_printf(dev, "Can't get _PSS package - %s\n",
542 			      AcpiFormatException(status));
543 		return ENXIO;
544 	}
545 
546 	obj = (ACPI_OBJECT *)buf.Pointer;
547 	if (!ACPI_PKG_VALID(obj, 1)) {
548 		device_printf(dev, "Invalid _PSS package\n");
549 		AcpiOsFree(obj);
550 		return ENXIO;
551 	}
552 
553 	/* Don't create too many P-States */
554 	npstate = obj->Package.Count;
555 	if (npstate > ACPI_NPSTATE_MAX) {
556 		device_printf(dev, "Too many P-States, %d->%d\n",
557 			      npstate, ACPI_NPSTATE_MAX);
558 		npstate = ACPI_NPSTATE_MAX;
559 	}
560 
561 	/*
562 	 * If we have already created P-State table,
563 	 * we must make sure that number of entries
564 	 * is consistent.
565 	 */
566 	if (acpi_pstates != NULL && acpi_npstates != npstate) {
567 		device_printf(dev, "Inconsistent # of P-States "
568 			      "cross Processor objects\n");
569 		AcpiOsFree(obj);
570 		return ENXIO;
571 	}
572 
573 	/*
574 	 * Create a temporary P-State table
575 	 */
576 	pstate = kmalloc(sizeof(*pstate) * npstate, M_TEMP, M_WAITOK);
577 	for (i = 0, p = pstate; i < npstate; ++i, ++p) {
578 		ACPI_OBJECT *pkg;
579 		uint32_t *ptr[ACPI_PSS_PX_NENTRY] = {
580 			&p->st_freq, &p->st_power, &p->st_xsit_lat,
581 			&p->st_bm_lat, &p->st_cval, &p->st_sval
582 		};
583 		int j;
584 
585 		pkg = &obj->Package.Elements[i];
586 		if (!ACPI_PKG_VALID(pkg, ACPI_PSS_PX_NENTRY)) {
587 			device_printf(dev, "Invalud _PSS P%d\n", i);
588 			AcpiOsFree(obj);
589 			kfree(pstate, M_TEMP);
590 			return ENXIO;
591 		}
592 		for (j = 0; j < ACPI_PSS_PX_NENTRY; ++j) {
593 			if (acpi_PkgInt32(pkg, j, ptr[j]) != 0) {
594 				device_printf(dev, "Can't extract "
595 					      "_PSS P%d %dth entry\n", i, j);
596 				AcpiOsFree(obj);
597 				kfree(pstate, M_TEMP);
598 				return ENXIO;
599 			}
600 		}
601 		if (p->st_freq & 0x80000000) {
602 			device_printf(dev, "Invalid _PSS P%d freq: 0x%08x\n",
603 			    i, p->st_freq);
604 			AcpiOsFree(obj);
605 			kfree(pstate, M_TEMP);
606 			return ENXIO;
607 		}
608 	}
609 
610 	/* Free _PSS */
611 	AcpiOsFree(obj);
612 
613 	if (acpi_pstates == NULL) {
614 		/*
615 		 * If no P-State table is created yet,
616 		 * save the temporary one we just created.
617 		 */
618 		acpi_pstates = pstate;
619 		acpi_npstates = npstate;
620 		pstate = NULL;
621 
622 		if (bootverbose) {
623 			for (i = 0; i < acpi_npstates; ++i) {
624 				device_printf(dev,
625 				"freq %u, pwr %u, xlat %u, blat %u, "
626 				"cv %08x, sv %08x\n",
627 				acpi_pstates[i].st_freq,
628 				acpi_pstates[i].st_power,
629 				acpi_pstates[i].st_xsit_lat,
630 				acpi_pstates[i].st_bm_lat,
631 				acpi_pstates[i].st_cval,
632 				acpi_pstates[i].st_sval);
633 			}
634 		}
635 	} else {
636 		/*
637 		 * Make sure that P-State tables are same
638 		 * for all processors.
639 		 */
640 		if (memcmp(pstate, acpi_pstates,
641 			   sizeof(*pstate) * npstate) != 0) {
642 			device_printf(dev, "Inconsistent _PSS "
643 				      "cross Processor objects\n");
644 #if 0
645 			/*
646 			 * Some BIOSes create different P-State tables;
647 			 * just trust the one from the BSP and move on.
648 			 */
649 			kfree(pstate, M_TEMP);
650 			return ENXIO;
651 #endif
652 		}
653 		kfree(pstate, M_TEMP);
654 	}
655 
656 fetch_ppc:
657 	/* By default, we start from P-State table's first entry */
658 	sstart = 0;
659 
660 	/*
661 	 * Adjust the usable first entry of P-State table,
662 	 * if there is _PPC object.
663 	 */
664 	error = acpi_pst_eval_ppc(sc, &sstart);
665 	if (error && error != ENOENT)
666 		return error;
667 	else if (!error)
668 		sc->pst_flags |= ACPI_PST_FLAG_PPC;
669 	if (acpi_pstate_start < 0) {
670 		acpi_pstate_start = sstart;
671 	} else if (acpi_pstate_start != sstart) {
672 		device_printf(dev, "_PPC mismatch, was %d, now %d\n",
673 		    acpi_pstate_start, sstart);
674 		if (acpi_pstate_start < sstart) {
675 			device_printf(dev, "_PPC %d -> %d\n",
676 			    acpi_pstate_start, sstart);
677 			acpi_pstate_start = sstart;
678 		}
679 	}
680 
681 	/*
682 	 * By default, we assume number of usable P-States is same as
683 	 * number of P-States.
684 	 */
685 	scount = acpi_npstates;
686 
687 	/*
688 	 * Allow users to override or set _PDL
689 	 */
690 	if (acpi_pst_pdl >= 0) {
691 		if (acpi_pst_pdl < acpi_npstates) {
692 			if (bootverbose) {
693 				device_printf(dev, "_PDL override %d\n",
694 				    acpi_pst_pdl);
695 			}
696 			scount = acpi_pst_pdl + 1;
697 			goto proc_pdl;
698 		} else {
699 			device_printf(dev, "Invalid _PDL override %d, "
700 			    "must be less than %d\n", acpi_pst_pdl,
701 			    acpi_npstates);
702 		}
703 	}
704 
705 	/*
706 	 * Adjust the number of usable entries in P-State table,
707 	 * if there is _PDL object.
708 	 */
709 	error = acpi_pst_eval_pdl(sc, &scount);
710 	if (error && error != ENOENT)
711 		return error;
712 	else if (!error)
713 		sc->pst_flags |= ACPI_PST_FLAG_PDL;
714 proc_pdl:
715 	if (acpi_pstate_count == 0) {
716 		acpi_pstate_count = scount;
717 	} else if (acpi_pstate_count != scount) {
718 		device_printf(dev, "_PDL mismatch, was %d, now %d\n",
719 		    acpi_pstate_count, scount);
720 		if (acpi_pstate_count > scount) {
721 			device_printf(dev, "_PDL %d -> %d\n",
722 			    acpi_pstate_count, scount);
723 			acpi_pstate_count = scount;
724 		}
725 	}
726 
727 	/*
728 	 * Some CPUs only have package P-states, but some BIOSes put each
729 	 * hyperthread to its own P-state domain; allow user to override.
730 	 */
731 	if (LIST_EMPTY(&dom->pd_pstlist) &&
732 	    (acpi_pst_force_pkg_domain ||
733 	     (cpu_vendor_id == CPU_VENDOR_INTEL &&
734 	      acpi_pst_intel_pkg_domain))) {
735 		cpumask_t mask;
736 
737 		mask = get_cpumask_from_level(sc->pst_cpuid, CHIP_LEVEL);
738 		if (CPUMASK_TESTNZERO(mask)) {
739 			struct acpi_pst_softc *pst = NULL;
740 			struct acpi_pst_domain *dom1;
741 
742 			LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) {
743 				LIST_FOREACH(pst, &dom1->pd_pstlist,
744 				    pst_link) {
745 					if (CPUMASK_TESTBIT(mask,
746 					    pst->pst_cpuid))
747 						break;
748 				}
749 				if (pst != NULL)
750 					break;
751 			}
752 			if (pst != NULL &&
753 			    memcmp(&pst->pst_creg, &sc->pst_creg,
754 			        sizeof(sc->pst_creg)) == 0 &&
755 			    memcmp(&pst->pst_sreg, &sc->pst_sreg,
756 			        sizeof(sc->pst_sreg)) == 0) {
757 				/*
758 				 * Use the same domain for CPUs in the
759 				 * same package.
760 				 */
761 				device_printf(dev, "Destroy domain%u, "
762 				    "force pkg domain%u\n",
763 				    dom->pd_dom, dom1->pd_dom);
764 				LIST_REMOVE(dom, pd_link);
765 				kfree(dom, M_DEVBUF);
766 				dom = dom1;
767 				/*
768 				 * Make sure that adding us will not
769 				 * overflow the domain containing
770 				 * siblings in the same package.
771 				 */
772 				acpi_pst_domain_check_nproc(dev, dom);
773 			}
774 		}
775 	}
776 
777 	/* Link us with the domain */
778 	sc->pst_domain = dom;
779 	LIST_INSERT_HEAD(&dom->pd_pstlist, sc, pst_link);
780 
781 	if (device_get_unit(dev) == 0)
782 		AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_pst_postattach, NULL);
783 
784 	if (sc->pst_flags & (ACPI_PST_FLAG_PPC | ACPI_PST_FLAG_PDL))
785 		sc->pst_parent->cpu_pst_notify = acpi_pst_notify;
786 
787 	return 0;
788 }
789 
790 static struct acpi_pst_domain *
791 acpi_pst_domain_create_pkg(device_t dev, ACPI_OBJECT *obj)
792 {
793 	struct acpi_pst_domain *dom;
794 	uint32_t val, domain, coord, nproc;
795 
796 	if (!ACPI_PKG_VALID_EQ(obj, 5)) {
797 		device_printf(dev, "Invalid _PSD package\n");
798 		return NULL;
799 	}
800 
801 	/* NumberOfEntries */
802 	if (acpi_PkgInt32(obj, 0, &val) != 0 || val != 5) {
803 		device_printf(dev, "Invalid _PSD NumberOfEntries\n");
804 		return NULL;
805 	}
806 
807 	/* Revision */
808 	if (acpi_PkgInt32(obj, 1, &val) != 0 || val != 0) {
809 		device_printf(dev, "Invalid _PSD Revision\n");
810 		return NULL;
811 	}
812 
813 	if (acpi_PkgInt32(obj, 2, &domain) != 0 ||
814 	    acpi_PkgInt32(obj, 3, &coord) != 0 ||
815 	    acpi_PkgInt32(obj, 4, &nproc) != 0) {
816 		device_printf(dev, "Can't extract _PSD package\n");
817 		return NULL;
818 	}
819 
820 	if (!ACPI_PSD_COORD_VALID(coord)) {
821 		device_printf(dev, "Invalid _PSD CoordType (%#x)\n", coord);
822 		return NULL;
823 	}
824 
825 	if (nproc > MAXCPU) {
826 		/*
827 		 * If NumProcessors is greater than MAXCPU
828 		 * and domain's coordination is SWALL, then
829 		 * we will never be able to start all CPUs
830 		 * within this domain, and power state
831 		 * transition will never be completed, so we
832 		 * just bail out here.
833 		 */
834 		if (coord == ACPI_PSD_COORD_SWALL) {
835 			device_printf(dev, "Unsupported _PSD NumProcessors "
836 				      "(%d)\n", nproc);
837 			return NULL;
838 		}
839 	} else if (nproc == 0) {
840 		device_printf(dev, "_PSD NumProcessors are zero\n");
841 		return NULL;
842 	}
843 
844 	dom = acpi_pst_domain_find(domain);
845 	if (dom != NULL) {
846 		if (dom->pd_flags & ACPI_PSTDOM_FLAG_INT) {
847 			device_printf(dev, "Mixed Integer _PSD and "
848 			    "Package _PSD\n");
849 			return NULL;
850 		}
851 		if (dom->pd_coord != coord) {
852 			device_printf(dev, "Inconsistent _PSD coord "
853 			    "information cross Processor objects\n");
854 			return NULL;
855 		}
856 		if (dom->pd_nproc != nproc) {
857 			device_printf(dev, "Inconsistent _PSD nproc "
858 			    "information cross Processor objects\n");
859 			/*
860 			 * Some stupid BIOSes will set wrong "# of processors",
861 			 * e.g. 1 for CPU w/ hyperthreading; Be lenient here.
862 			 */
863 		}
864 		return dom;
865 	}
866 
867 	dom = acpi_pst_domain_alloc(domain, coord, nproc);
868 	if (bootverbose) {
869 		device_printf(dev, "create pkg domain%u, coord %#x\n",
870 		    dom->pd_dom, dom->pd_coord);
871 	}
872 
873 	return dom;
874 }
875 
876 static struct acpi_pst_domain *
877 acpi_pst_domain_create_int(device_t dev, uint32_t domain)
878 {
879 	struct acpi_pst_domain *dom;
880 
881 	dom = acpi_pst_domain_find(domain);
882 	if (dom != NULL) {
883 		if ((dom->pd_flags & ACPI_PSTDOM_FLAG_INT) == 0) {
884 			device_printf(dev, "Mixed Package _PSD and "
885 			    "Integer _PSD\n");
886 			return NULL;
887 		}
888 		KKASSERT(dom->pd_coord == ACPI_PSD_COORD_SWALL);
889 
890 		dom->pd_nproc++;
891 		return dom;
892 	}
893 
894 	dom = acpi_pst_domain_alloc(domain, ACPI_PSD_COORD_SWALL, 1);
895 	dom->pd_flags |= ACPI_PSTDOM_FLAG_INT;
896 
897 	if (bootverbose)
898 		device_printf(dev, "create int domain%u\n", dom->pd_dom);
899 
900 	return dom;
901 }
902 
903 static struct acpi_pst_domain *
904 acpi_pst_domain_find(uint32_t domain)
905 {
906 	struct acpi_pst_domain *dom;
907 
908 	LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
909 		if (dom->pd_flags & ACPI_PSTDOM_FLAG_STUB)
910 			continue;
911 		if (dom->pd_dom == domain)
912 			return dom;
913 	}
914 	return NULL;
915 }
916 
917 static struct acpi_pst_domain *
918 acpi_pst_domain_alloc(uint32_t domain, uint32_t coord, uint32_t nproc)
919 {
920 	struct acpi_pst_domain *dom;
921 
922 	dom = kmalloc(sizeof(*dom), M_DEVBUF, M_WAITOK | M_ZERO);
923 	dom->pd_dom = domain;
924 	dom->pd_coord = coord;
925 	dom->pd_nproc = nproc;
926 	LIST_INIT(&dom->pd_pstlist);
927 	lwkt_serialize_init(&dom->pd_serialize);
928 
929 	LIST_INSERT_HEAD(&acpi_pst_domains, dom, pd_link);
930 
931 	return dom;
932 }
933 
934 static void
935 acpi_pst_domain_set_pstate_locked(struct acpi_pst_domain *dom, int i, int *global)
936 {
937 	const struct acpi_pstate *pstate;
938 	struct acpi_pst_softc *sc;
939 	int done, error;
940 
941 	ASSERT_SERIALIZED(&dom->pd_serialize);
942 
943 	KKASSERT(i >= 0 && i < acpi_npstates);
944 	pstate = &acpi_pstates[i];
945 
946 	done = 0;
947 	LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
948 		if (!done) {
949 			error = acpi_pst_set_pstate(sc, pstate);
950 			if (error) {
951 				device_printf(sc->pst_dev, "can't set "
952 					      "freq %d\n", pstate->st_freq);
953 				/* XXX error cleanup? */
954 			}
955 			if (dom->pd_coord == ACPI_PSD_COORD_SWANY)
956 				done = 1;
957 		}
958 		sc->pst_state = i;
959 	}
960 	dom->pd_state = i;
961 
962 	if (global != NULL)
963 		*global = i;
964 }
965 
966 static void
967 acpi_pst_domain_set_pstate(struct acpi_pst_domain *dom, int i, int *global)
968 {
969 	lwkt_serialize_enter(&dom->pd_serialize);
970 	acpi_pst_domain_set_pstate_locked(dom, i, global);
971 	lwkt_serialize_exit(&dom->pd_serialize);
972 }
973 
974 static void
975 acpi_pst_global_set_pstate(int i)
976 {
977 	struct acpi_pst_domain *dom;
978 	int *global = &acpi_pst_global_state;
979 
980 	LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
981 		/* Skip dead domain */
982 		if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD)
983 			continue;
984 		acpi_pst_domain_set_pstate(dom, i, global);
985 		global = NULL;
986 	}
987 }
988 
989 static void
990 acpi_pst_global_fixup_pstate(void)
991 {
992 	struct acpi_pst_domain *dom;
993 	int *global = &acpi_pst_global_state;
994 	int sstart, scount;
995 
996 	sstart = acpi_pstate_start;
997 	scount = acpi_pstate_count;
998 
999 	LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
1000 		int i = -1;
1001 
1002 		/* Skip dead domain */
1003 		if (dom->pd_flags & ACPI_PSTDOM_FLAG_DEAD)
1004 			continue;
1005 
1006 		lwkt_serialize_enter(&dom->pd_serialize);
1007 
1008 		if (global != NULL) {
1009 			if (*global < sstart)
1010 				*global = sstart;
1011 			else if (*global >= scount)
1012 				*global = scount - 1;
1013 			global = NULL;
1014 		}
1015 		if (dom->pd_state < sstart)
1016 			i = sstart;
1017 		else if (dom->pd_state >= scount)
1018 			i = scount - 1;
1019 		if (i >= 0)
1020 			acpi_pst_domain_set_pstate_locked(dom, i, NULL);
1021 
1022 		lwkt_serialize_exit(&dom->pd_serialize);
1023 	}
1024 }
1025 
1026 static void
1027 acpi_pst_postattach(void *arg __unused)
1028 {
1029 	struct acpi_pst_domain *dom;
1030 	struct acpi_cpu_softc *cpu;
1031 	device_t *devices;
1032 	int i, ndevices, error, has_domain;
1033 
1034 	devices = NULL;
1035 	ndevices = 0;
1036 	error = devclass_get_devices(acpi_pst_devclass, &devices, &ndevices);
1037 	if (error)
1038 		return;
1039 
1040 	if (ndevices == 0)
1041 		return;
1042 
1043 	cpu = NULL;
1044 	for (i = 0; i < ndevices; ++i) {
1045 		cpu = device_get_softc(device_get_parent(devices[i]));
1046 		if (cpu->glob_sysctl_tree != NULL)
1047 			break;
1048 	}
1049 	kfree(devices, M_TEMP);
1050 	KKASSERT(cpu != NULL);
1051 
1052 	if (acpi_pst_md == NULL)
1053 		kprintf("ACPI: no P-State CPU driver\n");
1054 
1055 	has_domain = 0;
1056 	LIST_FOREACH(dom, &acpi_pst_domains, pd_link) {
1057 		struct acpi_pst_softc *sc;
1058 		char buf[32];
1059 
1060 		dom->pd_state = acpi_pstate_start;
1061 
1062 		/*
1063 		 * Make sure that all processors belonging to this
1064 		 * domain are located.
1065 		 */
1066 		i = 0;
1067 		LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1068 			sc->pst_state = acpi_pstate_start;
1069 			++i;
1070 		}
1071 		if (i != dom->pd_nproc) {
1072 			KKASSERT(i < dom->pd_nproc);
1073 
1074 			kprintf("ACPI: domain%u misses processors, "
1075 				"should be %d, got %d\n", dom->pd_dom,
1076 				dom->pd_nproc, i);
1077 			if (dom->pd_coord == ACPI_PSD_COORD_SWALL) {
1078 				/*
1079 				 * If this domain's coordination is
1080 				 * SWALL and we don't see all of the
1081 				 * member CPUs of this domain, then
1082 				 * the P-State transition will never
1083 				 * be completed, so just leave this
1084 				 * domain out.
1085 				 */
1086 				dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1087 				continue;
1088 			}
1089 			dom->pd_nproc = i;
1090 		}
1091 
1092 		/*
1093 		 * Validate P-State configurations for this domain
1094 		 */
1095 		LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1096 			error = acpi_pst_check_csr(sc);
1097 			if (error)
1098 				break;
1099 
1100 			error = acpi_pst_check_pstates(sc);
1101 			if (error)
1102 				break;
1103 		}
1104 		if (sc != NULL) {
1105 			kprintf("ACPI: domain%u P-State configuration "
1106 				"check failed\n", dom->pd_dom);
1107 			dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1108 			continue;
1109 		}
1110 
1111 		/*
1112 		 * Do necssary P-State initialization
1113 		 */
1114 		LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1115 			error = acpi_pst_init(sc);
1116 			if (error)
1117 				break;
1118 		}
1119 		if (sc != NULL) {
1120 			kprintf("ACPI: domain%u P-State initialization "
1121 				"check failed\n", dom->pd_dom);
1122 			dom->pd_flags |= ACPI_PSTDOM_FLAG_DEAD;
1123 			continue;
1124 		}
1125 
1126 		has_domain = 1;
1127 
1128 		ksnprintf(buf, sizeof(buf), "px_dom%u", dom->pd_dom);
1129 
1130 		sysctl_ctx_init(&dom->pd_sysctl_ctx);
1131 		dom->pd_sysctl_tree =
1132 		SYSCTL_ADD_NODE(&dom->pd_sysctl_ctx,
1133 			SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1134 			OID_AUTO, buf, CTLFLAG_RD, 0,
1135 			"P-State domain");
1136 		if (dom->pd_sysctl_tree == NULL) {
1137 			kprintf("ACPI: Can't create sysctl tree for domain%u",
1138 				dom->pd_dom);
1139 			continue;
1140 		}
1141 
1142 		SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1143 				SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1144 				OID_AUTO, "available",
1145 				CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP,
1146 				dom, 0, acpi_pst_sysctl_freqs, "A",
1147 				"available frequencies");
1148 
1149 		SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1150 				SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1151 				OID_AUTO, "avail",
1152 				CTLTYPE_OPAQUE | CTLFLAG_RD,
1153 				dom, 0, acpi_pst_sysctl_freqs_bin, "IU",
1154 				"available frequencies");
1155 
1156 		SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1157 				SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1158 				OID_AUTO, "power",
1159 				CTLTYPE_OPAQUE | CTLFLAG_RD,
1160 				dom, 0, acpi_pst_sysctl_power, "IU",
1161 				"power of available frequencies");
1162 
1163 		SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1164 				SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1165 				OID_AUTO, "members",
1166 				CTLTYPE_STRING | CTLFLAG_RD,
1167 				dom, 0, acpi_pst_sysctl_members, "A",
1168 				"member cpus");
1169 
1170 		if (acpi_pst_md != NULL &&
1171 		    acpi_pst_md->pmd_set_pstate != NULL) {
1172 			SYSCTL_ADD_PROC(&dom->pd_sysctl_ctx,
1173 					SYSCTL_CHILDREN(dom->pd_sysctl_tree),
1174 					OID_AUTO, "select",
1175 					CTLTYPE_UINT | CTLFLAG_RW,
1176 					dom, 0, acpi_pst_sysctl_select,
1177 					"IU", "select freq");
1178 		}
1179 	}
1180 
1181 	if (has_domain && acpi_pst_md != NULL &&
1182 	    acpi_pst_md->pmd_set_pstate != NULL) {
1183 		SYSCTL_ADD_PROC(&cpu->glob_sysctl_ctx,
1184 				SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1185 				OID_AUTO, "px_global",
1186 				CTLTYPE_UINT | CTLFLAG_RW,
1187 				NULL, 0, acpi_pst_sysctl_global,
1188 				"IU", "select freq for all domains");
1189 		SYSCTL_ADD_INT(&cpu->glob_sysctl_ctx,
1190 			       SYSCTL_CHILDREN(cpu->glob_sysctl_tree),
1191 			       OID_AUTO, "px_handle_notify", CTLFLAG_RW,
1192 			       &acpi_pst_handle_notify, 0,
1193 			       "handle type 0x80 notify");
1194 
1195 		acpi_pst_global_set_pstate(acpi_pstate_start);
1196 	}
1197 }
1198 
1199 static int
1200 acpi_pst_sysctl_freqs(SYSCTL_HANDLER_ARGS)
1201 {
1202 	int i, error, sstart, scount;
1203 
1204 	error = 0;
1205 	sstart = acpi_pstate_start;
1206 	scount = acpi_pstate_count;
1207 	for (i = 0; i < acpi_npstates; ++i) {
1208 		if (error == 0 && i)
1209 			error = SYSCTL_OUT(req, " ", 1);
1210 		if (error == 0) {
1211 			const char *pat;
1212 			char buf[32];
1213 
1214 			if (i < sstart || i >= scount)
1215 				pat = "(%u)";
1216 			else
1217 				pat = "%u";
1218 
1219 			ksnprintf(buf, sizeof(buf), pat,
1220 				  acpi_pstates[i].st_freq);
1221 			error = SYSCTL_OUT(req, buf, strlen(buf));
1222 		}
1223 	}
1224 	return error;
1225 }
1226 
1227 static int
1228 acpi_pst_sysctl_freqs_bin(SYSCTL_HANDLER_ARGS)
1229 {
1230 	uint32_t freqs[ACPI_NPSTATE_MAX];
1231 	int cnt, i, sstart, scount;
1232 
1233 	sstart = acpi_pstate_start;
1234 	scount = acpi_pstate_count;
1235 
1236 	cnt = scount - sstart;
1237 	for (i = 0; i < cnt; ++i)
1238 		freqs[i] = acpi_pstates[sstart + i].st_freq;
1239 
1240 	return sysctl_handle_opaque(oidp, freqs, cnt * sizeof(freqs[0]), req);
1241 }
1242 
1243 static int
1244 acpi_pst_sysctl_power(SYSCTL_HANDLER_ARGS)
1245 {
1246 	uint32_t power[ACPI_NPSTATE_MAX];
1247 	int cnt, i, sstart, scount;
1248 
1249 	sstart = acpi_pstate_start;
1250 	scount = acpi_pstate_count;
1251 
1252 	cnt = scount - sstart;
1253 	for (i = 0; i < cnt; ++i)
1254 		power[i] = acpi_pstates[sstart + i].st_power;
1255 
1256 	return sysctl_handle_opaque(oidp, power, cnt * sizeof(power[0]), req);
1257 }
1258 
1259 static int
1260 acpi_pst_sysctl_members(SYSCTL_HANDLER_ARGS)
1261 {
1262 	struct acpi_pst_domain *dom = arg1;
1263 	struct acpi_pst_softc *sc;
1264 	int loop, error;
1265 
1266 	loop = error = 0;
1267 	LIST_FOREACH(sc, &dom->pd_pstlist, pst_link) {
1268 		char buf[32];
1269 
1270 		if (error == 0 && loop)
1271 			error = SYSCTL_OUT(req, " ", 1);
1272 		if (error == 0) {
1273 			ksnprintf(buf, sizeof(buf), "cpu%d", sc->pst_cpuid);
1274 			error = SYSCTL_OUT(req, buf, strlen(buf));
1275 		}
1276 
1277 		if (error == 0 && acpi_pst_md && acpi_pst_md->pmd_get_pstate) {
1278 			const struct acpi_pstate *pstate;
1279 			const char *str;
1280 
1281 			pstate = acpi_pst_get_pstate(sc);
1282 			if (pstate == NULL) {
1283 				str = "(*)";
1284 			} else {
1285 				ksnprintf(buf, sizeof(buf), "(%d)",
1286 					  pstate->st_freq);
1287 				str = buf;
1288 			}
1289 			error = SYSCTL_OUT(req, str, strlen(str));
1290 		}
1291 		++loop;
1292 	}
1293 	return error;
1294 }
1295 
1296 static int
1297 acpi_pst_sysctl_select(SYSCTL_HANDLER_ARGS)
1298 {
1299 	struct acpi_pst_domain *dom = arg1;
1300 	int error, i, freq;
1301 
1302 	KKASSERT(dom->pd_state >= 0 && dom->pd_state < acpi_npstates);
1303 
1304 	freq = acpi_pstates[dom->pd_state].st_freq;
1305 
1306 	error = sysctl_handle_int(oidp, &freq, 0, req);
1307 	if (error || req->newptr == NULL)
1308 		return error;
1309 
1310 	i = acpi_pst_freq2index(freq);
1311 	if (i < 0)
1312 		return EINVAL;
1313 
1314 	acpi_pst_domain_set_pstate(dom, i, NULL);
1315 	return 0;
1316 }
1317 
1318 static int
1319 acpi_pst_sysctl_global(SYSCTL_HANDLER_ARGS)
1320 {
1321 	int error, i, freq;
1322 
1323 	KKASSERT(acpi_pst_global_state >= 0 &&
1324 		 acpi_pst_global_state < acpi_npstates);
1325 
1326 	freq = acpi_pstates[acpi_pst_global_state].st_freq;
1327 
1328 	error = sysctl_handle_int(oidp, &freq, 0, req);
1329 	if (error || req->newptr == NULL)
1330 		return error;
1331 
1332 	i = acpi_pst_freq2index(freq);
1333 	if (i < 0)
1334 		return EINVAL;
1335 
1336 	acpi_pst_global_set_pstate(i);
1337 
1338 	return 0;
1339 }
1340 
1341 static void
1342 acpi_pst_check_csr_handler(struct cpuhelper_msg *msg)
1343 {
1344 	struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg;
1345 	int error;
1346 
1347 	error = acpi_pst_md->pmd_check_csr(pmsg->ch_ctrl, pmsg->ch_status);
1348 	cpuhelper_replymsg(msg, error);
1349 }
1350 
1351 static int
1352 acpi_pst_check_csr(struct acpi_pst_softc *sc)
1353 {
1354 	struct acpi_pst_chmsg msg;
1355 
1356 	if (acpi_pst_md == NULL)
1357 		return 0;
1358 
1359 	cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport,
1360 	    acpi_pst_check_csr_handler, NULL, MSGF_PRIORITY);
1361 	msg.ch_ctrl = &sc->pst_creg;
1362 	msg.ch_status = &sc->pst_sreg;
1363 
1364 	return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid));
1365 }
1366 
1367 static void
1368 acpi_pst_check_pstates_handler(struct cpuhelper_msg *msg)
1369 {
1370 	int error;
1371 
1372 	error = acpi_pst_md->pmd_check_pstates(acpi_pstates, acpi_npstates);
1373 	cpuhelper_replymsg(msg, error);
1374 }
1375 
1376 static int
1377 acpi_pst_check_pstates(struct acpi_pst_softc *sc)
1378 {
1379 	struct cpuhelper_msg msg;
1380 
1381 	if (acpi_pst_md == NULL)
1382 		return 0;
1383 
1384 	cpuhelper_initmsg(&msg, &curthread->td_msgport,
1385 	    acpi_pst_check_pstates_handler, NULL, MSGF_PRIORITY);
1386 	return (cpuhelper_domsg(&msg, sc->pst_cpuid));
1387 }
1388 
1389 static void
1390 acpi_pst_init_handler(struct cpuhelper_msg *msg)
1391 {
1392 	struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg;
1393 	int error;
1394 
1395 	error = acpi_pst_md->pmd_init(pmsg->ch_ctrl, pmsg->ch_status);
1396 	cpuhelper_replymsg(msg, error);
1397 }
1398 
1399 static int
1400 acpi_pst_init(struct acpi_pst_softc *sc)
1401 {
1402 	struct acpi_pst_chmsg msg;
1403 
1404 	if (acpi_pst_md == NULL)
1405 		return 0;
1406 
1407 	cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport,
1408 	    acpi_pst_init_handler, NULL, MSGF_PRIORITY);
1409 	msg.ch_ctrl = &sc->pst_creg;
1410 	msg.ch_status = &sc->pst_sreg;
1411 
1412 	return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid));
1413 }
1414 
1415 static void
1416 acpi_pst_set_pstate_handler(struct cpuhelper_msg *msg)
1417 {
1418 	struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg;
1419 	int error;
1420 
1421 	error = acpi_pst_md->pmd_set_pstate(pmsg->ch_ctrl, pmsg->ch_status,
1422 	    msg->ch_cbarg);
1423 	cpuhelper_replymsg(msg, error);
1424 }
1425 
1426 static int
1427 acpi_pst_set_pstate(struct acpi_pst_softc *sc, const struct acpi_pstate *pstate)
1428 {
1429 	struct acpi_pst_chmsg msg;
1430 
1431 	KKASSERT(acpi_pst_md != NULL);
1432 
1433 	cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport,
1434 	    acpi_pst_set_pstate_handler, __DECONST(void *, pstate),
1435 	    MSGF_PRIORITY);
1436 	msg.ch_ctrl = &sc->pst_creg;
1437 	msg.ch_status = &sc->pst_sreg;
1438 
1439 	return (cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid));
1440 }
1441 
1442 static void
1443 acpi_pst_get_pstate_handler(struct cpuhelper_msg *msg)
1444 {
1445 	struct acpi_pst_chmsg *pmsg = (struct acpi_pst_chmsg *)msg;
1446 	const struct acpi_pstate *pstate;
1447 
1448 	pstate = acpi_pst_md->pmd_get_pstate(pmsg->ch_status, acpi_pstates,
1449 	    acpi_npstates);
1450 	msg->ch_cbarg = __DECONST(void *, pstate);
1451 	cpuhelper_replymsg(msg, 0);
1452 }
1453 
1454 static const struct acpi_pstate *
1455 acpi_pst_get_pstate(struct acpi_pst_softc *sc)
1456 {
1457 	struct acpi_pst_chmsg msg;
1458 
1459 	if (acpi_pst_md == NULL)
1460 		return 0;
1461 
1462 	cpuhelper_initmsg(&msg.ch_msg, &curthread->td_msgport,
1463 	    acpi_pst_get_pstate_handler, NULL, MSGF_PRIORITY);
1464 	msg.ch_status = &sc->pst_sreg;
1465 
1466 	cpuhelper_domsg(&msg.ch_msg, sc->pst_cpuid);
1467 	return (msg.ch_msg.ch_cbarg);
1468 }
1469 
1470 static int
1471 acpi_pst_alloc_resource(device_t dev, ACPI_OBJECT *obj, int idx,
1472 			struct acpi_pst_res *res)
1473 {
1474 	struct acpi_pst_softc *sc = device_get_softc(dev);
1475 	int error, type;
1476 
1477 	/* Save GAS */
1478 	error = acpi_PkgRawGas(obj, idx, &res->pr_gas);
1479 	if (error)
1480 		return error;
1481 
1482 	/* Allocate resource, if possible */
1483 	res->pr_rid = sc->pst_parent->cpu_next_rid;
1484 	acpi_bus_alloc_gas(dev, &type, &res->pr_rid, &res->pr_gas, &res->pr_res, 0);
1485 	if (res->pr_res != NULL) {
1486 		sc->pst_parent->cpu_next_rid++;
1487 		res->pr_bt = rman_get_bustag(res->pr_res);
1488 		res->pr_bh = rman_get_bushandle(res->pr_res);
1489 	} else {
1490 		res->pr_rid = 0;
1491 	}
1492 	return 0;
1493 }
1494 
1495 static void
1496 acpi_pst_domain_check_nproc(device_t dev, struct acpi_pst_domain *dom)
1497 {
1498 	struct acpi_pst_softc *pst;
1499 	int i;
1500 
1501 	i = 0;
1502 	LIST_FOREACH(pst, &dom->pd_pstlist, pst_link)
1503 		++i;
1504 	if (i == dom->pd_nproc) {
1505 		/*
1506 		 * Some stupid BIOSes will set wrong "# of processors",
1507 		 * e.g. 1 for CPU w/ hyperthreading; Be lenient here.
1508 		 */
1509 		if (bootverbose) {
1510 			device_printf(dev, "domain%u already contains %d "
1511 			    "P-States\n", dom->pd_dom, dom->pd_nproc);
1512 		}
1513 		dom->pd_nproc++;
1514 	}
1515 	KKASSERT(i < dom->pd_nproc);
1516 }
1517 
1518 static int
1519 acpi_pst_eval_ppc(struct acpi_pst_softc *sc, int *sstart)
1520 {
1521 	ACPI_BUFFER buf;
1522 	ACPI_STATUS status;
1523 	ACPI_OBJECT *obj;
1524 
1525 	buf.Pointer = NULL;
1526 	buf.Length = ACPI_ALLOCATE_BUFFER;
1527 	status = AcpiEvaluateObject(sc->pst_handle, "_PPC", NULL, &buf);
1528 	if (!ACPI_FAILURE(status)) {
1529 		ACPI_OBJECT_LIST arglist;
1530 		ACPI_OBJECT arg[2];
1531 
1532 		obj = (ACPI_OBJECT *)buf.Pointer;
1533 		if (obj->Type == ACPI_TYPE_INTEGER) {
1534 			if (obj->Integer.Value >= acpi_npstates) {
1535 				device_printf(sc->pst_dev,
1536 				    "Invalid _PPC value\n");
1537 				AcpiOsFree(obj);
1538 				return ENXIO;
1539 			}
1540 			*sstart = obj->Integer.Value;
1541 			if (bootverbose) {
1542 				device_printf(sc->pst_dev, "_PPC %d\n",
1543 				    *sstart);
1544 			}
1545 		} else {
1546 			device_printf(sc->pst_dev, "Invalid _PPC object\n");
1547 			AcpiOsFree(obj);
1548 			return ENXIO;
1549 		}
1550 
1551 		/* Free _PPC */
1552 		AcpiOsFree(obj);
1553 
1554 		/* _PPC has been successfully processed */
1555 		arglist.Pointer = arg;
1556 		arglist.Count = 2;
1557 		arg[0].Type = ACPI_TYPE_INTEGER;
1558 		arg[0].Integer.Value = 0x80;
1559 		arg[1].Type = ACPI_TYPE_INTEGER;
1560 		arg[1].Integer.Value = 0;
1561 		AcpiEvaluateObject(sc->pst_handle, "_OST", &arglist, NULL);
1562 
1563 		return 0;
1564 	}
1565 	return ENOENT;
1566 }
1567 
1568 static int
1569 acpi_pst_eval_pdl(struct acpi_pst_softc *sc, int *scount)
1570 {
1571 	ACPI_BUFFER buf;
1572 	ACPI_STATUS status;
1573 	ACPI_OBJECT *obj;
1574 
1575 	buf.Pointer = NULL;
1576 	buf.Length = ACPI_ALLOCATE_BUFFER;
1577 	status = AcpiEvaluateObject(sc->pst_handle, "_PDL", NULL, &buf);
1578 	if (!ACPI_FAILURE(status)) {
1579 		obj = (ACPI_OBJECT *)buf.Pointer;
1580 		if (obj->Type == ACPI_TYPE_INTEGER) {
1581 			if (obj->Integer.Value >= acpi_npstates) {
1582 				device_printf(sc->pst_dev,
1583 				    "Invalid _PDL value\n");
1584 				AcpiOsFree(obj);
1585 				return ENXIO;
1586 			}
1587 			if (obj->Integer.Value >= acpi_pstate_start) {
1588 				*scount = obj->Integer.Value + 1;
1589 				if (bootverbose) {
1590 					device_printf(sc->pst_dev, "_PDL %d\n",
1591 					    *scount);
1592 				}
1593 			} else {
1594 				/* Prefer _PPC as stated in ACPI 5.1 8.4.4.6 */
1595 				device_printf(sc->pst_dev, "conflict _PDL %ju "
1596 				    "and _PPC %d, ignore\n",
1597 				    (uintmax_t)obj->Integer.Value,
1598 				    acpi_pstate_start);
1599 			}
1600 		} else {
1601 			device_printf(sc->pst_dev, "Invalid _PDL object\n");
1602 			AcpiOsFree(obj);
1603 			return ENXIO;
1604 		}
1605 
1606 		/* Free _PDL */
1607 		AcpiOsFree(obj);
1608 
1609 		return 0;
1610 	}
1611 	return ENOENT;
1612 }
1613 
1614 /*
1615  * Notify is serialized by acpi task thread.
1616  */
1617 static void
1618 acpi_pst_notify(device_t dev)
1619 {
1620 	struct acpi_pst_softc *sc = device_get_softc(dev);
1621 	boolean_t fixup = FALSE;
1622 
1623 	if (!acpi_pst_handle_notify)
1624 		return;
1625 
1626 	/*
1627 	 * NOTE:
1628 	 * _PPC and _PDL evaluation order is critical.  _PDL
1629 	 * evaluation depends on _PPC evaluation.
1630 	 */
1631 	if (sc->pst_flags & ACPI_PST_FLAG_PPC) {
1632 		int sstart = acpi_pstate_start;
1633 
1634 		acpi_pst_eval_ppc(sc, &sstart);
1635 		if (acpi_pstate_start != sstart && sc->pst_cpuid == 0) {
1636 			acpi_pstate_start = sstart;
1637 			fixup = TRUE;
1638 		}
1639 	}
1640 	if (sc->pst_flags & ACPI_PST_FLAG_PDL) {
1641 		int scount = acpi_pstate_count;
1642 
1643 		acpi_pst_eval_pdl(sc, &scount);
1644 		if (acpi_pstate_count != scount && sc->pst_cpuid == 0) {
1645 			acpi_pstate_count = scount;
1646 			fixup = TRUE;
1647 		}
1648 	}
1649 
1650 	if (fixup && acpi_pst_md != NULL &&
1651 	    acpi_pst_md->pmd_set_pstate != NULL)
1652 		acpi_pst_global_fixup_pstate();
1653 }
1654