1*bbb1b6f9SApple OSS Distributions /*
2*bbb1b6f9SApple OSS Distributions * Copyright (c) 2019 Apple Computer, Inc. All rights reserved.
3*bbb1b6f9SApple OSS Distributions *
4*bbb1b6f9SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*bbb1b6f9SApple OSS Distributions *
6*bbb1b6f9SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*bbb1b6f9SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*bbb1b6f9SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*bbb1b6f9SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*bbb1b6f9SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*bbb1b6f9SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*bbb1b6f9SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*bbb1b6f9SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*bbb1b6f9SApple OSS Distributions *
15*bbb1b6f9SApple OSS Distributions * Please obtain a copy of the License at
16*bbb1b6f9SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*bbb1b6f9SApple OSS Distributions *
18*bbb1b6f9SApple OSS Distributions * The Original Code and all software distributed under the License are
19*bbb1b6f9SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*bbb1b6f9SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*bbb1b6f9SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*bbb1b6f9SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*bbb1b6f9SApple OSS Distributions * Please see the License for the specific language governing rights and
24*bbb1b6f9SApple OSS Distributions * limitations under the License.
25*bbb1b6f9SApple OSS Distributions *
26*bbb1b6f9SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*bbb1b6f9SApple OSS Distributions */
28*bbb1b6f9SApple OSS Distributions
29*bbb1b6f9SApple OSS Distributions extern "C" {
30*bbb1b6f9SApple OSS Distributions #include <kern/debug.h>
31*bbb1b6f9SApple OSS Distributions #include <kern/queue.h>
32*bbb1b6f9SApple OSS Distributions }
33*bbb1b6f9SApple OSS Distributions
34*bbb1b6f9SApple OSS Distributions #include <kern/sched_prim.h>
35*bbb1b6f9SApple OSS Distributions #include <machine/machine_routines.h>
36*bbb1b6f9SApple OSS Distributions #include <IOKit/IOLib.h>
37*bbb1b6f9SApple OSS Distributions #include <IOKit/IOPlatformExpert.h>
38*bbb1b6f9SApple OSS Distributions #include <IOKit/IOKitKeysPrivate.h>
39*bbb1b6f9SApple OSS Distributions #include <IOKit/IOPlatformActions.h>
40*bbb1b6f9SApple OSS Distributions #include "IOKitKernelInternal.h"
41*bbb1b6f9SApple OSS Distributions
42*bbb1b6f9SApple OSS Distributions static IOLock *gIOPlatformActionsLock;
43*bbb1b6f9SApple OSS Distributions
44*bbb1b6f9SApple OSS Distributions typedef kern_return_t (*iocpu_platform_action_t)(void * refcon0, void * refcon1, uint32_t priority,
45*bbb1b6f9SApple OSS Distributions void * param1, void * param2, void * param3,
46*bbb1b6f9SApple OSS Distributions const char * name, uint64_t platform_action_flags);
47*bbb1b6f9SApple OSS Distributions
48*bbb1b6f9SApple OSS Distributions struct iocpu_platform_action_entry {
49*bbb1b6f9SApple OSS Distributions queue_chain_t link;
50*bbb1b6f9SApple OSS Distributions iocpu_platform_action_t action;
51*bbb1b6f9SApple OSS Distributions int32_t priority;
52*bbb1b6f9SApple OSS Distributions const char * name;
53*bbb1b6f9SApple OSS Distributions void * refcon0;
54*bbb1b6f9SApple OSS Distributions void * refcon1;
55*bbb1b6f9SApple OSS Distributions boolean_t callout_in_progress;
56*bbb1b6f9SApple OSS Distributions struct iocpu_platform_action_entry * alloc_list;
57*bbb1b6f9SApple OSS Distributions };
58*bbb1b6f9SApple OSS Distributions typedef struct iocpu_platform_action_entry iocpu_platform_action_entry_t;
59*bbb1b6f9SApple OSS Distributions
60*bbb1b6f9SApple OSS Distributions enum {
61*bbb1b6f9SApple OSS Distributions kQueueSleep = 0,
62*bbb1b6f9SApple OSS Distributions kQueueWake = 1,
63*bbb1b6f9SApple OSS Distributions kQueueQuiesce = 2,
64*bbb1b6f9SApple OSS Distributions kQueueActive = 3,
65*bbb1b6f9SApple OSS Distributions kQueueHaltRestart = 4,
66*bbb1b6f9SApple OSS Distributions kQueuePanic = 5,
67*bbb1b6f9SApple OSS Distributions kQueueCount = 6
68*bbb1b6f9SApple OSS Distributions };
69*bbb1b6f9SApple OSS Distributions
70*bbb1b6f9SApple OSS Distributions #define PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS 1
71*bbb1b6f9SApple OSS Distributions #define PLATFORM_ACTION_FLAGS_NO_LOGGING 2
72*bbb1b6f9SApple OSS Distributions
73*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformSleepActionKey;
74*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformWakeActionKey;
75*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformQuiesceActionKey;
76*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformActiveActionKey;
77*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformHaltRestartActionKey;
78*bbb1b6f9SApple OSS Distributions const OSSymbol * gIOPlatformPanicActionKey;
79*bbb1b6f9SApple OSS Distributions
80*bbb1b6f9SApple OSS Distributions static queue_head_t gActionQueues[kQueueCount];
81*bbb1b6f9SApple OSS Distributions static const OSSymbol * gActionSymbols[kQueueCount];
82*bbb1b6f9SApple OSS Distributions
83*bbb1b6f9SApple OSS Distributions static bool
84*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformAction(IOService * service, uint32_t qidx);
85*bbb1b6f9SApple OSS Distributions
86*bbb1b6f9SApple OSS Distributions static void
iocpu_add_platform_action(queue_head_t * queue,iocpu_platform_action_entry_t * entry)87*bbb1b6f9SApple OSS Distributions iocpu_add_platform_action(queue_head_t * queue, iocpu_platform_action_entry_t * entry)
88*bbb1b6f9SApple OSS Distributions {
89*bbb1b6f9SApple OSS Distributions iocpu_platform_action_entry_t * next;
90*bbb1b6f9SApple OSS Distributions
91*bbb1b6f9SApple OSS Distributions queue_iterate(queue, next, iocpu_platform_action_entry_t *, link)
92*bbb1b6f9SApple OSS Distributions {
93*bbb1b6f9SApple OSS Distributions if (next->priority > entry->priority) {
94*bbb1b6f9SApple OSS Distributions queue_insert_before(queue, entry, next, iocpu_platform_action_entry_t *, link);
95*bbb1b6f9SApple OSS Distributions return;
96*bbb1b6f9SApple OSS Distributions }
97*bbb1b6f9SApple OSS Distributions }
98*bbb1b6f9SApple OSS Distributions queue_enter(queue, entry, iocpu_platform_action_entry_t *, link); // at tail
99*bbb1b6f9SApple OSS Distributions }
100*bbb1b6f9SApple OSS Distributions
101*bbb1b6f9SApple OSS Distributions static void
iocpu_remove_platform_action(iocpu_platform_action_entry_t * entry)102*bbb1b6f9SApple OSS Distributions iocpu_remove_platform_action(iocpu_platform_action_entry_t * entry)
103*bbb1b6f9SApple OSS Distributions {
104*bbb1b6f9SApple OSS Distributions remque(&entry->link);
105*bbb1b6f9SApple OSS Distributions }
106*bbb1b6f9SApple OSS Distributions
107*bbb1b6f9SApple OSS Distributions static kern_return_t
iocpu_run_platform_actions(queue_head_t * queue,uint32_t first_priority,uint32_t last_priority,void * param1,void * param2,void * param3,uint64_t platform_action_flags)108*bbb1b6f9SApple OSS Distributions iocpu_run_platform_actions(queue_head_t * queue, uint32_t first_priority, uint32_t last_priority,
109*bbb1b6f9SApple OSS Distributions void * param1, void * param2, void * param3, uint64_t platform_action_flags)
110*bbb1b6f9SApple OSS Distributions {
111*bbb1b6f9SApple OSS Distributions kern_return_t ret = KERN_SUCCESS;
112*bbb1b6f9SApple OSS Distributions kern_return_t result = KERN_SUCCESS;
113*bbb1b6f9SApple OSS Distributions iocpu_platform_action_entry_t * next;
114*bbb1b6f9SApple OSS Distributions boolean_t allow_nested_callouts = (platform_action_flags & PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
115*bbb1b6f9SApple OSS Distributions
116*bbb1b6f9SApple OSS Distributions queue_iterate(queue, next, iocpu_platform_action_entry_t *, link)
117*bbb1b6f9SApple OSS Distributions {
118*bbb1b6f9SApple OSS Distributions uint32_t pri = (next->priority < 0) ? -next->priority : next->priority;
119*bbb1b6f9SApple OSS Distributions if ((pri >= first_priority) && (pri <= last_priority)) {
120*bbb1b6f9SApple OSS Distributions if (!allow_nested_callouts && !next->callout_in_progress) {
121*bbb1b6f9SApple OSS Distributions next->callout_in_progress = TRUE;
122*bbb1b6f9SApple OSS Distributions ret = (*next->action)(next->refcon0, next->refcon1, pri, param1, param2, param3, next->name, platform_action_flags);
123*bbb1b6f9SApple OSS Distributions next->callout_in_progress = FALSE;
124*bbb1b6f9SApple OSS Distributions } else if (allow_nested_callouts) {
125*bbb1b6f9SApple OSS Distributions ret = (*next->action)(next->refcon0, next->refcon1, pri, param1, param2, param3, next->name, platform_action_flags);
126*bbb1b6f9SApple OSS Distributions }
127*bbb1b6f9SApple OSS Distributions }
128*bbb1b6f9SApple OSS Distributions if (KERN_SUCCESS == result) {
129*bbb1b6f9SApple OSS Distributions result = ret;
130*bbb1b6f9SApple OSS Distributions }
131*bbb1b6f9SApple OSS Distributions }
132*bbb1b6f9SApple OSS Distributions return result;
133*bbb1b6f9SApple OSS Distributions }
134*bbb1b6f9SApple OSS Distributions
135*bbb1b6f9SApple OSS Distributions extern "C" kern_return_t
IOCPURunPlatformQuiesceActions(void)136*bbb1b6f9SApple OSS Distributions IOCPURunPlatformQuiesceActions(void)
137*bbb1b6f9SApple OSS Distributions {
138*bbb1b6f9SApple OSS Distributions assert(preemption_enabled() == false);
139*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_QUIESCE, 0);
140*bbb1b6f9SApple OSS Distributions return iocpu_run_platform_actions(&gActionQueues[kQueueQuiesce], 0, 0U - 1,
141*bbb1b6f9SApple OSS Distributions NULL, NULL, NULL, PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
142*bbb1b6f9SApple OSS Distributions }
143*bbb1b6f9SApple OSS Distributions
144*bbb1b6f9SApple OSS Distributions extern "C" kern_return_t
IOCPURunPlatformActiveActions(void)145*bbb1b6f9SApple OSS Distributions IOCPURunPlatformActiveActions(void)
146*bbb1b6f9SApple OSS Distributions {
147*bbb1b6f9SApple OSS Distributions assert(preemption_enabled() == false);
148*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_ACTIVE, 0);
149*bbb1b6f9SApple OSS Distributions ml_hibernate_active_pre();
150*bbb1b6f9SApple OSS Distributions kern_return_t result = iocpu_run_platform_actions(&gActionQueues[kQueueActive], 0, 0U - 1,
151*bbb1b6f9SApple OSS Distributions NULL, NULL, NULL, PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
152*bbb1b6f9SApple OSS Distributions ml_hibernate_active_post();
153*bbb1b6f9SApple OSS Distributions return result;
154*bbb1b6f9SApple OSS Distributions }
155*bbb1b6f9SApple OSS Distributions
156*bbb1b6f9SApple OSS Distributions extern "C" kern_return_t
IOCPURunPlatformHaltRestartActions(uint32_t message)157*bbb1b6f9SApple OSS Distributions IOCPURunPlatformHaltRestartActions(uint32_t message)
158*bbb1b6f9SApple OSS Distributions {
159*bbb1b6f9SApple OSS Distributions if (!gActionQueues[kQueueHaltRestart].next) {
160*bbb1b6f9SApple OSS Distributions return kIOReturnNotReady;
161*bbb1b6f9SApple OSS Distributions }
162*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_HALT_RESTART, 0);
163*bbb1b6f9SApple OSS Distributions return iocpu_run_platform_actions(&gActionQueues[kQueueHaltRestart], 0, 0U - 1,
164*bbb1b6f9SApple OSS Distributions (void *)(uintptr_t) message, NULL, NULL, PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
165*bbb1b6f9SApple OSS Distributions }
166*bbb1b6f9SApple OSS Distributions
167*bbb1b6f9SApple OSS Distributions extern "C" kern_return_t
IOCPURunPlatformPanicActions(uint32_t message,uint32_t details)168*bbb1b6f9SApple OSS Distributions IOCPURunPlatformPanicActions(uint32_t message, uint32_t details)
169*bbb1b6f9SApple OSS Distributions {
170*bbb1b6f9SApple OSS Distributions // Don't allow nested calls of panic actions
171*bbb1b6f9SApple OSS Distributions if (!gActionQueues[kQueuePanic].next) {
172*bbb1b6f9SApple OSS Distributions return kIOReturnNotReady;
173*bbb1b6f9SApple OSS Distributions }
174*bbb1b6f9SApple OSS Distributions uint64_t platform_action_flags = 0;
175*bbb1b6f9SApple OSS Distributions
176*bbb1b6f9SApple OSS Distributions if (!verbose_panic_flow_logging) {
177*bbb1b6f9SApple OSS Distributions platform_action_flags = PLATFORM_ACTION_FLAGS_NO_LOGGING;
178*bbb1b6f9SApple OSS Distributions }
179*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_PANIC, 0);
180*bbb1b6f9SApple OSS Distributions return iocpu_run_platform_actions(&gActionQueues[kQueuePanic], 0, 0U - 1,
181*bbb1b6f9SApple OSS Distributions (void *)(uintptr_t) message, (void *)(uintptr_t) details, NULL, platform_action_flags);
182*bbb1b6f9SApple OSS Distributions }
183*bbb1b6f9SApple OSS Distributions
184*bbb1b6f9SApple OSS Distributions extern "C" kern_return_t
IOCPURunPlatformPanicSyncAction(void * addr,uint32_t offset,uint32_t len)185*bbb1b6f9SApple OSS Distributions IOCPURunPlatformPanicSyncAction(void *addr, uint32_t offset, uint32_t len)
186*bbb1b6f9SApple OSS Distributions {
187*bbb1b6f9SApple OSS Distributions PE_panic_save_context_t context = {
188*bbb1b6f9SApple OSS Distributions .psc_buffer = addr,
189*bbb1b6f9SApple OSS Distributions .psc_offset = offset,
190*bbb1b6f9SApple OSS Distributions .psc_length = len
191*bbb1b6f9SApple OSS Distributions };
192*bbb1b6f9SApple OSS Distributions
193*bbb1b6f9SApple OSS Distributions // Don't allow nested calls of panic actions
194*bbb1b6f9SApple OSS Distributions if (!gActionQueues[kQueuePanic].next) {
195*bbb1b6f9SApple OSS Distributions return kIOReturnNotReady;
196*bbb1b6f9SApple OSS Distributions }
197*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_PANIC_SYNC, 0);
198*bbb1b6f9SApple OSS Distributions return iocpu_run_platform_actions(&gActionQueues[kQueuePanic], 0, 0U - 1,
199*bbb1b6f9SApple OSS Distributions (void *)(uintptr_t)(kPEPanicSync), &context, NULL, FALSE);
200*bbb1b6f9SApple OSS Distributions }
201*bbb1b6f9SApple OSS Distributions
202*bbb1b6f9SApple OSS Distributions void
IOPlatformActionsPreSleep(void)203*bbb1b6f9SApple OSS Distributions IOPlatformActionsPreSleep(void)
204*bbb1b6f9SApple OSS Distributions {
205*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_PRE_SLEEP, 0);
206*bbb1b6f9SApple OSS Distributions iocpu_run_platform_actions(&gActionQueues[kQueueSleep], 0, 0U - 1,
207*bbb1b6f9SApple OSS Distributions NULL, NULL, NULL, PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
208*bbb1b6f9SApple OSS Distributions }
209*bbb1b6f9SApple OSS Distributions
210*bbb1b6f9SApple OSS Distributions void
IOPlatformActionsPostResume(void)211*bbb1b6f9SApple OSS Distributions IOPlatformActionsPostResume(void)
212*bbb1b6f9SApple OSS Distributions {
213*bbb1b6f9SApple OSS Distributions cpu_event_debug_log(PLATFORM_POST_RESUME, 0);
214*bbb1b6f9SApple OSS Distributions iocpu_run_platform_actions(&gActionQueues[kQueueWake], 0, 0U - 1,
215*bbb1b6f9SApple OSS Distributions NULL, NULL, NULL, PLATFORM_ACTION_FLAGS_ALLOW_NESTED_CALLOUTS);
216*bbb1b6f9SApple OSS Distributions }
217*bbb1b6f9SApple OSS Distributions
218*bbb1b6f9SApple OSS Distributions void
IOPlatformActionsInitialize(void)219*bbb1b6f9SApple OSS Distributions IOPlatformActionsInitialize(void)
220*bbb1b6f9SApple OSS Distributions {
221*bbb1b6f9SApple OSS Distributions gIOPlatformActionsLock = IOLockAlloc();
222*bbb1b6f9SApple OSS Distributions
223*bbb1b6f9SApple OSS Distributions for (uint32_t qidx = kQueueSleep; qidx < kQueueCount; qidx++) {
224*bbb1b6f9SApple OSS Distributions queue_init(&gActionQueues[qidx]);
225*bbb1b6f9SApple OSS Distributions }
226*bbb1b6f9SApple OSS Distributions
227*bbb1b6f9SApple OSS Distributions gIOPlatformSleepActionKey = gActionSymbols[kQueueSleep]
228*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformSleepActionKey);
229*bbb1b6f9SApple OSS Distributions gIOPlatformWakeActionKey = gActionSymbols[kQueueWake]
230*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformWakeActionKey);
231*bbb1b6f9SApple OSS Distributions gIOPlatformQuiesceActionKey = gActionSymbols[kQueueQuiesce]
232*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformQuiesceActionKey);
233*bbb1b6f9SApple OSS Distributions gIOPlatformActiveActionKey = gActionSymbols[kQueueActive]
234*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformActiveActionKey);
235*bbb1b6f9SApple OSS Distributions gIOPlatformHaltRestartActionKey = gActionSymbols[kQueueHaltRestart]
236*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformHaltRestartActionKey);
237*bbb1b6f9SApple OSS Distributions gIOPlatformPanicActionKey = gActionSymbols[kQueuePanic]
238*bbb1b6f9SApple OSS Distributions = OSSymbol::withCStringNoCopy(kIOPlatformPanicActionKey);
239*bbb1b6f9SApple OSS Distributions }
240*bbb1b6f9SApple OSS Distributions
241*bbb1b6f9SApple OSS Distributions static kern_return_t
IOServicePlatformAction(void * refcon0,void * refcon1,uint32_t priority,void * param1,void * param2,void * param3,const char * service_name,uint64_t platform_action_flags)242*bbb1b6f9SApple OSS Distributions IOServicePlatformAction(void * refcon0, void * refcon1, uint32_t priority,
243*bbb1b6f9SApple OSS Distributions void * param1, void * param2, void * param3,
244*bbb1b6f9SApple OSS Distributions const char * service_name, uint64_t platform_action_flags)
245*bbb1b6f9SApple OSS Distributions {
246*bbb1b6f9SApple OSS Distributions IOReturn ret;
247*bbb1b6f9SApple OSS Distributions IOService * service = (IOService *) refcon0;
248*bbb1b6f9SApple OSS Distributions const OSSymbol * function = (const OSSymbol *) refcon1;
249*bbb1b6f9SApple OSS Distributions
250*bbb1b6f9SApple OSS Distributions if (!(platform_action_flags & PLATFORM_ACTION_FLAGS_NO_LOGGING)) {
251*bbb1b6f9SApple OSS Distributions IOLog("%s -> %s\n", function->getCStringNoCopy(), service_name);
252*bbb1b6f9SApple OSS Distributions }
253*bbb1b6f9SApple OSS Distributions
254*bbb1b6f9SApple OSS Distributions /*
255*bbb1b6f9SApple OSS Distributions * We intentionally don't trace params that are kernel addresses,
256*bbb1b6f9SApple OSS Distributions * and truncate 64 bit values to 32 bit, so they all fit into
257*bbb1b6f9SApple OSS Distributions * one tracepoint along with IOService registry id.
258*bbb1b6f9SApple OSS Distributions */
259*bbb1b6f9SApple OSS Distributions SOCD_TRACE_XNU_START(PLATFORM_ACTION,
260*bbb1b6f9SApple OSS Distributions ADDR(function->getCStringNoCopy()),
261*bbb1b6f9SApple OSS Distributions ADDR(service->getMetaClass()),
262*bbb1b6f9SApple OSS Distributions PACK_2X32(VALUE(param1), VALUE(service->getRegistryEntryID())),
263*bbb1b6f9SApple OSS Distributions PACK_2X32(VALUE(param3), VALUE(param2)));
264*bbb1b6f9SApple OSS Distributions
265*bbb1b6f9SApple OSS Distributions ret = service->callPlatformFunction(function, false,
266*bbb1b6f9SApple OSS Distributions (void *)(uintptr_t) priority, param1, param2, param3);
267*bbb1b6f9SApple OSS Distributions
268*bbb1b6f9SApple OSS Distributions SOCD_TRACE_XNU_END(PLATFORM_ACTION,
269*bbb1b6f9SApple OSS Distributions ADDR(function->getCStringNoCopy()),
270*bbb1b6f9SApple OSS Distributions ADDR(service->getMetaClass()),
271*bbb1b6f9SApple OSS Distributions PACK_2X32(VALUE(param1), VALUE(service->getRegistryEntryID())),
272*bbb1b6f9SApple OSS Distributions PACK_2X32(VALUE(param3), VALUE(param2)));
273*bbb1b6f9SApple OSS Distributions
274*bbb1b6f9SApple OSS Distributions return ret;
275*bbb1b6f9SApple OSS Distributions }
276*bbb1b6f9SApple OSS Distributions
277*bbb1b6f9SApple OSS Distributions static bool
IOInstallServicePlatformAction(IOService * service,uint32_t qidx)278*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformAction(IOService * service, uint32_t qidx)
279*bbb1b6f9SApple OSS Distributions {
280*bbb1b6f9SApple OSS Distributions iocpu_platform_action_entry_t * entry;
281*bbb1b6f9SApple OSS Distributions OSNumber * num;
282*bbb1b6f9SApple OSS Distributions uint32_t priority;
283*bbb1b6f9SApple OSS Distributions const OSSymbol * key = gActionSymbols[qidx];
284*bbb1b6f9SApple OSS Distributions queue_head_t * queue = &gActionQueues[qidx];
285*bbb1b6f9SApple OSS Distributions bool reverse;
286*bbb1b6f9SApple OSS Distributions
287*bbb1b6f9SApple OSS Distributions num = OSDynamicCast(OSNumber, service->getProperty(key));
288*bbb1b6f9SApple OSS Distributions if (!num) {
289*bbb1b6f9SApple OSS Distributions return true;
290*bbb1b6f9SApple OSS Distributions }
291*bbb1b6f9SApple OSS Distributions
292*bbb1b6f9SApple OSS Distributions reverse = false;
293*bbb1b6f9SApple OSS Distributions switch (qidx) {
294*bbb1b6f9SApple OSS Distributions case kQueueWake:
295*bbb1b6f9SApple OSS Distributions case kQueueActive:
296*bbb1b6f9SApple OSS Distributions reverse = true;
297*bbb1b6f9SApple OSS Distributions break;
298*bbb1b6f9SApple OSS Distributions }
299*bbb1b6f9SApple OSS Distributions queue_iterate(queue, entry, iocpu_platform_action_entry_t *, link)
300*bbb1b6f9SApple OSS Distributions {
301*bbb1b6f9SApple OSS Distributions if (service == entry->refcon0) {
302*bbb1b6f9SApple OSS Distributions return true;
303*bbb1b6f9SApple OSS Distributions }
304*bbb1b6f9SApple OSS Distributions }
305*bbb1b6f9SApple OSS Distributions
306*bbb1b6f9SApple OSS Distributions entry = IOMallocType(iocpu_platform_action_entry_t);
307*bbb1b6f9SApple OSS Distributions entry->action = &IOServicePlatformAction;
308*bbb1b6f9SApple OSS Distributions entry->name = service->getName();
309*bbb1b6f9SApple OSS Distributions priority = num->unsigned32BitValue();
310*bbb1b6f9SApple OSS Distributions if (reverse) {
311*bbb1b6f9SApple OSS Distributions entry->priority = -priority;
312*bbb1b6f9SApple OSS Distributions } else {
313*bbb1b6f9SApple OSS Distributions entry->priority = priority;
314*bbb1b6f9SApple OSS Distributions }
315*bbb1b6f9SApple OSS Distributions entry->refcon0 = service;
316*bbb1b6f9SApple OSS Distributions entry->refcon1 = (void *) key;
317*bbb1b6f9SApple OSS Distributions entry->callout_in_progress = FALSE;
318*bbb1b6f9SApple OSS Distributions
319*bbb1b6f9SApple OSS Distributions iocpu_add_platform_action(queue, entry);
320*bbb1b6f9SApple OSS Distributions return false;
321*bbb1b6f9SApple OSS Distributions }
322*bbb1b6f9SApple OSS Distributions
323*bbb1b6f9SApple OSS Distributions
324*bbb1b6f9SApple OSS Distributions IOReturn
IOInstallServicePlatformActions(IOService * service)325*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformActions(IOService * service)
326*bbb1b6f9SApple OSS Distributions {
327*bbb1b6f9SApple OSS Distributions IOLockLock(gIOPlatformActionsLock);
328*bbb1b6f9SApple OSS Distributions
329*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformAction(service, kQueueHaltRestart);
330*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformAction(service, kQueuePanic);
331*bbb1b6f9SApple OSS Distributions
332*bbb1b6f9SApple OSS Distributions IOLockUnlock(gIOPlatformActionsLock);
333*bbb1b6f9SApple OSS Distributions
334*bbb1b6f9SApple OSS Distributions return kIOReturnSuccess;
335*bbb1b6f9SApple OSS Distributions }
336*bbb1b6f9SApple OSS Distributions
337*bbb1b6f9SApple OSS Distributions IOReturn
IOInstallServiceSleepPlatformActions(IOService * service)338*bbb1b6f9SApple OSS Distributions IOInstallServiceSleepPlatformActions(IOService * service)
339*bbb1b6f9SApple OSS Distributions {
340*bbb1b6f9SApple OSS Distributions IOLockLock(gIOPlatformActionsLock);
341*bbb1b6f9SApple OSS Distributions
342*bbb1b6f9SApple OSS Distributions for (uint32_t qidx = kQueueSleep; qidx <= kQueueActive; qidx++) {
343*bbb1b6f9SApple OSS Distributions IOInstallServicePlatformAction(service, qidx);
344*bbb1b6f9SApple OSS Distributions }
345*bbb1b6f9SApple OSS Distributions
346*bbb1b6f9SApple OSS Distributions IOLockUnlock(gIOPlatformActionsLock);
347*bbb1b6f9SApple OSS Distributions
348*bbb1b6f9SApple OSS Distributions return kIOReturnSuccess;
349*bbb1b6f9SApple OSS Distributions }
350*bbb1b6f9SApple OSS Distributions
351*bbb1b6f9SApple OSS Distributions IOReturn
IORemoveServicePlatformActions(IOService * service)352*bbb1b6f9SApple OSS Distributions IORemoveServicePlatformActions(IOService * service)
353*bbb1b6f9SApple OSS Distributions {
354*bbb1b6f9SApple OSS Distributions iocpu_platform_action_entry_t * entry;
355*bbb1b6f9SApple OSS Distributions iocpu_platform_action_entry_t * next;
356*bbb1b6f9SApple OSS Distributions
357*bbb1b6f9SApple OSS Distributions IOLockLock(gIOPlatformActionsLock);
358*bbb1b6f9SApple OSS Distributions
359*bbb1b6f9SApple OSS Distributions for (uint32_t qidx = kQueueSleep; qidx < kQueueCount; qidx++) {
360*bbb1b6f9SApple OSS Distributions next = (typeof(entry))queue_first(&gActionQueues[qidx]);
361*bbb1b6f9SApple OSS Distributions while (!queue_end(&gActionQueues[qidx], &next->link)) {
362*bbb1b6f9SApple OSS Distributions entry = next;
363*bbb1b6f9SApple OSS Distributions next = (typeof(entry))queue_next(&entry->link);
364*bbb1b6f9SApple OSS Distributions if (service == entry->refcon0) {
365*bbb1b6f9SApple OSS Distributions iocpu_remove_platform_action(entry);
366*bbb1b6f9SApple OSS Distributions IOFreeType(entry, iocpu_platform_action_entry_t);
367*bbb1b6f9SApple OSS Distributions }
368*bbb1b6f9SApple OSS Distributions }
369*bbb1b6f9SApple OSS Distributions }
370*bbb1b6f9SApple OSS Distributions
371*bbb1b6f9SApple OSS Distributions IOLockUnlock(gIOPlatformActionsLock);
372*bbb1b6f9SApple OSS Distributions
373*bbb1b6f9SApple OSS Distributions return kIOReturnSuccess;
374*bbb1b6f9SApple OSS Distributions }
375