1 /* $OpenBSD: rtkit.c,v 1.11 2022/12/06 23:18:54 kettenis 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 483 state->mc = mbox_channel(node, name, &client); 484 if (state->mc == NULL) { 485 free(state, M_DEVBUF, sizeof(*state)); 486 return NULL; 487 } 488 state->rk = rk; 489 490 state->iop_pwrstate = RTKIT_MGMT_PWR_STATE_SLEEP; 491 state->ap_pwrstate = RTKIT_MGMT_PWR_STATE_QUIESCED; 492 493 return state; 494 } 495 496 int 497 rtkit_boot(struct rtkit_state *state) 498 { 499 /* Wake up! */ 500 return rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_ON); 501 } 502 503 void 504 rtkit_shutdown(struct rtkit_state *state) 505 { 506 struct rtkit *rk = state->rk; 507 int i; 508 509 rtkit_set_ap_pwrstate(state, RTKIT_MGMT_PWR_STATE_QUIESCED); 510 rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_SLEEP); 511 512 KASSERT(state->iop_pwrstate == RTKIT_MGMT_PWR_STATE_SLEEP); 513 KASSERT(state->ap_pwrstate == RTKIT_MGMT_PWR_STATE_QUIESCED); 514 state->epmap = 0; 515 516 /* Clean up our memory allocations. */ 517 for (i = 0; i < state->ndmamem; i++) { 518 if (rk->rk_unmap) { 519 rk->rk_unmap(rk->rk_cookie, 520 state->dmamem[i].rdm_seg.ds_addr, 521 state->dmamem[i].rdm_seg.ds_len); 522 } 523 bus_dmamap_unload(rk->rk_dmat, state->dmamem[i].rdm_map); 524 bus_dmamap_destroy(rk->rk_dmat, state->dmamem[i].rdm_map); 525 bus_dmamem_free(rk->rk_dmat, &state->dmamem[i].rdm_seg, 1); 526 } 527 state->ndmamem = 0; 528 } 529 530 int 531 rtkit_set_ap_pwrstate(struct rtkit_state *state, uint16_t pwrstate) 532 { 533 struct mbox_channel *mc = state->mc; 534 int error, timo; 535 536 if (state->ap_pwrstate == pwrstate) 537 return 0; 538 539 error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_AP_PWR_STATE, 540 pwrstate); 541 if (error) 542 return error; 543 544 for (timo = 0; timo < 100000; timo++) { 545 error = rtkit_poll(state); 546 if (error == EWOULDBLOCK) { 547 delay(10); 548 continue; 549 } 550 551 KASSERT(error == 0); 552 if (state->ap_pwrstate == pwrstate) 553 break; 554 } 555 556 return error; 557 } 558 559 int 560 rtkit_set_iop_pwrstate(struct rtkit_state *state, uint16_t pwrstate) 561 { 562 struct mbox_channel *mc = state->mc; 563 int error, timo; 564 565 if (state->iop_pwrstate == pwrstate) 566 return 0; 567 568 error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE, 569 pwrstate); 570 if (error) 571 return error; 572 573 for (timo = 0; timo < 100000; timo++) { 574 error = rtkit_poll(state); 575 if (error == EWOULDBLOCK) { 576 delay(10); 577 continue; 578 } 579 580 KASSERT(error == 0); 581 if (state->iop_pwrstate == pwrstate) 582 break; 583 } 584 585 return error; 586 } 587 588 int 589 rtkit_start_endpoint(struct rtkit_state *state, uint32_t endpoint, 590 void (*callback)(void *, uint64_t), void *arg) 591 { 592 if (endpoint < 32 || endpoint >= 64) 593 return EINVAL; 594 595 if ((state->epmap & (1ULL << endpoint)) == 0) 596 return EINVAL; 597 598 state->callback[endpoint - 32] = callback; 599 state->arg[endpoint - 32] = arg; 600 return rtkit_start(state, endpoint); 601 } 602 603 int 604 rtkit_send_endpoint(struct rtkit_state *state, uint32_t endpoint, 605 uint64_t data) 606 { 607 return rtkit_send(state->mc, endpoint, 0, data); 608 } 609