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

source code of linux/drivers/soc/apple/rtkit.c