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