• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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