1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /*
3 * Apple RTKit IPC library
4 * Copyright (C) The Asahi Linux Contributors
5 */
6
7 #include "rtkit-internal.h"
8
9 enum {
10 APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */
11 APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */
12 APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */
13 APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */
14 APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */
15 };
16
17 enum {
18 APPLE_RTKIT_EP_MGMT = 0,
19 APPLE_RTKIT_EP_CRASHLOG = 1,
20 APPLE_RTKIT_EP_SYSLOG = 2,
21 APPLE_RTKIT_EP_DEBUG = 3,
22 APPLE_RTKIT_EP_IOREPORT = 4,
23 APPLE_RTKIT_EP_OSLOG = 8,
24 };
25
26 #define APPLE_RTKIT_MGMT_TYPE GENMASK_ULL(59, 52)
27
28 enum {
29 APPLE_RTKIT_MGMT_HELLO = 1,
30 APPLE_RTKIT_MGMT_HELLO_REPLY = 2,
31 APPLE_RTKIT_MGMT_STARTEP = 5,
32 APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE = 6,
33 APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK = 7,
34 APPLE_RTKIT_MGMT_EPMAP = 8,
35 APPLE_RTKIT_MGMT_EPMAP_REPLY = 8,
36 APPLE_RTKIT_MGMT_SET_AP_PWR_STATE = 0xb,
37 APPLE_RTKIT_MGMT_SET_AP_PWR_STATE_ACK = 0xb,
38 };
39
40 #define APPLE_RTKIT_MGMT_HELLO_MINVER GENMASK_ULL(15, 0)
41 #define APPLE_RTKIT_MGMT_HELLO_MAXVER GENMASK_ULL(31, 16)
42
43 #define APPLE_RTKIT_MGMT_EPMAP_LAST BIT_ULL(51)
44 #define APPLE_RTKIT_MGMT_EPMAP_BASE GENMASK_ULL(34, 32)
45 #define APPLE_RTKIT_MGMT_EPMAP_BITMAP GENMASK_ULL(31, 0)
46
47 #define APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE BIT_ULL(0)
48
49 #define APPLE_RTKIT_MGMT_STARTEP_EP GENMASK_ULL(39, 32)
50 #define APPLE_RTKIT_MGMT_STARTEP_FLAG BIT_ULL(1)
51
52 #define APPLE_RTKIT_MGMT_PWR_STATE GENMASK_ULL(15, 0)
53
54 #define APPLE_RTKIT_CRASHLOG_CRASH 1
55
56 #define APPLE_RTKIT_BUFFER_REQUEST 1
57 #define APPLE_RTKIT_BUFFER_REQUEST_SIZE GENMASK_ULL(51, 44)
58 #define APPLE_RTKIT_BUFFER_REQUEST_IOVA GENMASK_ULL(43, 0)
59
60 #define APPLE_RTKIT_SYSLOG_TYPE GENMASK_ULL(59, 52)
61
62 #define APPLE_RTKIT_SYSLOG_LOG 5
63
64 #define APPLE_RTKIT_SYSLOG_INIT 8
65 #define APPLE_RTKIT_SYSLOG_N_ENTRIES GENMASK_ULL(7, 0)
66 #define APPLE_RTKIT_SYSLOG_MSG_SIZE GENMASK_ULL(31, 24)
67
68 #define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56)
69 #define APPLE_RTKIT_OSLOG_BUFFER_REQUEST 1
70 #define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36)
71 #define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0)
72
73 #define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11
74 #define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12
75
76 struct apple_rtkit_rx_work {
77 struct apple_rtkit *rtk;
78 u8 ep;
79 u64 msg;
80 struct work_struct work;
81 };
82
apple_rtkit_is_running(struct apple_rtkit * rtk)83 bool apple_rtkit_is_running(struct apple_rtkit *rtk)
84 {
85 if (rtk->crashed)
86 return false;
87 if ((rtk->iop_power_state & 0xff) != APPLE_RTKIT_PWR_STATE_ON)
88 return false;
89 if ((rtk->ap_power_state & 0xff) != APPLE_RTKIT_PWR_STATE_ON)
90 return false;
91 return true;
92 }
93 EXPORT_SYMBOL_GPL(apple_rtkit_is_running);
94
apple_rtkit_is_crashed(struct apple_rtkit * rtk)95 bool apple_rtkit_is_crashed(struct apple_rtkit *rtk)
96 {
97 return rtk->crashed;
98 }
99 EXPORT_SYMBOL_GPL(apple_rtkit_is_crashed);
100
apple_rtkit_management_send(struct apple_rtkit * rtk,u8 type,u64 msg)101 static void apple_rtkit_management_send(struct apple_rtkit *rtk, u8 type,
102 u64 msg)
103 {
104 msg &= ~APPLE_RTKIT_MGMT_TYPE;
105 msg |= FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, type);
106 apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_MGMT, msg, NULL, false);
107 }
108
apple_rtkit_management_rx_hello(struct apple_rtkit * rtk,u64 msg)109 static void apple_rtkit_management_rx_hello(struct apple_rtkit *rtk, u64 msg)
110 {
111 u64 reply;
112
113 int min_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MINVER, msg);
114 int max_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MAXVER, msg);
115 int want_ver = min(APPLE_RTKIT_MAX_SUPPORTED_VERSION, max_ver);
116
117 dev_dbg(rtk->dev, "RTKit: Min ver %d, max ver %d\n", min_ver, max_ver);
118
119 if (min_ver > APPLE_RTKIT_MAX_SUPPORTED_VERSION) {
120 dev_err(rtk->dev, "RTKit: Firmware min version %d is too new\n",
121 min_ver);
122 goto abort_boot;
123 }
124
125 if (max_ver < APPLE_RTKIT_MIN_SUPPORTED_VERSION) {
126 dev_err(rtk->dev, "RTKit: Firmware max version %d is too old\n",
127 max_ver);
128 goto abort_boot;
129 }
130
131 dev_info(rtk->dev, "RTKit: Initializing (protocol version %d)\n",
132 want_ver);
133 rtk->version = want_ver;
134
135 reply = FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MINVER, want_ver);
136 reply |= FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MAXVER, want_ver);
137 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_HELLO_REPLY, reply);
138
139 return;
140
141 abort_boot:
142 rtk->boot_result = -EINVAL;
143 complete_all(&rtk->epmap_completion);
144 }
145
apple_rtkit_management_rx_epmap(struct apple_rtkit * rtk,u64 msg)146 static void apple_rtkit_management_rx_epmap(struct apple_rtkit *rtk, u64 msg)
147 {
148 int i, ep;
149 u64 reply;
150 unsigned long bitmap = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BITMAP, msg);
151 u32 base = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BASE, msg);
152
153 dev_dbg(rtk->dev,
154 "RTKit: received endpoint bitmap 0x%lx with base 0x%x\n",
155 bitmap, base);
156
157 for_each_set_bit(i, &bitmap, 32) {
158 ep = 32 * base + i;
159 dev_dbg(rtk->dev, "RTKit: Discovered endpoint 0x%02x\n", ep);
160 set_bit(ep, rtk->endpoints);
161 }
162
163 reply = FIELD_PREP(APPLE_RTKIT_MGMT_EPMAP_BASE, base);
164 if (msg & APPLE_RTKIT_MGMT_EPMAP_LAST)
165 reply |= APPLE_RTKIT_MGMT_EPMAP_LAST;
166 else
167 reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE;
168
169 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_EPMAP_REPLY, reply);
170
171 if (!(msg & APPLE_RTKIT_MGMT_EPMAP_LAST))
172 return;
173
174 for_each_set_bit(ep, rtk->endpoints, APPLE_RTKIT_APP_ENDPOINT_START) {
175 switch (ep) {
176 /* the management endpoint is started by default */
177 case APPLE_RTKIT_EP_MGMT:
178 break;
179
180 /* without starting these RTKit refuses to boot */
181 case APPLE_RTKIT_EP_SYSLOG:
182 case APPLE_RTKIT_EP_CRASHLOG:
183 case APPLE_RTKIT_EP_DEBUG:
184 case APPLE_RTKIT_EP_IOREPORT:
185 case APPLE_RTKIT_EP_OSLOG:
186 dev_dbg(rtk->dev,
187 "RTKit: Starting system endpoint 0x%02x\n", ep);
188 apple_rtkit_start_ep(rtk, ep);
189 break;
190
191 default:
192 dev_warn(rtk->dev,
193 "RTKit: Unknown system endpoint: 0x%02x\n",
194 ep);
195 }
196 }
197
198 rtk->boot_result = 0;
199 complete_all(&rtk->epmap_completion);
200 }
201
apple_rtkit_management_rx_iop_pwr_ack(struct apple_rtkit * rtk,u64 msg)202 static void apple_rtkit_management_rx_iop_pwr_ack(struct apple_rtkit *rtk,
203 u64 msg)
204 {
205 unsigned int new_state = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg);
206
207 dev_dbg(rtk->dev, "RTKit: IOP power state transition: 0x%x -> 0x%x\n",
208 rtk->iop_power_state, new_state);
209 rtk->iop_power_state = new_state;
210
211 complete_all(&rtk->iop_pwr_ack_completion);
212 }
213
apple_rtkit_management_rx_ap_pwr_ack(struct apple_rtkit * rtk,u64 msg)214 static void apple_rtkit_management_rx_ap_pwr_ack(struct apple_rtkit *rtk,
215 u64 msg)
216 {
217 unsigned int new_state = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg);
218
219 dev_dbg(rtk->dev, "RTKit: AP power state transition: 0x%x -> 0x%x\n",
220 rtk->ap_power_state, new_state);
221 rtk->ap_power_state = new_state;
222
223 complete_all(&rtk->ap_pwr_ack_completion);
224 }
225
apple_rtkit_management_rx(struct apple_rtkit * rtk,u64 msg)226 static void apple_rtkit_management_rx(struct apple_rtkit *rtk, u64 msg)
227 {
228 u8 type = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg);
229
230 switch (type) {
231 case APPLE_RTKIT_MGMT_HELLO:
232 apple_rtkit_management_rx_hello(rtk, msg);
233 break;
234 case APPLE_RTKIT_MGMT_EPMAP:
235 apple_rtkit_management_rx_epmap(rtk, msg);
236 break;
237 case APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK:
238 apple_rtkit_management_rx_iop_pwr_ack(rtk, msg);
239 break;
240 case APPLE_RTKIT_MGMT_SET_AP_PWR_STATE_ACK:
241 apple_rtkit_management_rx_ap_pwr_ack(rtk, msg);
242 break;
243 default:
244 dev_warn(
245 rtk->dev,
246 "RTKit: unknown management message: 0x%llx (type: 0x%02x)\n",
247 msg, type);
248 }
249 }
250
apple_rtkit_common_rx_get_buffer(struct apple_rtkit * rtk,struct apple_rtkit_shmem * buffer,u8 ep,u64 msg)251 static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk,
252 struct apple_rtkit_shmem *buffer,
253 u8 ep, u64 msg)
254 {
255 u64 reply;
256 int err;
257
258 /* The different size vs. IOVA shifts look odd but are indeed correct this way */
259 if (ep == APPLE_RTKIT_EP_OSLOG) {
260 buffer->size = FIELD_GET(APPLE_RTKIT_OSLOG_SIZE, msg);
261 buffer->iova = FIELD_GET(APPLE_RTKIT_OSLOG_IOVA, msg) << 12;
262 } else {
263 buffer->size = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg) << 12;
264 buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg);
265 }
266
267 buffer->buffer = NULL;
268 buffer->iomem = NULL;
269 buffer->is_mapped = false;
270
271 dev_dbg(rtk->dev, "RTKit: buffer request for 0x%zx bytes at %pad\n",
272 buffer->size, &buffer->iova);
273
274 if (buffer->iova &&
275 (!rtk->ops->shmem_setup || !rtk->ops->shmem_destroy)) {
276 err = -EINVAL;
277 goto error;
278 }
279
280 if (rtk->ops->shmem_setup) {
281 err = rtk->ops->shmem_setup(rtk->cookie, buffer);
282 if (err)
283 goto error;
284 } else {
285 buffer->buffer = dma_alloc_coherent(rtk->dev, buffer->size,
286 &buffer->iova, GFP_KERNEL);
287 if (!buffer->buffer) {
288 err = -ENOMEM;
289 goto error;
290 }
291 }
292
293 if (!buffer->is_mapped) {
294 /* oslog uses different fields and needs a shifted IOVA instead of size */
295 if (ep == APPLE_RTKIT_EP_OSLOG) {
296 reply = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE,
297 APPLE_RTKIT_OSLOG_BUFFER_REQUEST);
298 reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buffer->size);
299 reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA,
300 buffer->iova >> 12);
301 } else {
302 reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE,
303 APPLE_RTKIT_BUFFER_REQUEST);
304 reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE,
305 buffer->size >> 12);
306 reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA,
307 buffer->iova);
308 }
309 apple_rtkit_send_message(rtk, ep, reply, NULL, false);
310 }
311
312 return 0;
313
314 error:
315 buffer->buffer = NULL;
316 buffer->iomem = NULL;
317 buffer->iova = 0;
318 buffer->size = 0;
319 buffer->is_mapped = false;
320 return err;
321 }
322
apple_rtkit_free_buffer(struct apple_rtkit * rtk,struct apple_rtkit_shmem * bfr)323 static void apple_rtkit_free_buffer(struct apple_rtkit *rtk,
324 struct apple_rtkit_shmem *bfr)
325 {
326 if (bfr->size == 0)
327 return;
328
329 if (rtk->ops->shmem_destroy)
330 rtk->ops->shmem_destroy(rtk->cookie, bfr);
331 else if (bfr->buffer)
332 dma_free_coherent(rtk->dev, bfr->size, bfr->buffer, bfr->iova);
333
334 bfr->buffer = NULL;
335 bfr->iomem = NULL;
336 bfr->iova = 0;
337 bfr->size = 0;
338 bfr->is_mapped = false;
339 }
340
apple_rtkit_memcpy(struct apple_rtkit * rtk,void * dst,struct apple_rtkit_shmem * bfr,size_t offset,size_t len)341 static void apple_rtkit_memcpy(struct apple_rtkit *rtk, void *dst,
342 struct apple_rtkit_shmem *bfr, size_t offset,
343 size_t len)
344 {
345 if (bfr->iomem)
346 memcpy_fromio(dst, bfr->iomem + offset, len);
347 else
348 memcpy(dst, bfr->buffer + offset, len);
349 }
350
apple_rtkit_crashlog_rx(struct apple_rtkit * rtk,u64 msg)351 static void apple_rtkit_crashlog_rx(struct apple_rtkit *rtk, u64 msg)
352 {
353 u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
354 u8 *bfr;
355
356 if (type != APPLE_RTKIT_CRASHLOG_CRASH) {
357 dev_warn(rtk->dev, "RTKit: Unknown crashlog message: %llx\n",
358 msg);
359 return;
360 }
361
362 if (!rtk->crashlog_buffer.size) {
363 apple_rtkit_common_rx_get_buffer(rtk, &rtk->crashlog_buffer,
364 APPLE_RTKIT_EP_CRASHLOG, msg);
365 return;
366 }
367
368 dev_err(rtk->dev, "RTKit: co-processor has crashed\n");
369
370 /*
371 * create a shadow copy here to make sure the co-processor isn't able
372 * to change the log while we're dumping it. this also ensures
373 * the buffer is in normal memory and not iomem for e.g. the SMC
374 */
375 bfr = kzalloc(rtk->crashlog_buffer.size, GFP_KERNEL);
376 if (bfr) {
377 apple_rtkit_memcpy(rtk, bfr, &rtk->crashlog_buffer, 0,
378 rtk->crashlog_buffer.size);
379 apple_rtkit_crashlog_dump(rtk, bfr, rtk->crashlog_buffer.size);
380 kfree(bfr);
381 } else {
382 dev_err(rtk->dev,
383 "RTKit: Couldn't allocate crashlog shadow buffer\n");
384 }
385
386 rtk->crashed = true;
387 if (rtk->ops->crashed)
388 rtk->ops->crashed(rtk->cookie);
389 }
390
apple_rtkit_ioreport_rx(struct apple_rtkit * rtk,u64 msg)391 static void apple_rtkit_ioreport_rx(struct apple_rtkit *rtk, u64 msg)
392 {
393 u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
394
395 switch (type) {
396 case APPLE_RTKIT_BUFFER_REQUEST:
397 apple_rtkit_common_rx_get_buffer(rtk, &rtk->ioreport_buffer,
398 APPLE_RTKIT_EP_IOREPORT, msg);
399 break;
400 /* unknown, must be ACKed or the co-processor will hang */
401 case 0x8:
402 case 0xc:
403 apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_IOREPORT, msg,
404 NULL, false);
405 break;
406 default:
407 dev_warn(rtk->dev, "RTKit: Unknown ioreport message: %llx\n",
408 msg);
409 }
410 }
411
apple_rtkit_syslog_rx_init(struct apple_rtkit * rtk,u64 msg)412 static void apple_rtkit_syslog_rx_init(struct apple_rtkit *rtk, u64 msg)
413 {
414 rtk->syslog_n_entries = FIELD_GET(APPLE_RTKIT_SYSLOG_N_ENTRIES, msg);
415 rtk->syslog_msg_size = FIELD_GET(APPLE_RTKIT_SYSLOG_MSG_SIZE, msg);
416
417 rtk->syslog_msg_buffer = kzalloc(rtk->syslog_msg_size, GFP_KERNEL);
418
419 dev_dbg(rtk->dev,
420 "RTKit: syslog initialized: entries: %zd, msg_size: %zd\n",
421 rtk->syslog_n_entries, rtk->syslog_msg_size);
422 }
423
should_crop_syslog_char(char c)424 static bool should_crop_syslog_char(char c)
425 {
426 return c == '\n' || c == '\r' || c == ' ' || c == '\0';
427 }
428
apple_rtkit_syslog_rx_log(struct apple_rtkit * rtk,u64 msg)429 static void apple_rtkit_syslog_rx_log(struct apple_rtkit *rtk, u64 msg)
430 {
431 u8 idx = msg & 0xff;
432 char log_context[24];
433 size_t entry_size = 0x20 + rtk->syslog_msg_size;
434 int msglen;
435
436 if (!rtk->syslog_msg_buffer) {
437 dev_warn(
438 rtk->dev,
439 "RTKit: received syslog message but no syslog_msg_buffer\n");
440 goto done;
441 }
442 if (!rtk->syslog_buffer.size) {
443 dev_warn(
444 rtk->dev,
445 "RTKit: received syslog message but syslog_buffer.size is zero\n");
446 goto done;
447 }
448 if (!rtk->syslog_buffer.buffer && !rtk->syslog_buffer.iomem) {
449 dev_warn(
450 rtk->dev,
451 "RTKit: received syslog message but no syslog_buffer.buffer or syslog_buffer.iomem\n");
452 goto done;
453 }
454 if (idx > rtk->syslog_n_entries) {
455 dev_warn(rtk->dev, "RTKit: syslog index %d out of range\n",
456 idx);
457 goto done;
458 }
459
460 apple_rtkit_memcpy(rtk, log_context, &rtk->syslog_buffer,
461 idx * entry_size + 8, sizeof(log_context));
462 apple_rtkit_memcpy(rtk, rtk->syslog_msg_buffer, &rtk->syslog_buffer,
463 idx * entry_size + 8 + sizeof(log_context),
464 rtk->syslog_msg_size);
465
466 log_context[sizeof(log_context) - 1] = 0;
467
468 msglen = rtk->syslog_msg_size - 1;
469 while (msglen > 0 &&
470 should_crop_syslog_char(rtk->syslog_msg_buffer[msglen - 1]))
471 msglen--;
472
473 rtk->syslog_msg_buffer[msglen] = 0;
474 dev_info(rtk->dev, "RTKit: syslog message: %s: %s\n", log_context,
475 rtk->syslog_msg_buffer);
476
477 done:
478 apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_SYSLOG, msg, NULL, false);
479 }
480
apple_rtkit_syslog_rx(struct apple_rtkit * rtk,u64 msg)481 static void apple_rtkit_syslog_rx(struct apple_rtkit *rtk, u64 msg)
482 {
483 u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
484
485 switch (type) {
486 case APPLE_RTKIT_BUFFER_REQUEST:
487 apple_rtkit_common_rx_get_buffer(rtk, &rtk->syslog_buffer,
488 APPLE_RTKIT_EP_SYSLOG, msg);
489 break;
490 case APPLE_RTKIT_SYSLOG_INIT:
491 apple_rtkit_syslog_rx_init(rtk, msg);
492 break;
493 case APPLE_RTKIT_SYSLOG_LOG:
494 apple_rtkit_syslog_rx_log(rtk, msg);
495 break;
496 default:
497 dev_warn(rtk->dev, "RTKit: Unknown syslog message: %llx\n",
498 msg);
499 }
500 }
501
apple_rtkit_oslog_rx(struct apple_rtkit * rtk,u64 msg)502 static void apple_rtkit_oslog_rx(struct apple_rtkit *rtk, u64 msg)
503 {
504 u8 type = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg);
505
506 switch (type) {
507 case APPLE_RTKIT_OSLOG_BUFFER_REQUEST:
508 apple_rtkit_common_rx_get_buffer(rtk, &rtk->oslog_buffer,
509 APPLE_RTKIT_EP_OSLOG, msg);
510 break;
511 default:
512 dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n",
513 msg);
514 }
515 }
516
apple_rtkit_rx_work(struct work_struct * work)517 static void apple_rtkit_rx_work(struct work_struct *work)
518 {
519 struct apple_rtkit_rx_work *rtk_work =
520 container_of(work, struct apple_rtkit_rx_work, work);
521 struct apple_rtkit *rtk = rtk_work->rtk;
522
523 switch (rtk_work->ep) {
524 case APPLE_RTKIT_EP_MGMT:
525 apple_rtkit_management_rx(rtk, rtk_work->msg);
526 break;
527 case APPLE_RTKIT_EP_CRASHLOG:
528 apple_rtkit_crashlog_rx(rtk, rtk_work->msg);
529 break;
530 case APPLE_RTKIT_EP_SYSLOG:
531 apple_rtkit_syslog_rx(rtk, rtk_work->msg);
532 break;
533 case APPLE_RTKIT_EP_IOREPORT:
534 apple_rtkit_ioreport_rx(rtk, rtk_work->msg);
535 break;
536 case APPLE_RTKIT_EP_OSLOG:
537 apple_rtkit_oslog_rx(rtk, rtk_work->msg);
538 break;
539 case APPLE_RTKIT_APP_ENDPOINT_START ... 0xff:
540 if (rtk->ops->recv_message)
541 rtk->ops->recv_message(rtk->cookie, rtk_work->ep,
542 rtk_work->msg);
543 else
544 dev_warn(
545 rtk->dev,
546 "Received unexpected message to EP%02d: %llx\n",
547 rtk_work->ep, rtk_work->msg);
548 break;
549 default:
550 dev_warn(rtk->dev,
551 "RTKit: message to unknown endpoint %02x: %llx\n",
552 rtk_work->ep, rtk_work->msg);
553 }
554
555 kfree(rtk_work);
556 }
557
apple_rtkit_rx(struct apple_mbox * mbox,struct apple_mbox_msg msg,void * cookie)558 static void apple_rtkit_rx(struct apple_mbox *mbox, struct apple_mbox_msg msg,
559 void *cookie)
560 {
561 struct apple_rtkit *rtk = cookie;
562 struct apple_rtkit_rx_work *work;
563 u8 ep = msg.msg1;
564
565 /*
566 * The message was read from a MMIO FIFO and we have to make
567 * sure all reads from buffers sent with that message happen
568 * afterwards.
569 */
570 dma_rmb();
571
572 if (!test_bit(ep, rtk->endpoints))
573 dev_warn(rtk->dev,
574 "RTKit: Message to undiscovered endpoint 0x%02x\n",
575 ep);
576
577 if (ep >= APPLE_RTKIT_APP_ENDPOINT_START &&
578 rtk->ops->recv_message_early &&
579 rtk->ops->recv_message_early(rtk->cookie, ep, msg.msg0))
580 return;
581
582 work = kzalloc(sizeof(*work), GFP_ATOMIC);
583 if (!work)
584 return;
585
586 work->rtk = rtk;
587 work->ep = ep;
588 work->msg = msg.msg0;
589 INIT_WORK(&work->work, apple_rtkit_rx_work);
590 queue_work(rtk->wq, &work->work);
591 }
592
apple_rtkit_send_message(struct apple_rtkit * rtk,u8 ep,u64 message,struct completion * completion,bool atomic)593 int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message,
594 struct completion *completion, bool atomic)
595 {
596 struct apple_mbox_msg msg = {
597 .msg0 = message,
598 .msg1 = ep,
599 };
600
601 if (rtk->crashed)
602 return -EINVAL;
603 if (ep >= APPLE_RTKIT_APP_ENDPOINT_START &&
604 !apple_rtkit_is_running(rtk))
605 return -EINVAL;
606
607 /*
608 * The message will be sent with a MMIO write. We need the barrier
609 * here to ensure any previous writes to buffers are visible to the
610 * device before that MMIO write happens.
611 */
612 dma_wmb();
613
614 return apple_mbox_send(rtk->mbox, msg, atomic);
615 }
616 EXPORT_SYMBOL_GPL(apple_rtkit_send_message);
617
apple_rtkit_poll(struct apple_rtkit * rtk)618 int apple_rtkit_poll(struct apple_rtkit *rtk)
619 {
620 return apple_mbox_poll(rtk->mbox);
621 }
622 EXPORT_SYMBOL_GPL(apple_rtkit_poll);
623
apple_rtkit_start_ep(struct apple_rtkit * rtk,u8 endpoint)624 int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint)
625 {
626 u64 msg;
627
628 if (!test_bit(endpoint, rtk->endpoints))
629 return -EINVAL;
630 if (endpoint >= APPLE_RTKIT_APP_ENDPOINT_START &&
631 !apple_rtkit_is_running(rtk))
632 return -EINVAL;
633
634 msg = FIELD_PREP(APPLE_RTKIT_MGMT_STARTEP_EP, endpoint);
635 msg |= APPLE_RTKIT_MGMT_STARTEP_FLAG;
636 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_STARTEP, msg);
637
638 return 0;
639 }
640 EXPORT_SYMBOL_GPL(apple_rtkit_start_ep);
641
apple_rtkit_init(struct device * dev,void * cookie,const char * mbox_name,int mbox_idx,const struct apple_rtkit_ops * ops)642 struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
643 const char *mbox_name, int mbox_idx,
644 const struct apple_rtkit_ops *ops)
645 {
646 struct apple_rtkit *rtk;
647 int ret;
648
649 if (!ops)
650 return ERR_PTR(-EINVAL);
651
652 rtk = kzalloc(sizeof(*rtk), GFP_KERNEL);
653 if (!rtk)
654 return ERR_PTR(-ENOMEM);
655
656 rtk->dev = dev;
657 rtk->cookie = cookie;
658 rtk->ops = ops;
659
660 init_completion(&rtk->epmap_completion);
661 init_completion(&rtk->iop_pwr_ack_completion);
662 init_completion(&rtk->ap_pwr_ack_completion);
663
664 bitmap_zero(rtk->endpoints, APPLE_RTKIT_MAX_ENDPOINTS);
665 set_bit(APPLE_RTKIT_EP_MGMT, rtk->endpoints);
666
667 if (mbox_name)
668 rtk->mbox = apple_mbox_get_byname(dev, mbox_name);
669 else
670 rtk->mbox = apple_mbox_get(dev, mbox_idx);
671
672 if (IS_ERR(rtk->mbox)) {
673 ret = PTR_ERR(rtk->mbox);
674 goto free_rtk;
675 }
676
677 rtk->mbox->rx = apple_rtkit_rx;
678 rtk->mbox->cookie = rtk;
679
680 rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_HIGHPRI | WQ_MEM_RECLAIM,
681 dev_name(rtk->dev));
682 if (!rtk->wq) {
683 ret = -ENOMEM;
684 goto free_rtk;
685 }
686
687 ret = apple_mbox_start(rtk->mbox);
688 if (ret)
689 goto destroy_wq;
690
691 return rtk;
692
693 destroy_wq:
694 destroy_workqueue(rtk->wq);
695 free_rtk:
696 kfree(rtk);
697 return ERR_PTR(ret);
698 }
699 EXPORT_SYMBOL_GPL(apple_rtkit_init);
700
apple_rtkit_wait_for_completion(struct completion * c)701 static int apple_rtkit_wait_for_completion(struct completion *c)
702 {
703 long t;
704
705 t = wait_for_completion_interruptible_timeout(c,
706 msecs_to_jiffies(1000));
707 if (t < 0)
708 return t;
709 else if (t == 0)
710 return -ETIME;
711 else
712 return 0;
713 }
714
apple_rtkit_reinit(struct apple_rtkit * rtk)715 int apple_rtkit_reinit(struct apple_rtkit *rtk)
716 {
717 /* make sure we don't handle any messages while reinitializing */
718 apple_mbox_stop(rtk->mbox);
719 flush_workqueue(rtk->wq);
720
721 apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
722 apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
723 apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer);
724 apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
725
726 kfree(rtk->syslog_msg_buffer);
727
728 rtk->syslog_msg_buffer = NULL;
729 rtk->syslog_n_entries = 0;
730 rtk->syslog_msg_size = 0;
731
732 bitmap_zero(rtk->endpoints, APPLE_RTKIT_MAX_ENDPOINTS);
733 set_bit(APPLE_RTKIT_EP_MGMT, rtk->endpoints);
734
735 reinit_completion(&rtk->epmap_completion);
736 reinit_completion(&rtk->iop_pwr_ack_completion);
737 reinit_completion(&rtk->ap_pwr_ack_completion);
738
739 rtk->crashed = false;
740 rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_OFF;
741 rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_OFF;
742
743 return apple_mbox_start(rtk->mbox);
744 }
745 EXPORT_SYMBOL_GPL(apple_rtkit_reinit);
746
apple_rtkit_set_ap_power_state(struct apple_rtkit * rtk,unsigned int state)747 static int apple_rtkit_set_ap_power_state(struct apple_rtkit *rtk,
748 unsigned int state)
749 {
750 u64 msg;
751 int ret;
752
753 reinit_completion(&rtk->ap_pwr_ack_completion);
754
755 msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
756 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE,
757 msg);
758
759 ret = apple_rtkit_wait_for_completion(&rtk->ap_pwr_ack_completion);
760 if (ret)
761 return ret;
762
763 if (rtk->ap_power_state != state)
764 return -EINVAL;
765 return 0;
766 }
767
apple_rtkit_set_iop_power_state(struct apple_rtkit * rtk,unsigned int state)768 static int apple_rtkit_set_iop_power_state(struct apple_rtkit *rtk,
769 unsigned int state)
770 {
771 u64 msg;
772 int ret;
773
774 reinit_completion(&rtk->iop_pwr_ack_completion);
775
776 msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
777 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
778 msg);
779
780 ret = apple_rtkit_wait_for_completion(&rtk->iop_pwr_ack_completion);
781 if (ret)
782 return ret;
783
784 if (rtk->iop_power_state != state)
785 return -EINVAL;
786 return 0;
787 }
788
apple_rtkit_boot(struct apple_rtkit * rtk)789 int apple_rtkit_boot(struct apple_rtkit *rtk)
790 {
791 int ret;
792
793 if (apple_rtkit_is_running(rtk))
794 return 0;
795 if (rtk->crashed)
796 return -EINVAL;
797
798 dev_dbg(rtk->dev, "RTKit: waiting for boot to finish\n");
799 ret = apple_rtkit_wait_for_completion(&rtk->epmap_completion);
800 if (ret)
801 return ret;
802 if (rtk->boot_result)
803 return rtk->boot_result;
804
805 dev_dbg(rtk->dev, "RTKit: waiting for IOP power state ACK\n");
806 ret = apple_rtkit_wait_for_completion(&rtk->iop_pwr_ack_completion);
807 if (ret)
808 return ret;
809
810 return apple_rtkit_set_ap_power_state(rtk, APPLE_RTKIT_PWR_STATE_ON);
811 }
812 EXPORT_SYMBOL_GPL(apple_rtkit_boot);
813
apple_rtkit_shutdown(struct apple_rtkit * rtk)814 int apple_rtkit_shutdown(struct apple_rtkit *rtk)
815 {
816 int ret;
817
818 /* if OFF is used here the co-processor will not wake up again */
819 ret = apple_rtkit_set_ap_power_state(rtk,
820 APPLE_RTKIT_PWR_STATE_QUIESCED);
821 if (ret)
822 return ret;
823
824 ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_SLEEP);
825 if (ret)
826 return ret;
827
828 return apple_rtkit_reinit(rtk);
829 }
830 EXPORT_SYMBOL_GPL(apple_rtkit_shutdown);
831
apple_rtkit_idle(struct apple_rtkit * rtk)832 int apple_rtkit_idle(struct apple_rtkit *rtk)
833 {
834 int ret;
835
836 /* if OFF is used here the co-processor will not wake up again */
837 ret = apple_rtkit_set_ap_power_state(rtk,
838 APPLE_RTKIT_PWR_STATE_IDLE);
839 if (ret)
840 return ret;
841
842 ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_IDLE);
843 if (ret)
844 return ret;
845
846 rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
847 rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
848 return 0;
849 }
850 EXPORT_SYMBOL_GPL(apple_rtkit_idle);
851
apple_rtkit_quiesce(struct apple_rtkit * rtk)852 int apple_rtkit_quiesce(struct apple_rtkit *rtk)
853 {
854 int ret;
855
856 ret = apple_rtkit_set_ap_power_state(rtk,
857 APPLE_RTKIT_PWR_STATE_QUIESCED);
858 if (ret)
859 return ret;
860
861 ret = apple_rtkit_set_iop_power_state(rtk,
862 APPLE_RTKIT_PWR_STATE_QUIESCED);
863 if (ret)
864 return ret;
865
866 ret = apple_rtkit_reinit(rtk);
867 if (ret)
868 return ret;
869
870 rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_QUIESCED;
871 rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_QUIESCED;
872 return 0;
873 }
874 EXPORT_SYMBOL_GPL(apple_rtkit_quiesce);
875
apple_rtkit_wake(struct apple_rtkit * rtk)876 int apple_rtkit_wake(struct apple_rtkit *rtk)
877 {
878 u64 msg;
879
880 if (apple_rtkit_is_running(rtk))
881 return -EINVAL;
882
883 reinit_completion(&rtk->iop_pwr_ack_completion);
884
885 /*
886 * Use open-coded apple_rtkit_set_iop_power_state since apple_rtkit_boot
887 * will wait for the completion anyway.
888 */
889 msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_ON);
890 apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
891 msg);
892
893 return apple_rtkit_boot(rtk);
894 }
895 EXPORT_SYMBOL_GPL(apple_rtkit_wake);
896
apple_rtkit_free(struct apple_rtkit * rtk)897 void apple_rtkit_free(struct apple_rtkit *rtk)
898 {
899 apple_mbox_stop(rtk->mbox);
900 destroy_workqueue(rtk->wq);
901
902 apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
903 apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
904 apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer);
905 apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
906
907 kfree(rtk->syslog_msg_buffer);
908 kfree(rtk);
909 }
910 EXPORT_SYMBOL_GPL(apple_rtkit_free);
911
apple_rtkit_free_wrapper(void * data)912 static void apple_rtkit_free_wrapper(void *data)
913 {
914 apple_rtkit_free(data);
915 }
916
devm_apple_rtkit_init(struct device * dev,void * cookie,const char * mbox_name,int mbox_idx,const struct apple_rtkit_ops * ops)917 struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
918 const char *mbox_name, int mbox_idx,
919 const struct apple_rtkit_ops *ops)
920 {
921 struct apple_rtkit *rtk;
922 int ret;
923
924 rtk = apple_rtkit_init(dev, cookie, mbox_name, mbox_idx, ops);
925 if (IS_ERR(rtk))
926 return rtk;
927
928 ret = devm_add_action_or_reset(dev, apple_rtkit_free_wrapper, rtk);
929 if (ret)
930 return ERR_PTR(ret);
931
932 return rtk;
933 }
934 EXPORT_SYMBOL_GPL(devm_apple_rtkit_init);
935
936 MODULE_LICENSE("Dual MIT/GPL");
937 MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
938 MODULE_DESCRIPTION("Apple RTKit driver");
939