2 * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * CPU-specific power management support.
26 * Implements the "wrappers" to the KEXT.
28 #include <i386/machine_routines.h>
29 #include <i386/machine_cpu.h>
30 #include <i386/misc_protos.h>
31 #include <i386/pmap.h>
34 #include <i386/proc_reg.h>
36 #include <kern/processor.h>
37 #include <i386/pmCPU.h>
38 #include <i386/cpuid.h>
40 #include <i386/db_machdep.h>
41 #include <ddb/db_aout.h>
42 #include <ddb/db_access.h>
43 #include <ddb/db_sym.h>
44 #include <ddb/db_variables.h>
45 #include <ddb/db_command.h>
46 #include <ddb/db_output.h>
47 #include <ddb/db_expr.h>
50 extern int disableConsoleOutput
;
52 decl_simple_lock_data(,pm_init_lock
);
55 * The following is set when the KEXT loads and initializes.
57 pmDispatch_t
*pmDispatch
= NULL
;
60 * Current power management states (for use until KEXT is loaded).
62 static pmInitState_t pmInitState
;
65 * Nap control variables:
67 uint32_t napCtl
= 0; /* Defaults to neither napping
69 uint32_t forcenap
= 0; /* Force nap (fn) boot-arg controls */
70 uint32_t maxBusDelay
= 0xFFFFFFFF; /* Maximum memory bus delay that
71 I/O devices can tolerate
72 before errors (nanoseconds) */
73 uint32_t C4C2SnoopDelay
= 0; /* C4 to C2 transition time -
74 time before a C4 system
75 can snoop (nanoseconds) */
78 * We are being asked to set PState (sel).
81 pmsCPUSet(uint32_t sel
)
83 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUSet
!= NULL
)
84 (*pmDispatch
->pmsCPUSet
)(sel
);
86 pmInitState
.PState
= sel
;
90 * This code configures the initial step tables. It should be called after
91 * the timebase frequency is initialized.
93 * Note that this is not used in normal operation. It is strictly for
94 * debugging/testing purposes.
100 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUConf
!= NULL
)
101 (*pmDispatch
->pmsCPUConf
)();
105 * Machine-dependent initialization.
108 pmsCPUMachineInit(void)
111 * Initialize some of the initial state to "uninitialized" until
112 * it gets set with something more useful. This allows the KEXT
113 * to determine if the initial value was actually set to something.
115 pmInitState
.PState
= -1;
116 pmInitState
.PLimit
= -1;
118 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUMachineInit
!= NULL
)
119 (*pmDispatch
->pmsCPUMachineInit
)();
123 * This function should be called once for each processor to force the
124 * processor to the correct initial voltage and frequency.
130 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUInit
!= NULL
)
131 (*pmDispatch
->pmsCPUInit
)();
135 * Broadcast a change to all processing including ourselves.
138 pmsCPURun(uint32_t nstep
)
140 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPURun
!= NULL
)
141 (*pmDispatch
->pmsCPURun
)(nstep
);
145 * Return the current state of a core.
150 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUQuery
!= NULL
)
151 return((*pmDispatch
->pmsCPUQuery
)());
154 * Return a non-sense value.
160 * Return the current state of the package.
163 pmsCPUPackageQuery(void)
165 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUPackageQuery
!= NULL
)
166 return((*pmDispatch
->pmsCPUPackageQuery
)());
169 * Return a non-sense value.
175 * Force the CPU package to the lowest power level. This is a low-level
176 * interface meant to be called from the panic or debugger code to bring
177 * the CPU to a safe power level for unmanaged operation.
179 * Note that while this will bring an entire package to a safe level, it
180 * cannot affect other packages. As a general rule, this should be run on
181 * every code as part of entering the debugger or on the panic path.
184 pmsCPUYellowFlag(void)
186 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUYellowFlag
!= NULL
)
187 (*pmDispatch
->pmsCPUYellowFlag
)();
191 * Restore the CPU to the power state it was in before a yellow flag.
194 pmsCPUGreenFlag(void)
196 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUGreenFlag
!= NULL
)
197 (*pmDispatch
->pmsCPUGreenFlag
)();
201 * Load a new ratio/VID table.
203 * Note that this interface is specific to the Intel SpeedStep implementation.
204 * It is expected that this will only be called once to override the default
205 * ratio/VID table when the platform starts.
207 * Normally, the table will need to be replaced at the same time that the
208 * stepper program proper is replaced, as the PState indices from an old
209 * program may no longer be valid. When replacing the default program this
210 * should not be a problem as any new table will have at least two PState
211 * entries and the default program only references P0 and P1.
214 pmsCPULoadVIDTable(uint16_t *tablep
, int nstates
)
216 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPULoadVIDTable
!= NULL
)
217 return((*pmDispatch
->pmsCPULoadVIDTable
)(tablep
, nstates
));
221 if (nstates
> MAX_PSTATES
)
222 return(KERN_FAILURE
);
224 for (i
= 0; i
< nstates
; i
+= 1)
225 pmInitState
.VIDTable
[i
] = tablep
[i
];
227 return(KERN_SUCCESS
);
231 * Set the (global) PState limit. CPUs will not be permitted to run at
232 * a lower (more performant) PState than this.
235 pmsCPUSetPStateLimit(uint32_t limit
)
237 if (pmDispatch
!= NULL
&& pmDispatch
->pmsCPUSetPStateLimit
!= NULL
)
238 return((*pmDispatch
->pmsCPUSetPStateLimit
)(limit
));
240 pmInitState
.PLimit
= limit
;
241 return(KERN_SUCCESS
);
245 * Initialize the Cstate change code.
248 power_management_init(void)
255 * Initialize the lock for the KEXT initialization.
257 simple_lock_init(&pm_init_lock
, 0);
262 * The following is a hack to disable power management on some systems
263 * until the KEXT is done. This is strictly temporary!!!
266 cpuFamily
= (xcpuid
[eax
] >> 8) & 0xf;
267 cpuModel
= (xcpuid
[eax
] >> 4) & 0xf;
269 if (cpuFamily
!= 0x6 || cpuModel
< 0xe)
272 if (pmDispatch
!= NULL
&& pmDispatch
->cstateInit
!= NULL
)
273 (*pmDispatch
->cstateInit
)();
277 * This function will update the system nap policy. It should be called
278 * whenever conditions change: when the system is ready to being napping
279 * and if something changes the rules (e.g. a sysctl altering the policy
283 machine_nap_policy(void)
285 if (pmDispatch
!= NULL
&& pmDispatch
->cstateNapPolicy
!= NULL
)
286 napCtl
= (*pmDispatch
->cstateNapPolicy
)(forcenap
, napCtl
);
290 * ACPI calls the following routine to set/update mwait hints. A table
291 * (possibly null) specifies the available Cstates and their hints, all
292 * other states are assumed to be invalid. ACPI may update available
293 * states to change the nap policy (for example, while AC power is
297 Cstate_table_set(Cstate_hint_t
*tablep
, unsigned int nstates
)
300 return(KERN_SUCCESS
);
302 if (pmDispatch
!= NULL
&& pmDispatch
->cstateTableSet
!= NULL
)
303 return((*pmDispatch
->cstateTableSet
)(tablep
, nstates
));
307 for (i
= 0; i
< nstates
; i
+= 1) {
308 pmInitState
.CStates
[i
].number
= tablep
[i
].number
;
309 pmInitState
.CStates
[i
].hint
= tablep
[i
].hint
;
312 pmInitState
.CStatesCount
= nstates
;
314 return(KERN_SUCCESS
);
319 __asm__
volatile ( "sti" : : : "memory");
323 * Called when the CPU is idle. It will choose the best C state to
327 machine_idle_cstate(void)
329 if (pmDispatch
!= NULL
&& pmDispatch
->cstateMachineIdle
!= NULL
)
330 (*pmDispatch
->cstateMachineIdle
)(napCtl
);
341 pp
= current_cpu_datap();
342 return(&pp
->cpu_pmStats
);
346 pmsCPUStepperData(void)
350 pp
= current_cpu_datap();
358 pp
= current_cpu_datap();
359 return(pp
->cpu_pmHpet
);
363 * Called by the power management kext to register itself and to get the
364 * callbacks it might need into other power management functions.
367 pmRegister(pmDispatch_t
*cpuFuncs
, pmCallBacks_t
*callbacks
)
369 if (callbacks
!= NULL
) {
370 callbacks
->Park
= pmsPark
;
371 callbacks
->Run
= pmsRun
;
372 callbacks
->RunLocal
= pmsRunLocal
;
373 callbacks
->SetStep
= pmsSetStep
;
374 callbacks
->NapPolicy
= machine_nap_policy
;
375 callbacks
->Build
= pmsBuild
;
376 callbacks
->Stats
= pmsCPUStats
;
377 callbacks
->StepperData
= pmsCPUStepperData
;
378 callbacks
->HPETAddr
= CPUHPETAddr
;
379 callbacks
->InitState
= &pmInitState
;
382 if (cpuFuncs
!= NULL
)
383 pmDispatch
= cpuFuncs
;
387 * Unregisters the power management functions from the kext.
390 pmUnRegister(pmDispatch_t
*cpuFuncs
)
392 if (cpuFuncs
!= NULL
&& pmDispatch
== cpuFuncs
)
401 db_cfg(__unused db_expr_t addr
,
402 __unused
int have_addr
,
403 __unused db_expr_t count
,
404 __unused
char *modif
)
410 db_display_iokit(__unused db_expr_t addr
,
411 __unused
int have_addr
,
412 __unused db_expr_t count
,
413 __unused
char *modif
)
419 db_dtimers(__unused db_expr_t addr
,
420 __unused
int have_addr
,
421 __unused db_expr_t count
,
422 __unused
char *modif
)
428 db_intcnt(__unused db_expr_t addr
,
429 __unused
int have_addr
,
430 __unused db_expr_t count
,
431 __unused
char *modif
)
437 db_nap(__unused db_expr_t addr
,
438 __unused
int have_addr
,
439 __unused db_expr_t count
,
440 __unused
char *modif
)
446 db_pmgr(__unused db_expr_t addr
,
447 __unused
int have_addr
,
448 __unused db_expr_t count
,
449 __unused
char *modif
)
455 db_test(__unused db_expr_t addr
,
456 __unused
int have_addr
,
457 __unused db_expr_t count
,
458 __unused
char *modif
)
464 db_getpmgr(__unused pmData_t
*pmj
)