Home | History | Annotate | Line # | Download | only in apple
      1 /*	$NetBSD: apple_rtkit.c,v 1.1 2022/04/27 08:06:20 skrll Exp $ */
      2 /*	$OpenBSD: rtkit.c,v 1.3 2022/01/10 09:07:28 kettenis Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 2021 Mark Kettenis <kettenis (at) openbsd.org>
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  */
     19 
     20 #include <sys/param.h>
     21 #include <sys/systm.h>
     22 
     23 #include <sys/kmem.h>
     24 
     25 #include <dev/fdt/fdtvar.h>
     26 
     27 #include <arm/apple/apple_rtkit.h>
     28 #include <arm/apple/apple_mbox.h>
     29 
     30 
     31 #define RTKIT_EP_MGMT			0
     32 #define RTKIT_EP_CRASHLOG		1
     33 #define RTKIT_EP_SYSLOG			2
     34 #define RTKIT_EP_DEBUG			3
     35 #define RTKIT_EP_IOREPORT		4
     36 
     37 #define RTKIT_MGMT_TYPE_MASK		__BITS(59, 52)
     38 #define RTKIT_MGMT_TYPE(x)		__SHIFTOUT((x), RTKIT_MGMT_TYPE_MASK)
     39 
     40 #define RTKIT_MGMT_PWR_STATE_MASK	__BITS(7, 0)
     41 #define RTKIT_MGMT_PWR_STATE(x)		__SHIFTOUT((x), RTKIT_MGMT_PWR_STATE_MASK)
     42 #define RTKIT_MGMT_PWR_STATE_ON		0x20
     43 
     44 #define RTKIT_MGMT_HELLO		1
     45 #define RTKIT_MGMT_HELLO_ACK		2
     46 #define RTKIT_MGMT_STARTEP		5
     47 #define RTKIT_MGMT_IOP_PWR_STATE	6
     48 #define RTKIT_MGMT_IOP_PWR_STATE_ACK	7
     49 #define RTKIT_MGMT_EPMAP		8
     50 
     51 #define RTKIT_MGMT_HELLO_MINVER_MASK	__BITS(15, 0)
     52 #define RTKIT_MGMT_HELLO_MINVER(x)	__SHIFTOUT((x), RTKIT_MGMT_HELLO_MINVER_MASK)
     53 #define RTKIT_MGMT_HELLO_MAXVER_MASK	__BITS(31, 16)
     54 #define RTKIT_MGMT_HELLO_MAXVER(x)	__SHIFTOUT((x), RTKIT_MGMT_HELLO_MAXVER_MASK)
     55 
     56 #define RTKIT_MGMT_STARTEP_EP_SHIFT	32
     57 #define RTKIT_MGMT_STARTEP_EP_MASK	__BITS(39, 32)
     58 #define RTKIT_MGMT_STARTEP_START	__BIT(1)
     59 
     60 #define RTKIT_MGMT_EPMAP_LAST		__BIT(51)
     61 #define RTKIT_MGMT_EPMAP_BASE_MASK	__BITS(34, 32)
     62 #define RTKIT_MGMT_EPMAP_BASE(x)	__SHIFTOUT((x), RTKIT_MGMT_EPMAP_BASE_MASK)
     63 #define RTKIT_MGMT_EPMAP_BITMAP_MASK	__BITS(31, 0)
     64 #define RTKIT_MGMT_EPMAP_BITMAP(x)	__SHIFTOUT((x), RTKIT_MGMT_EPMAP_BITMAP_MASK)
     65 #define RTKIT_MGMT_EPMAP_MORE		__BIT(0)
     66 
     67 #define RTKIT_BUFFER_REQUEST		1
     68 #define RTKIT_BUFFER_ADDR_MASK		__BITS(41, 0)
     69 #define RTKIT_BUFFER_ADDR(x)		__SHIFTOUT((x), RTKIT_BUFFER_ADDR_MASK)
     70 #define RTKIT_BUFFER_SIZE_MASK		__BITS(51, 44)
     71 #define RTKIT_BUFFER_SIZE(x)		__SHIFTOUT((x), RTKIT_BUFFER_SIZE_MASK)
     72 
     73 /* Versions we support. */
     74 #define RTKIT_MINVER			11
     75 #define RTKIT_MAXVER			12
     76 
     77 struct rtkit_state {
     78 	struct fdtbus_mbox_channel	*mc;
     79 	int			pwrstate;
     80 	uint64_t		epmap;
     81 	void			(*callback[32])(void *, uint64_t);
     82 	void			*arg[32];
     83 };
     84 
     85 static int
     86 rtkit_recv(struct fdtbus_mbox_channel *mc, struct apple_mbox_msg *msg)
     87 {
     88 	int error, timo;
     89 
     90 	for (timo = 0; timo < 10000; timo++) {
     91 		error = fdtbus_mbox_recv(mc, msg, sizeof(*msg));
     92 		if (error == 0)
     93 			break;
     94 		delay(10);
     95 	}
     96 
     97 	return error;
     98 }
     99 
    100 static int
    101 rtkit_send(struct fdtbus_mbox_channel *mc, uint32_t endpoint,
    102     uint64_t type, uint64_t data)
    103 {
    104 	struct apple_mbox_msg msg;
    105 
    106 	msg.data0 = __SHIFTIN(type, RTKIT_MGMT_TYPE_MASK) | data;
    107 	msg.data1 = endpoint;
    108 	return fdtbus_mbox_send(mc, &msg, sizeof(msg));
    109 }
    110 
    111 static int
    112 rtkit_start(struct rtkit_state *state, uint32_t endpoint)
    113 {
    114 	struct fdtbus_mbox_channel *mc = state->mc;
    115 	uint64_t reply;
    116 
    117 	reply = __SHIFTIN(endpoint, RTKIT_MGMT_STARTEP_EP_MASK);
    118 	reply |= RTKIT_MGMT_STARTEP_START;
    119 	return rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_STARTEP, reply);
    120 }
    121 
    122 static int
    123 rtkit_handle_mgmt(struct rtkit_state *state, struct apple_mbox_msg *msg)
    124 {
    125 	struct fdtbus_mbox_channel *mc = state->mc;
    126 	uint64_t minver, maxver, ver;
    127 	uint64_t base, bitmap, reply;
    128 	uint32_t endpoint;
    129 	int error;
    130 
    131 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
    132 	case RTKIT_MGMT_HELLO:
    133 		minver = RTKIT_MGMT_HELLO_MINVER(msg->data0);
    134 		maxver = RTKIT_MGMT_HELLO_MAXVER(msg->data0);
    135 		if (minver > RTKIT_MAXVER) {
    136 			printf("unsupported minimum firmware version "
    137 			    "%"PRId64"\n", minver);
    138 			return EINVAL;
    139 		}
    140 		if (maxver < RTKIT_MINVER) {
    141 			printf("unsupported maximum firmware version "
    142 			"%"PRId64"\n", maxver);
    143 			return EINVAL;
    144 		}
    145 		ver = MIN(RTKIT_MAXVER, maxver);
    146 		error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_HELLO_ACK,
    147 		    __SHIFTIN(ver, RTKIT_MGMT_HELLO_MINVER_MASK) |
    148 		    __SHIFTIN(ver, RTKIT_MGMT_HELLO_MAXVER_MASK));
    149 		if (error)
    150 			return error;
    151 		break;
    152 
    153 	case RTKIT_MGMT_IOP_PWR_STATE_ACK:
    154 		state->pwrstate = RTKIT_MGMT_PWR_STATE(msg->data0);
    155 		break;
    156 
    157 	case RTKIT_MGMT_EPMAP:
    158 		base = RTKIT_MGMT_EPMAP_BASE(msg->data0);
    159 		bitmap = RTKIT_MGMT_EPMAP_BITMAP(msg->data0);
    160 		state->epmap |= (bitmap << (base * 32));
    161 		reply = __SHIFTIN(base, RTKIT_MGMT_EPMAP_BASE_MASK);
    162 		if (msg->data0 & RTKIT_MGMT_EPMAP_LAST)
    163 			reply |= RTKIT_MGMT_EPMAP_LAST;
    164 		else
    165 			reply |= RTKIT_MGMT_EPMAP_MORE;
    166 		error = rtkit_send(state->mc, RTKIT_EP_MGMT,
    167 		    RTKIT_MGMT_EPMAP, reply);
    168 		if (error)
    169 			return error;
    170 		if (msg->data0 & RTKIT_MGMT_EPMAP_LAST) {
    171 			for (endpoint = 1; endpoint < 32; endpoint++) {
    172 				if ((state->epmap & __BIT(endpoint)) == 0)
    173 					continue;
    174 
    175 				switch (endpoint) {
    176 				case RTKIT_EP_CRASHLOG:
    177 				case RTKIT_EP_DEBUG:
    178 				case RTKIT_EP_IOREPORT:
    179 					error = rtkit_start(state, endpoint);
    180 					if (error)
    181 						return error;
    182 					break;
    183 				}
    184 			}
    185 		}
    186 		break;
    187 	default:
    188 		printf("unhandled management event "
    189 		    "0x%016"PRIx64"\n", msg->data0);
    190 		return EIO;
    191 	}
    192 
    193 	return 0;
    194 }
    195 
    196 static int
    197 rtkit_handle_crashlog(struct rtkit_state *state, struct apple_mbox_msg *msg)
    198 {
    199 	struct fdtbus_mbox_channel *mc = state->mc;
    200 	bus_addr_t addr;
    201 	bus_size_t size;
    202 	int error;
    203 
    204 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
    205 	case RTKIT_BUFFER_REQUEST:
    206 		addr = RTKIT_BUFFER_ADDR(msg->data0);
    207 		size = RTKIT_BUFFER_SIZE(msg->data0);
    208 		// XXXNH WTF is this conditional
    209 		if (addr)
    210 			break;
    211 
    212 		error = rtkit_send(mc, RTKIT_EP_CRASHLOG, RTKIT_BUFFER_REQUEST,
    213 		    __SHIFTIN(size, RTKIT_BUFFER_SIZE_MASK) | addr);
    214 		if (error)
    215 			return error;
    216 		break;
    217 	default:
    218 		printf("unhandled crashlog event "
    219 		    "0x%016"PRIx64"\n", msg->data0);
    220 		return EIO;
    221 	}
    222 
    223 	return 0;
    224 }
    225 
    226 static int
    227 rtkit_handle_ioreport(struct rtkit_state *state, struct apple_mbox_msg *msg)
    228 {
    229 	struct fdtbus_mbox_channel *mc = state->mc;
    230 	bus_addr_t addr;
    231 	bus_size_t size;
    232 	int error;
    233 
    234 	switch (RTKIT_MGMT_TYPE(msg->data0)) {
    235 	case RTKIT_BUFFER_REQUEST:
    236 		addr = RTKIT_BUFFER_ADDR(msg->data0);
    237 		size = RTKIT_BUFFER_SIZE(msg->data0);
    238 		// XXXNH WTF is this conditional
    239 		if (addr)
    240 			break;
    241 		error = rtkit_send(mc, RTKIT_EP_IOREPORT, RTKIT_BUFFER_REQUEST,
    242 		    __SHIFTIN(size, RTKIT_BUFFER_SIZE_MASK) | addr);
    243 		if (error)
    244 			return error;
    245 		break;
    246 	default:
    247 		printf("unhandled ioreport event"
    248 		    "0x%016"PRIx64"\n", msg->data0);
    249 		return EIO;
    250 	}
    251 
    252 	return 0;
    253 }
    254 
    255 int
    256 rtkit_poll(struct rtkit_state *state)
    257 {
    258 	struct fdtbus_mbox_channel *mc = state->mc;
    259 	struct apple_mbox_msg msg;
    260 	void (*callback)(void *, uint64_t);
    261 	void *arg;
    262 	uint32_t endpoint;
    263 	int error;
    264 
    265 	error = rtkit_recv(mc, &msg);
    266 	if (error)
    267 		return error;
    268 
    269 	endpoint = msg.data1;
    270 	switch (endpoint) {
    271 	case RTKIT_EP_MGMT:
    272 		error = rtkit_handle_mgmt(state, &msg);
    273 		if (error)
    274 			return error;
    275 		break;
    276 	case RTKIT_EP_CRASHLOG:
    277 		error = rtkit_handle_crashlog(state, &msg);
    278 		if (error)
    279 			return error;
    280 		break;
    281 	case RTKIT_EP_IOREPORT:
    282 		error = rtkit_handle_ioreport(state, &msg);
    283 		if (error)
    284 			return error;
    285 		break;
    286 	default:
    287 		if (endpoint >= 32 && endpoint < 64 &&
    288 		    state->callback[endpoint - 32]) {
    289 			callback = state->callback[endpoint - 32];
    290 			arg = state->arg[endpoint - 32];
    291 			callback(arg, msg.data0);
    292 			break;
    293 		}
    294 
    295 		printf("unhandled endpoint %d\n", msg.data1);
    296 		return EIO;
    297 	}
    298 
    299 	return 0;
    300 }
    301 
    302 static void
    303 rtkit_rx_callback(void *cookie)
    304 {
    305 	rtkit_poll(cookie);
    306 }
    307 
    308 struct rtkit_state *
    309 rtkit_init(int node, const char *name)
    310 {
    311 	struct rtkit_state *state;
    312 
    313 	state = kmem_zalloc(sizeof(*state), KM_SLEEP);
    314 	if (name) {
    315 		state->mc = fdtbus_mbox_get(node, name, rtkit_rx_callback, state);
    316 	} else {
    317 		state->mc = fdtbus_mbox_get_index(node, 0, rtkit_rx_callback, state);
    318 	}
    319 	if (state->mc == NULL) {
    320 		kmem_free(state, sizeof(*state));
    321 
    322 		return NULL;
    323 	}
    324 
    325 	return state;
    326 }
    327 
    328 int
    329 rtkit_boot(struct rtkit_state *state)
    330 {
    331 	struct fdtbus_mbox_channel *mc = state->mc;
    332 	int error;
    333 
    334 	/* Wake up! */
    335 	error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE,
    336 	    RTKIT_MGMT_PWR_STATE_ON);
    337 	if (error) {
    338 		return error;
    339 	}
    340 
    341 	while (state->pwrstate != RTKIT_MGMT_PWR_STATE_ON)
    342 		rtkit_poll(state);
    343 
    344 	return 0;
    345 }
    346 
    347 int
    348 rtkit_start_endpoint(struct rtkit_state *state, uint32_t endpoint,
    349     void (*callback)(void *, uint64_t), void *arg)
    350 {
    351 	if (endpoint < 32 || endpoint >= 64)
    352 		return EINVAL;
    353 
    354 	if ((state->epmap & __BIT(endpoint)) == 0)
    355 		return EINVAL;
    356 
    357 	state->callback[endpoint - 32] = callback;
    358 	state->arg[endpoint - 32] = arg;
    359 	return rtkit_start(state, endpoint);
    360 }
    361 
    362 int
    363 rtkit_send_endpoint(struct rtkit_state *state, uint32_t endpoint,
    364     uint64_t data)
    365 {
    366 
    367 	return rtkit_send(state->mc, endpoint, 0, data);
    368 }
    369