X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..13f56ec4e58bf8687e2a68032c093c0213dd519b:/osfmk/i386/pmCPU.c diff --git a/osfmk/i386/pmCPU.c b/osfmk/i386/pmCPU.c index 22eafd1b8..1f064b614 100644 --- a/osfmk/i386/pmCPU.c +++ b/osfmk/i386/pmCPU.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2010 Apple Inc. All rights reserved. + * Copyright (c) 2004-2011 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -54,15 +54,17 @@ 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; /* @@ -71,16 +73,6 @@ static boolean_t earlyTopology = FALSE; 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)(); } @@ -101,6 +93,20 @@ machine_idle(void) 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 since it'll be at idle + * where the decision using these values will be used. + */ + 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) @@ -201,8 +207,12 @@ pmMarkAllCPUsOff(void) static void pmInitComplete(void) { - if (earlyTopology && pmDispatch != NULL && pmDispatch->pmCPUStateInit != NULL) + if (earlyTopology + && pmDispatch != NULL + && pmDispatch->pmCPUStateInit != NULL) { (*pmDispatch->pmCPUStateInit)(); + earlyTopology = FALSE; + } pmInitDone = 1; } @@ -284,7 +294,7 @@ pmCPUGetDeadline(cpu_data_t *cpu) { uint64_t deadline = 0; - if (pmInitDone + if (pmInitDone && pmDispatch != NULL && pmDispatch->GetDeadline != NULL) deadline = (*pmDispatch->GetDeadline)(&cpu->lcpu); @@ -448,7 +458,8 @@ ml_get_maxsnoop(void) { uint64_t max_snoop = 0; - if (pmDispatch != NULL + if (pmInitDone + && pmDispatch != NULL && pmDispatch->getMaxSnoop != NULL) max_snoop = pmDispatch->getMaxSnoop(); @@ -461,7 +472,8 @@ ml_get_maxbusdelay(void) { uint64_t max_delay = 0; - if (pmDispatch != NULL + if (pmInitDone + && pmDispatch != NULL && pmDispatch->getMaxBusDelay != NULL) max_delay = pmDispatch->getMaxBusDelay(); @@ -482,8 +494,11 @@ ml_set_maxbusdelay(uint32_t mdelay) uint64_t maxdelay = mdelay; if (pmDispatch != NULL - && pmDispatch->setMaxBusDelay != NULL) + && pmDispatch->setMaxBusDelay != NULL) { + earlyMaxBusDelay = DELAY_UNSET; pmDispatch->setMaxBusDelay(maxdelay); + } else + earlyMaxBusDelay = maxdelay; } uint64_t @@ -505,8 +520,11 @@ void 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 @@ -811,6 +829,12 @@ pmKextRegister(uint32_t version, pmDispatch_t *cpuFuncs, 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); }