| 1 | /* | 
| 2 |  * Copyright (c) 2006-2010 Apple Inc. All rights reserved. | 
| 3 |  * | 
| 4 |  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | 
| 5 |  *  | 
| 6 |  * This file contains Original Code and/or Modifications of Original Code | 
| 7 |  * as defined in and that are subject to the Apple Public Source License | 
| 8 |  * Version 2.0 (the 'License'). You may not use this file except in | 
| 9 |  * compliance with the License. The rights granted to you under the License | 
| 10 |  * may not be used to create, or enable the creation or redistribution of, | 
| 11 |  * unlawful or unlicensed copies of an Apple operating system, or to | 
| 12 |  * circumvent, violate, or enable the circumvention or violation of, any | 
| 13 |  * terms of an Apple operating system software license agreement. | 
| 14 |  *  | 
| 15 |  * Please obtain a copy of the License at | 
| 16 |  * http://www.opensource.apple.com/apsl/ and read it before using this file. | 
| 17 |  *  | 
| 18 |  * The Original Code and all software distributed under the License are | 
| 19 |  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | 
| 20 |  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | 
| 21 |  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | 
| 22 |  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | 
| 23 |  * Please see the License for the specific language governing rights and | 
| 24 |  * limitations under the License. | 
| 25 |  *  | 
| 26 |  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | 
| 27 |  */ | 
| 28 | #ifdef KERNEL_PRIVATE | 
| 29 | #ifndef _I386_PMCPU_H_ | 
| 30 | #define _I386_PMCPU_H_ | 
| 31 |  | 
| 32 | #include <i386/cpu_topology.h> | 
| 33 |  | 
| 34 | #ifndef ASSEMBLER | 
| 35 |  | 
| 36 | /* | 
| 37 |  * This value should be changed each time that pmDispatch_t or pmCallBacks_t | 
| 38 |  * changes. | 
| 39 |  */ | 
| 40 | #define PM_DISPATCH_VERSION	102 | 
| 41 |  | 
| 42 | /* | 
| 43 |  * Dispatch table for functions that get installed when the power | 
| 44 |  * management KEXT loads. | 
| 45 |  * | 
| 46 |  * pmDispatch_t is the set of functions that the kernel can use to call | 
| 47 |  * into the power management KEXT. | 
| 48 |  * | 
| 49 |  * pmCallBacks_t is the set of functions that the power management kext | 
| 50 |  * can call to get at specific kernel functions. | 
| 51 |  */ | 
| 52 | typedef struct | 
| 53 | { | 
| 54 |     kern_return_t	(*pmCPUStateInit)(void); | 
| 55 |     void		(*cstateInit)(void); | 
| 56 |     uint64_t		(*MachineIdle)(uint64_t maxIdleDuration); | 
| 57 |     uint64_t		(*GetDeadline)(x86_lcpu_t *lcpu); | 
| 58 |     uint64_t		(*SetDeadline)(x86_lcpu_t *lcpu, uint64_t); | 
| 59 |     void		(*Deadline)(x86_lcpu_t *lcpu); | 
| 60 |     boolean_t		(*exitIdle)(x86_lcpu_t *lcpu); | 
| 61 |     void		(*markCPURunning)(x86_lcpu_t *lcpu); | 
| 62 |     int			(*pmCPUControl)(uint32_t cmd, void *datap); | 
| 63 |     void		(*pmCPUHalt)(void); | 
| 64 |     uint64_t		(*getMaxSnoop)(void); | 
| 65 |     void		(*setMaxBusDelay)(uint64_t time); | 
| 66 |     uint64_t		(*getMaxBusDelay)(void); | 
| 67 |     void		(*setMaxIntDelay)(uint64_t time); | 
| 68 |     uint64_t		(*getMaxIntDelay)(void); | 
| 69 |     void		(*pmCPUSafeMode)(x86_lcpu_t *lcpu, uint32_t flags); | 
| 70 |     void		(*pmTimerStateSave)(void); | 
| 71 |     void		(*pmTimerStateRestore)(void); | 
| 72 |     kern_return_t	(*exitHalt)(x86_lcpu_t *lcpu); | 
| 73 |     kern_return_t	(*exitHaltToOff)(x86_lcpu_t *lcpu); | 
| 74 |     void		(*markAllCPUsOff)(void); | 
| 75 |     void		(*pmSetRunCount)(uint32_t count); | 
| 76 |     boolean_t		(*pmIsCPUUnAvailable)(x86_lcpu_t *lcpu); | 
| 77 |     int			(*pmChooseCPU)(int startCPU, int endCPU, int preferredCPU); | 
| 78 |     int			(*pmIPIHandler)(void *state); | 
| 79 |     void		(*pmThreadTellUrgency)(int urgency, uint64_t rt_period, uint64_t rt_deadline); | 
| 80 |     void		(*pmActiveRTThreads)(boolean_t active); | 
| 81 |     boolean_t           (*pmInterruptPrewakeApplicable)(void); | 
| 82 | } pmDispatch_t; | 
| 83 |  | 
| 84 | /* common time fields exported to PM code. This structure may be | 
| 85 |  * allocated on the stack, so avoid making it unnecessarily large. | 
| 86 |  */ | 
| 87 | typedef struct pm_rtc_nanotime { | 
| 88 | 	uint64_t	tsc_base;		/* timestamp */ | 
| 89 | 	uint64_t	ns_base;		/* nanoseconds */ | 
| 90 | 	uint32_t	scale;			/* tsc -> nanosec multiplier */ | 
| 91 | 	uint32_t	shift;			/* tsc -> nanosec shift/div */ | 
| 92 | 	uint32_t	generation;		/* 0 == being updated */ | 
| 93 | } pm_rtc_nanotime_t; | 
| 94 |  | 
| 95 | typedef struct { | 
| 96 |     uint64_t		(*setRTCPop)(uint64_t time); | 
| 97 |     void		(*resyncDeadlines)(int cpu); | 
| 98 |     void		(*initComplete)(void); | 
| 99 |     x86_lcpu_t		*(*GetLCPU)(int cpu); | 
| 100 |     x86_core_t		*(*GetCore)(int cpu); | 
| 101 |     x86_die_t		*(*GetDie)(int cpu); | 
| 102 |     x86_pkg_t		*(*GetPackage)(int cpu); | 
| 103 |     x86_lcpu_t		*(*GetMyLCPU)(void); | 
| 104 |     x86_core_t		*(*GetMyCore)(void); | 
| 105 |     x86_die_t		*(*GetMyDie)(void); | 
| 106 |     x86_pkg_t		*(*GetMyPackage)(void); | 
| 107 |     x86_pkg_t		*(*GetPkgRoot)(void); | 
| 108 |     void		(*LockCPUTopology)(int lock); | 
| 109 |     boolean_t		(*GetHibernate)(int cpu); | 
| 110 |     processor_t		(*LCPUtoProcessor)(int lcpu); | 
| 111 |     processor_t		(*ThreadBind)(processor_t proc); | 
| 112 |     uint32_t		(*GetSavedRunCount)(void); | 
| 113 |     void		(*pmSendIPI)(int cpu); | 
| 114 |     void		(*GetNanotimeInfo)(pm_rtc_nanotime_t *); | 
| 115 |     int			(*ThreadGetUrgency)(uint64_t *rt_period, uint64_t *rt_deadline); | 
| 116 |     uint32_t		(*timerQueueMigrate)(int cpu); | 
| 117 |     void		(*RTCClockAdjust)(uint64_t adjustment); | 
| 118 |     x86_topology_parameters_t	*topoParms; | 
| 119 |     boolean_t		(*InterruptPending)(void); | 
| 120 |     boolean_t		(*IsInterrupting)(uint8_t vector); | 
| 121 |     void		(*InterruptStats)(uint64_t intrs[256]); | 
| 122 |     void		(*DisableApicTimer)(void); | 
| 123 | } pmCallBacks_t; | 
| 124 |  | 
| 125 | extern pmDispatch_t	*pmDispatch; | 
| 126 |  | 
| 127 | void power_management_init(void); | 
| 128 | void pmKextRegister(uint32_t version, pmDispatch_t *cpuFuncs, | 
| 129 | 		    pmCallBacks_t *callbacks); | 
| 130 | void pmUnRegister(pmDispatch_t *cpuFuncs); | 
| 131 | void pmCPUStateInit(void); | 
| 132 | uint64_t pmCPUGetDeadline(struct cpu_data *cpu); | 
| 133 | uint64_t pmCPUSetDeadline(struct cpu_data *cpu, uint64_t deadline); | 
| 134 | void pmCPUDeadline(struct cpu_data *cpu); | 
| 135 | boolean_t pmCPUExitIdle(struct cpu_data *cpu); | 
| 136 | void pmCPUMarkRunning(struct cpu_data *cpu); | 
| 137 | void pmMarkAllCPUsOff(void); | 
| 138 | int pmCPUControl(uint32_t cmd, void *datap); | 
| 139 | void pmCPUHalt(uint32_t reason); | 
| 140 | void pmTimerSave(void); | 
| 141 | void pmTimerRestore(void); | 
| 142 | kern_return_t pmCPUExitHalt(int cpu); | 
| 143 | kern_return_t pmCPUExitHaltToOff(int cpu); | 
| 144 | uint32_t pmTimerQueueMigrate(int); | 
| 145 |  | 
| 146 | #define PM_HALT_NORMAL		0		/* normal halt path */ | 
| 147 | #define PM_HALT_DEBUG		1		/* debug code wants to halt */ | 
| 148 | #define PM_HALT_PANIC		2		/* panic code wants to halt */ | 
| 149 | #define PM_HALT_SLEEP		3		/* sleep code wants to halt */ | 
| 150 |  | 
| 151 | void pmSafeMode(x86_lcpu_t *lcpu, uint32_t flags); | 
| 152 |  | 
| 153 | #define PM_SAFE_FL_NORMAL	0x00000001	/* put CPU into "normal" power mode */ | 
| 154 | #define PM_SAFE_FL_SAFE		0x00000002	/* put CPU into a "safe" power mode */ | 
| 155 | #define PM_SAFE_FL_PAUSE	0x00000010	/* pause execution on the CPU */ | 
| 156 | #define PM_SAFE_FL_RESUME	0x00000020	/* resume execution on the CPU */ | 
| 157 |  | 
| 158 | extern int pmsafe_debug; | 
| 159 | /* Default urgency timing threshold for the DEBUG build */ | 
| 160 | #define		URGENCY_NOTIFICATION_ASSERT_NS (5 * 1000 * 1000) | 
| 161 | extern uint64_t	urgency_notification_assert_abstime_threshold; | 
| 162 |  | 
| 163 | x86_lcpu_t * | 
| 164 | pmGetLogicalCPU(int cpu); | 
| 165 | x86_lcpu_t * | 
| 166 | pmGetMyLogicalCPU(void); | 
| 167 | processor_t | 
| 168 | pmLCPUtoProcessor(int lcpu); | 
| 169 | x86_pkg_t * | 
| 170 | pmGetPkgRoot(void); | 
| 171 |  | 
| 172 |  | 
| 173 | /****************************************************************************** | 
| 174 |  * | 
| 175 |  * All of the following are deprecated interfaces and no longer used. | 
| 176 |  * | 
| 177 |  ******************************************************************************/ | 
| 178 |  | 
| 179 |  | 
| 180 | #endif /* ASSEMBLER */ | 
| 181 |  | 
| 182 | #endif /* _I386_PMCPU_H_ */ | 
| 183 | #endif /* KERNEL_PRIVATE */ | 
| 184 |  |