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