/*
- * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
extern int disableConsoleOutput;
-decl_simple_lock_data(,pm_init_lock);
+#define DELAY_UNSET 0xFFFFFFFFFFFFFFFFULL
/*
* The following is set when the KEXT loads and initializes.
*/
pmDispatch_t *pmDispatch = NULL;
-static uint32_t pmInitDone = 0;
-static boolean_t earlyTopology = FALSE;
-
+static uint32_t pmInitDone = 0;
+static boolean_t earlyTopology = FALSE;
+static uint64_t earlyMaxBusDelay = DELAY_UNSET;
+static uint64_t earlyMaxIntDelay = DELAY_UNSET;
/*
* Initialize the Cstate change code.
void
power_management_init(void)
{
- static boolean_t initialized = FALSE;
-
- /*
- * Initialize the lock for the KEXT initialization.
- */
- if (!initialized) {
- simple_lock_init(&pm_init_lock, 0);
- initialized = TRUE;
- }
-
if (pmDispatch != NULL && pmDispatch->cstateInit != NULL)
(*pmDispatch->cstateInit)();
}
DBGLOG(cpu_handle, cpu_number(), MP_IDLE);
MARK_CPU_IDLE(cpu_number());
+ if (pmInitDone) {
+ /*
+ * Handle case where ml_set_maxbusdelay() or ml_set_maxintdelay()
+ * were called prior to the CPU PM kext being registered. We do
+ * this here since we know at this point the values will be first
+ * used since idle is where the decisions using these values is made.
+ */
+ if (earlyMaxBusDelay != DELAY_UNSET)
+ ml_set_maxbusdelay((uint32_t)(earlyMaxBusDelay & 0xFFFFFFFF));
+
+ if (earlyMaxIntDelay != DELAY_UNSET)
+ ml_set_maxintdelay(earlyMaxIntDelay);
+ }
+
if (pmInitDone
&& pmDispatch != NULL
&& pmDispatch->MachineIdle != NULL)
static void
pmInitComplete(void)
{
- if (earlyTopology && pmDispatch != NULL && pmDispatch->pmCPUStateInit != NULL)
+ if (earlyTopology
+ && pmDispatch != NULL
+ && pmDispatch->pmCPUStateInit != NULL) {
(*pmDispatch->pmCPUStateInit)();
+ earlyTopology = FALSE;
+ }
pmInitDone = 1;
}
{
uint64_t deadline = 0;
- if (pmInitDone
+ if (pmInitDone
&& pmDispatch != NULL
&& pmDispatch->GetDeadline != NULL)
deadline = (*pmDispatch->GetDeadline)(&cpu->lcpu);
{
uint64_t max_snoop = 0;
- if (pmDispatch != NULL
+ if (pmInitDone
+ && pmDispatch != NULL
&& pmDispatch->getMaxSnoop != NULL)
max_snoop = pmDispatch->getMaxSnoop();
{
uint64_t max_delay = 0;
- if (pmDispatch != NULL
+ if (pmInitDone
+ && pmDispatch != NULL
&& pmDispatch->getMaxBusDelay != NULL)
max_delay = pmDispatch->getMaxBusDelay();
uint64_t maxdelay = mdelay;
if (pmDispatch != NULL
- && pmDispatch->setMaxBusDelay != NULL)
+ && pmDispatch->setMaxBusDelay != NULL) {
+ earlyMaxBusDelay = DELAY_UNSET;
pmDispatch->setMaxBusDelay(maxdelay);
+ } else
+ earlyMaxBusDelay = maxdelay;
}
uint64_t
ml_set_maxintdelay(uint64_t mdelay)
{
if (pmDispatch != NULL
- && pmDispatch->setMaxIntDelay != NULL)
+ && pmDispatch->setMaxIntDelay != NULL) {
+ earlyMaxIntDelay = DELAY_UNSET;
pmDispatch->setMaxIntDelay(mdelay);
+ } else
+ earlyMaxIntDelay = mdelay;
}
boolean_t
if (cpuFuncs != NULL) {
pmDispatch = cpuFuncs;
+ if (earlyTopology
+ && pmDispatch->pmCPUStateInit != NULL) {
+ (*pmDispatch->pmCPUStateInit)();
+ earlyTopology = FALSE;
+ }
+
if (pmDispatch->pmIPIHandler != NULL) {
lapic_set_pm_func((i386_intr_func_t)pmDispatch->pmIPIHandler);
}