xref: /openbsd-src/sys/arch/arm64/dev/rtkit.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /*	$OpenBSD: rtkit.c,v 1.12 2023/04/07 09:31:59 jsg Exp $	*/
2 /*
3  * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 
23 #include <machine/bus.h>
24 #include <machine/fdt.h>
25 
26 #include <dev/ofw/openfirm.h>
27 #include <dev/ofw/ofw_misc.h>
28 #include <dev/ofw/fdt.h>
29 
30 #include <arm64/dev/aplmbox.h>
31 #include <arm64/dev/rtkit.h>
32 
33 #define RTKIT_EP_MGMT			0
34 #define RTKIT_EP_CRASHLOG		1
35 #define RTKIT_EP_SYSLOG			2
36 #define RTKIT_EP_DEBUG			3
37 #define RTKIT_EP_IOREPORT		4
38 #define RTKIT_EP_OSLOG			8
39 #define RTKIT_EP_UNKNOWN		10
40 
41 #define RTKIT_MGMT_TYPE(x)		(((x) >> 52) & 0xff)
42 #define RTKIT_MGMT_TYPE_SHIFT		52
43 
44 #define RTKIT_MGMT_PWR_STATE(x)		(((x) >> 0) & 0xffff)
45 
46 #define RTKIT_MGMT_HELLO		1
47 #define RTKIT_MGMT_HELLO_ACK		2
48 #define RTKIT_MGMT_STARTEP		5
49 #define RTKIT_MGMT_IOP_PWR_STATE	6
50 #define RTKIT_MGMT_IOP_PWR_STATE_ACK	7
51 #define RTKIT_MGMT_EPMAP		8
52 #define RTKIT_MGMT_AP_PWR_STATE		11
53 
54 #define RTKIT_MGMT_HELLO_MINVER(x)	(((x) >> 0) & 0xffff)
55 #define RTKIT_MGMT_HELLO_MINVER_SHIFT	0
56 #define RTKIT_MGMT_HELLO_MAXVER(x)	(((x) >> 16) & 0xffff)
57 #define RTKIT_MGMT_HELLO_MAXVER_SHIFT	16
58 
59 #define RTKIT_MGMT_STARTEP_EP_SHIFT	32
60 #define RTKIT_MGMT_STARTEP_START	(1ULL << 1)
61 
62 #define RTKIT_MGMT_EPMAP_LAST		(1ULL << 51)
63 #define RTKIT_MGMT_EPMAP_BASE(x)	(((x) >> 32) & 0x7)
64 #define RTKIT_MGMT_EPMAP_BASE_SHIFT	32
65 #define RTKIT_MGMT_EPMAP_BITMAP(x)	(((x) >> 0) & 0xffffffff)
66 #define RTKIT_MGMT_EPMAP_MORE		(1ULL << 0)
67 
68 #define RTKIT_BUFFER_REQUEST		1
69 #define RTKIT_BUFFER_ADDR(x)		(((x) >> 0) & 0xfffffffffff)
70 #define RTKIT_BUFFER_SIZE(x)		(((x) >> 44) & 0xff)
71 #define RTKIT_BUFFER_SIZE_SHIFT		44
72 
73 #define RTKIT_SYSLOG_LOG		5
74 #define RTKIT_SYSLOG_INIT		8
75 
76 #define RTKIT_IOREPORT_UNKNOWN1		8
77 #define RTKIT_IOREPORT_UNKNOWN2		12
78 
79 #define RTKIT_OSLOG_TYPE(x)		(((x) >> 56) & 0xff)
80 #define RTKIT_OSLOG_TYPE_SHIFT		56
81 #define RTKIT_OSLOG_INIT		1ULL
82 #define RTKIT_OSLOG_ACK			3ULL
83 
84 /* Versions we support. */
85 #define RTKIT_MINVER			11
86 #define RTKIT_MAXVER			12
87 
88 struct rtkit_dmamem {
89 	bus_dmamap_t		rdm_map;
90 	bus_dma_segment_t	rdm_seg;
91 	size_t			rdm_size;
92 };
93 
94 struct rtkit_state {
95 	struct mbox_channel	*mc;
96 	struct rtkit		*rk;
97 	uint16_t		iop_pwrstate;
98 	uint16_t		ap_pwrstate;
99 	uint64_t		epmap;
100 	void			(*callback[32])(void *, uint64_t);
101 	void			*arg[32];
102 	struct rtkit_dmamem	dmamem[32];
103 	int			ndmamem;
104 };
105 
106 int
107 rtkit_recv(struct mbox_channel *mc, struct aplmbox_msg *msg)
108 {
109 	return mbox_recv(mc, msg, sizeof(*msg));
110 }
111 
112 int
113 rtkit_send(struct mbox_channel *mc, uint32_t endpoint,
114     uint64_t type, uint64_t data)
115 {
116 	struct aplmbox_msg msg;
117 
118 	msg.data0 = (type << RTKIT_MGMT_TYPE_SHIFT) | data;
119 	msg.data1 = endpoint;
120 	return mbox_send(mc, &msg, sizeof(msg));
121 }
122 
123 bus_addr_t
124 rtkit_alloc(struct rtkit_state *state, bus_size_t size)
125 {
126 	struct rtkit *rk = state->rk;
127 	bus_dma_segment_t seg;
128 	bus_dmamap_t map;
129 	int nsegs;
130 
131 	if (state->ndmamem >= nitems(state->dmamem))
132 		return ENOMEM;
133 
134 	if (bus_dmamem_alloc(rk->rk_dmat, size, 16384, 0,
135 	    &seg, 1, &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO))
136 		return (bus_addr_t)-1;
137 
138 	if (bus_dmamap_create(rk->rk_dmat, size, 1, size, 0,
139 	    BUS_DMA_WAITOK, &map)) {
140 		bus_dmamem_free(rk->rk_dmat, &seg, 1);
141 		return (bus_addr_t)-1;
142 	}
143 
144 	if (bus_dmamap_load_raw(rk->rk_dmat, map, &seg, 1, size,
145 	    BUS_DMA_WAITOK)) {
146 		bus_dmamap_destroy(rk->rk_dmat, map);
147 		bus_dmamem_free(rk->rk_dmat, &seg, 1);
148 		return (bus_addr_t)-1;
149 	}
150 
151 	if (rk->rk_map) {
152 		if (rk->rk_map(rk->rk_cookie, seg.ds_addr, seg.ds_len)) {
153 			bus_dmamap_unload(rk->rk_dmat, map);
154 			bus_dmamap_destroy(rk->rk_dmat, map);
155 			bus_dmamem_free(rk->rk_dmat, &seg, 1);
156 			return (bus_addr_t)-1;
157 		}
158 	}
159 
160 	state->dmamem[state->ndmamem].rdm_map = map;
161 	state->dmamem[state->ndmamem].rdm_seg = seg;
162 	state->dmamem[state->ndmamem].rdm_size = size;
163 	state->ndmamem++;
164 
165 	return seg.ds_addr;
166 }
167 
168 int
169 rtkit_start(struct rtkit_state *state, uint32_t endpoint)
170 {
171 	struct mbox_channel *mc = state->mc;
172 	uint64_t reply;
173 
174 	reply = ((uint64_t)endpoint << RTKIT_MGMT_STARTEP_EP_SHIFT);
175 	reply |= RTKIT_MGMT_STARTEP_START;
176 	return rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_STARTEP, reply);
177 }
178 
179 int
180 rtkit_handle_mgmt(struct rtkit_state *state, struct aplmbox_msg *msg)
181 {
182 	struct mbox_channel *mc = state->mc;
183 	uint64_t minver, maxver, ver;
184 	uint64_t base, bitmap, reply;
185 	uint32_t endpoint;
186 	int error;
187 
188 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
189 	case RTKIT_MGMT_HELLO:
190 		minver = RTKIT_MGMT_HELLO_MINVER(msg->data0);
191 		maxver = RTKIT_MGMT_HELLO_MAXVER(msg->data0);
192 		if (minver > RTKIT_MAXVER) {
193 			printf("%s: unsupported minimum firmware version %lld\n",
194 			    __func__, minver);
195 			return EINVAL;
196 		}
197 		if (maxver < RTKIT_MINVER) {
198 			printf("%s: unsupported maximum firmware version %lld\n",
199 			    __func__, maxver);
200 			return EINVAL;
201 		}
202 		ver = min(RTKIT_MAXVER, maxver);
203 		error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_HELLO_ACK,
204 		    (ver << RTKIT_MGMT_HELLO_MINVER_SHIFT) |
205 		    (ver << RTKIT_MGMT_HELLO_MAXVER_SHIFT));
206 		if (error)
207 			return error;
208 		break;
209 	case RTKIT_MGMT_IOP_PWR_STATE_ACK:
210 		state->iop_pwrstate = RTKIT_MGMT_PWR_STATE(msg->data0);
211 		break;
212 	case RTKIT_MGMT_AP_PWR_STATE:
213 		state->ap_pwrstate = RTKIT_MGMT_PWR_STATE(msg->data0);
214 		break;
215 	case RTKIT_MGMT_EPMAP:
216 		base = RTKIT_MGMT_EPMAP_BASE(msg->data0);
217 		bitmap = RTKIT_MGMT_EPMAP_BITMAP(msg->data0);
218 		state->epmap |= (bitmap << (base * 32));
219 		reply = (base << RTKIT_MGMT_EPMAP_BASE_SHIFT);
220 		if (msg->data0 & RTKIT_MGMT_EPMAP_LAST)
221 			reply |= RTKIT_MGMT_EPMAP_LAST;
222 		else
223 			reply |= RTKIT_MGMT_EPMAP_MORE;
224 		error = rtkit_send(state->mc, RTKIT_EP_MGMT,
225 		    RTKIT_MGMT_EPMAP, reply);
226 		if (error)
227 			return error;
228 		if (msg->data0 & RTKIT_MGMT_EPMAP_LAST) {
229 			for (endpoint = 1; endpoint < 32; endpoint++) {
230 				if ((state->epmap & (1ULL << endpoint)) == 0)
231 					continue;
232 
233 				switch (endpoint) {
234 				case RTKIT_EP_CRASHLOG:
235 				case RTKIT_EP_SYSLOG:
236 				case RTKIT_EP_DEBUG:
237 				case RTKIT_EP_IOREPORT:
238 				case RTKIT_EP_OSLOG:
239 					error = rtkit_start(state, endpoint);
240 					if (error)
241 						return error;
242 					break;
243 				case RTKIT_EP_UNKNOWN:
244 					break;
245 				default:
246 					printf("%s: skipping endpoint %d\n",
247 					    __func__, endpoint);
248 					break;
249 				}
250 			}
251 		}
252 		break;
253 	default:
254 		printf("%s: unhandled management event 0x%016lld\n",
255 		    __func__, msg->data0);
256 		return EIO;
257 	}
258 
259 	return 0;
260 }
261 
262 int
263 rtkit_handle_crashlog(struct rtkit_state *state, struct aplmbox_msg *msg)
264 {
265 	struct mbox_channel *mc = state->mc;
266 	struct rtkit *rk = state->rk;
267 	bus_addr_t addr;
268 	bus_size_t size;
269 	int error;
270 
271 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
272 	case RTKIT_BUFFER_REQUEST:
273 		addr = RTKIT_BUFFER_ADDR(msg->data0);
274 		size = RTKIT_BUFFER_SIZE(msg->data0);
275 		if (addr)
276 			break;
277 
278 		if (rk) {
279 			addr = rtkit_alloc(state, size << PAGE_SHIFT);
280 			if (addr == (bus_addr_t)-1)
281 				return ENOMEM;
282 		}
283 
284 		error = rtkit_send(mc, RTKIT_EP_CRASHLOG, RTKIT_BUFFER_REQUEST,
285 		    (size << RTKIT_BUFFER_SIZE_SHIFT) | addr);
286 		if (error)
287 			return error;
288 		break;
289 	default:
290 		printf("%s: unhandled crashlog event 0x%016llx\n",
291 		    __func__, msg->data0);
292 		return EIO;
293 	}
294 
295 	return 0;
296 }
297 
298 int
299 rtkit_handle_syslog(struct rtkit_state *state, struct aplmbox_msg *msg)
300 {
301 	struct mbox_channel *mc = state->mc;
302 	struct rtkit *rk = state->rk;
303 	bus_addr_t addr;
304 	bus_size_t size;
305 	int error;
306 
307 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
308 	case RTKIT_BUFFER_REQUEST:
309 		addr = RTKIT_BUFFER_ADDR(msg->data0);
310 		size = RTKIT_BUFFER_SIZE(msg->data0);
311 		if (addr)
312 			break;
313 
314 		if (rk) {
315 			addr = rtkit_alloc(state, size << PAGE_SHIFT);
316 			if (addr == (bus_addr_t)-1)
317 				return ENOMEM;
318 		}
319 
320 		error = rtkit_send(mc, RTKIT_EP_SYSLOG, RTKIT_BUFFER_REQUEST,
321 		    (size << RTKIT_BUFFER_SIZE_SHIFT) | addr);
322 		if (error)
323 			return error;
324 		break;
325 	case RTKIT_SYSLOG_INIT:
326 		break;
327 	case RTKIT_SYSLOG_LOG:
328 		error = rtkit_send(mc, RTKIT_EP_SYSLOG,
329 		    RTKIT_MGMT_TYPE(msg->data0), msg->data0);
330 		if (error)
331 			return error;
332 		break;
333 	default:
334 		printf("%s: unhandled syslog event 0x%016llx\n",
335 		    __func__, msg->data0);
336 		return EIO;
337 	}
338 
339 	return 0;
340 }
341 
342 int
343 rtkit_handle_ioreport(struct rtkit_state *state, struct aplmbox_msg *msg)
344 {
345 	struct mbox_channel *mc = state->mc;
346 	struct rtkit *rk = state->rk;
347 	bus_addr_t addr;
348 	bus_size_t size;
349 	int error;
350 
351 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
352 	case RTKIT_BUFFER_REQUEST:
353 		addr = RTKIT_BUFFER_ADDR(msg->data0);
354 		size = RTKIT_BUFFER_SIZE(msg->data0);
355 		if (addr)
356 			break;
357 
358 		if (rk) {
359 			addr = rtkit_alloc(state, size << PAGE_SHIFT);
360 			if (addr == (bus_addr_t)-1)
361 				return ENOMEM;
362 		}
363 
364 		error = rtkit_send(mc, RTKIT_EP_IOREPORT, RTKIT_BUFFER_REQUEST,
365 		    (size << RTKIT_BUFFER_SIZE_SHIFT) | addr);
366 		if (error)
367 			return error;
368 		break;
369 	case RTKIT_IOREPORT_UNKNOWN1:
370 	case RTKIT_IOREPORT_UNKNOWN2:
371 		/* These unknown events have to be acked to make progress. */
372 		error = rtkit_send(mc, RTKIT_EP_IOREPORT,
373 		    RTKIT_MGMT_TYPE(msg->data0), msg->data0);
374 		if (error)
375 			return error;
376 		break;
377 	default:
378 		printf("%s: unhandled ioreport event 0x%016llx\n",
379 		    __func__, msg->data0);
380 		return EIO;
381 	}
382 
383 	return 0;
384 }
385 
386 int
387 rtkit_handle_oslog(struct rtkit_state *state, struct aplmbox_msg *msg)
388 {
389 	struct mbox_channel *mc = state->mc;
390 	int error;
391 
392 	switch (RTKIT_OSLOG_TYPE(msg->data0)) {
393 	case RTKIT_OSLOG_INIT:
394 		error = rtkit_send(mc, RTKIT_EP_OSLOG,
395 		    0, RTKIT_OSLOG_ACK << RTKIT_OSLOG_TYPE_SHIFT);
396 		if (error)
397 			return error;
398 		break;
399 	default:
400 		printf("%s: unhandled oslog event 0x%016llx\n",
401 		    __func__, msg->data0);
402 		return EIO;
403 	}
404 
405 	return 0;
406 }
407 
408 int
409 rtkit_poll(struct rtkit_state *state)
410 {
411 	struct mbox_channel *mc = state->mc;
412 	struct aplmbox_msg msg;
413 	void (*callback)(void *, uint64_t);
414 	void *arg;
415 	uint32_t endpoint;
416 	int error;
417 
418 	error = rtkit_recv(mc, &msg);
419 	if (error)
420 		return error;
421 
422 	endpoint = msg.data1;
423 	switch (endpoint) {
424 	case RTKIT_EP_MGMT:
425 		error = rtkit_handle_mgmt(state, &msg);
426 		if (error)
427 			return error;
428 		break;
429 	case RTKIT_EP_CRASHLOG:
430 		error = rtkit_handle_crashlog(state, &msg);
431 		if (error)
432 			return error;
433 		break;
434 	case RTKIT_EP_SYSLOG:
435 		error = rtkit_handle_syslog(state, &msg);
436 		if (error)
437 			return error;
438 		break;
439 	case RTKIT_EP_IOREPORT:
440 		error = rtkit_handle_ioreport(state, &msg);
441 		if (error)
442 			return error;
443 		break;
444 	case RTKIT_EP_OSLOG:
445 		error = rtkit_handle_oslog(state, &msg);
446 		if (error)
447 			return error;
448 		break;
449 	default:
450 		if (endpoint >= 32 && endpoint < 64 &&
451 		    state->callback[endpoint - 32]) {
452 			callback = state->callback[endpoint - 32];
453 			arg = state->arg[endpoint - 32];
454 			callback(arg, msg.data0);
455 			break;
456 		}
457 
458 		printf("%s: unhandled endpoint %d\n", __func__, msg.data1);
459 		return EIO;
460 	}
461 
462 	return 0;
463 }
464 
465 void
466 rtkit_rx_callback(void *cookie)
467 {
468 	rtkit_poll(cookie);
469 }
470 
471 struct rtkit_state *
472 rtkit_init(int node, const char *name, int flags, struct rtkit *rk)
473 {
474 	struct rtkit_state *state;
475 	struct mbox_client client;
476 
477 	state = malloc(sizeof(*state), M_DEVBUF, M_WAITOK | M_ZERO);
478 	client.mc_rx_callback = rtkit_rx_callback;
479 	client.mc_rx_arg = state;
480 	if (flags & RK_WAKEUP)
481 		client.mc_flags = MC_WAKEUP;
482 	else
483 		client.mc_flags = 0;
484 
485 	state->mc = mbox_channel(node, name, &client);
486 	if (state->mc == NULL) {
487 		free(state, M_DEVBUF, sizeof(*state));
488 		return NULL;
489 	}
490 	state->rk = rk;
491 
492 	state->iop_pwrstate = RTKIT_MGMT_PWR_STATE_SLEEP;
493 	state->ap_pwrstate = RTKIT_MGMT_PWR_STATE_QUIESCED;
494 
495 	return state;
496 }
497 
498 int
499 rtkit_boot(struct rtkit_state *state)
500 {
501 	/* Wake up! */
502 	return rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_ON);
503 }
504 
505 void
506 rtkit_shutdown(struct rtkit_state *state)
507 {
508 	struct rtkit *rk = state->rk;
509 	int i;
510 
511 	rtkit_set_ap_pwrstate(state, RTKIT_MGMT_PWR_STATE_QUIESCED);
512 	rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_SLEEP);
513 
514 	KASSERT(state->iop_pwrstate == RTKIT_MGMT_PWR_STATE_SLEEP);
515 	KASSERT(state->ap_pwrstate == RTKIT_MGMT_PWR_STATE_QUIESCED);
516 	state->epmap = 0;
517 
518 	/* Clean up our memory allocations. */
519 	for (i = 0; i < state->ndmamem; i++) {
520 		if (rk->rk_unmap) {
521 			rk->rk_unmap(rk->rk_cookie,
522 			    state->dmamem[i].rdm_seg.ds_addr,
523 			    state->dmamem[i].rdm_seg.ds_len);
524 		}
525 		bus_dmamap_unload(rk->rk_dmat, state->dmamem[i].rdm_map);
526 		bus_dmamap_destroy(rk->rk_dmat, state->dmamem[i].rdm_map);
527 		bus_dmamem_free(rk->rk_dmat, &state->dmamem[i].rdm_seg, 1);
528 	}
529 	state->ndmamem = 0;
530 }
531 
532 int
533 rtkit_set_ap_pwrstate(struct rtkit_state *state, uint16_t pwrstate)
534 {
535 	struct mbox_channel *mc = state->mc;
536 	int error, timo;
537 
538 	if (state->ap_pwrstate == pwrstate)
539 		return 0;
540 
541 	error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_AP_PWR_STATE,
542 	    pwrstate);
543 	if (error)
544 		return error;
545 
546 	for (timo = 0; timo < 100000; timo++) {
547 		error = rtkit_poll(state);
548 		if (error == EWOULDBLOCK) {
549 			delay(10);
550 			continue;
551 		}
552 
553 		KASSERT(error == 0);
554 		if (state->ap_pwrstate == pwrstate)
555 			break;
556 	}
557 
558 	return error;
559 }
560 
561 int
562 rtkit_set_iop_pwrstate(struct rtkit_state *state, uint16_t pwrstate)
563 {
564 	struct mbox_channel *mc = state->mc;
565 	int error, timo;
566 
567 	if (state->iop_pwrstate == pwrstate)
568 		return 0;
569 
570 	error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE,
571 	    pwrstate);
572 	if (error)
573 		return error;
574 
575 	for (timo = 0; timo < 100000; timo++) {
576 		error = rtkit_poll(state);
577 		if (error == EWOULDBLOCK) {
578 			delay(10);
579 			continue;
580 		}
581 
582 		KASSERT(error == 0);
583 		if (state->iop_pwrstate == pwrstate)
584 			break;
585 	}
586 
587 	return error;
588 }
589 
590 int
591 rtkit_start_endpoint(struct rtkit_state *state, uint32_t endpoint,
592     void (*callback)(void *, uint64_t), void *arg)
593 {
594 	if (endpoint < 32 || endpoint >= 64)
595 		return EINVAL;
596 
597 	if ((state->epmap & (1ULL << endpoint)) == 0)
598 		return EINVAL;
599 
600 	state->callback[endpoint - 32] = callback;
601 	state->arg[endpoint - 32] = arg;
602 	return rtkit_start(state, endpoint);
603 }
604 
605 int
606 rtkit_send_endpoint(struct rtkit_state *state, uint32_t endpoint,
607     uint64_t data)
608 {
609 	return rtkit_send(state->mc, endpoint, 0, data);
610 }
611