1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This code sets up the callbacks(vx_handlers) so that the firmware may call 28 * into the kernel for console input and/or output while in the debugger. 29 * The callbacks that execute in debug mode must be careful to not 30 * allocate memory, access mutexes, etc. because most kernel services are 31 * not available during this mode. 32 * 33 * This code, and the underlying code that supports the polled input, is very 34 * hard to debug. In order to get the code to execute, polled input must 35 * provide input to the debugger. If anything goes wrong with the code, then 36 * it is hard to debug the debugger. If there are any problems to debug, 37 * the following is useful: 38 * 39 * set the polled_debug variable in /etc/system 40 * set polled_debug=1 41 * 42 * This variable will register the callbacks but will not throw the switch 43 * in the firmware. The callbacks can be executed by hand from the firmware. 44 * Boot the system and drop down to the firmware. 45 * 46 * ok " /os-io" select-dev 47 * 48 * The following will cause the polled_give_input to execute: 49 * ok take 50 * 51 * The following will cause the polled_take_input to execute: 52 * ok give 53 * 54 * The following will cause polled_read to execute: 55 * ok read 56 */ 57 58 #include <sys/stropts.h> 59 #include <v9/sys/prom_isa.h> 60 #include <sys/devops.h> 61 #include <sys/modctl.h> 62 #include <sys/ddi.h> 63 #include <sys/sunddi.h> 64 #include <sys/promif.h> 65 #include <sys/note.h> 66 #include <sys/consdev.h> 67 #include <sys/polled_io.h> 68 #include <sys/kdi.h> 69 #ifdef sun4v 70 #include <sys/ldoms.h> 71 #endif 72 73 /* 74 * Internal Functions 75 */ 76 static void polled_give_input(cell_t *cif); 77 static void polled_read(cell_t *cif); 78 static void polled_take_input(cell_t *cif); 79 80 static void polled_write(cell_t *cif); 81 static void polled_io_register(cons_polledio_t *, 82 polled_io_console_type_t, int); 83 static int polled_io_take_console(polled_io_console_type_t, int); 84 static int polled_io_release_console(polled_io_console_type_t, int); 85 86 /* 87 * State information regarding the input/output device 88 */ 89 static polled_device_t polled_input_device; 90 static polled_device_t polled_output_device; 91 static int polled_vx_handlers_init = 0; 92 93 extern void add_vx_handler(char *name, int flag, void (*func)(cell_t *)); 94 95 /* 96 * This is a useful flag for debugging the entry points. This flag 97 * allows us to exercise the entry points from the firmware without 98 * switching the firmware's notion of the input device. 99 */ 100 int polled_debug = 0; 101 102 /* 103 * This routine is called to initialize polled I/O. We insert our entry 104 * points so that the firmware will call into this code 105 * when the switch is thrown in polled_io_take_console(). 106 */ 107 void 108 polled_io_init(void) 109 { 110 111 /* 112 * Only do the initialization once 113 */ 114 if (polled_vx_handlers_init != 0) 115 return; 116 #ifdef sun4v 117 if (!domaining_enabled()) { 118 #endif 119 /* 120 * Add the vx_handlers for the different functions that 121 * need to be accessed from firmware. 122 */ 123 add_vx_handler("enter-input", 1, polled_give_input); 124 125 add_vx_handler("read", 1, polled_read); 126 127 add_vx_handler("exit-input", 1, polled_take_input); 128 129 add_vx_handler("write", 1, polled_write); 130 #ifdef sun4v 131 } 132 #endif 133 134 /* 135 * Initialize lock to protect multiple thread access to the 136 * polled_input_device structure. This does not protect 137 * us from access in debug mode. 138 */ 139 mutex_init(&polled_input_device.polled_device_lock, 140 NULL, MUTEX_DRIVER, NULL); 141 142 /* 143 * Initialize lock to protect multiple thread access to the 144 * polled_output_device structure. This does not protect 145 * us from access in debug mode. 146 */ 147 mutex_init(&polled_output_device.polled_device_lock, 148 NULL, MUTEX_DRIVER, NULL); 149 150 polled_vx_handlers_init = 1; 151 } 152 153 /* 154 * Register a device for input or output. The polled_io structure 155 * will be filled in with the callbacks that are appropriate for 156 * that device. 157 */ 158 int 159 polled_io_register_callbacks( 160 cons_polledio_t *polled_io, 161 int flags 162 ) 163 { 164 /* 165 * If the input structure entries aren't filled in, then register this 166 * structure as an input device. 167 */ 168 if ((polled_io->cons_polledio_getchar != NULL) && 169 (polled_io->cons_polledio_ischar != NULL)) { 170 171 polled_io_register(polled_io, POLLED_IO_CONSOLE_INPUT, flags); 172 } 173 174 /* 175 * If the output structure entries aren't filled in, then register this 176 * structure as an output device. 177 */ 178 if (polled_io->cons_polledio_putchar != NULL) { 179 180 polled_io_register(polled_io, POLLED_IO_CONSOLE_OUTPUT, flags); 181 } 182 183 cons_polledio = polled_io; 184 185 return (DDI_SUCCESS); 186 } 187 188 /* 189 * Sends string through the polled output interfaces when the 190 * system is panicing. 191 */ 192 void 193 polled_io_cons_write(uchar_t *text, size_t len) 194 { 195 cons_polledio_t *pio = polled_output_device.polled_io; 196 int i; 197 198 for (i = 0; i < len; i++) 199 pio->cons_polledio_putchar( 200 pio->cons_polledio_argument, text[i]); 201 } 202 203 /* 204 * Generic internal routine for registering a polled input or output device. 205 */ 206 /* ARGSUSED */ 207 static void 208 polled_io_register( 209 cons_polledio_t *polled_io, 210 polled_io_console_type_t type, 211 int flags 212 ) 213 { 214 switch (type) { 215 case POLLED_IO_CONSOLE_INPUT: 216 /* 217 * Grab the device lock, because we are going to access 218 * protected structure entries. We do this before the 219 * POLLED_IO_CONSOLE_OPEN_INPUT so that we serialize 220 * registration. 221 */ 222 mutex_enter(&polled_input_device.polled_device_lock); 223 224 /* 225 * Save the polled_io pointers so that we can access 226 * them later. 227 */ 228 polled_input_device.polled_io = polled_io; 229 230 mutex_exit(&polled_input_device.polled_device_lock); 231 232 233 if (!polled_debug) { 234 /* 235 * Tell the generic console framework to 236 * repoint firmware's stdin to this keyboard device. 237 */ 238 (void) polled_io_take_console(type, 0); 239 } 240 241 break; 242 243 case POLLED_IO_CONSOLE_OUTPUT: 244 /* 245 * Grab the device lock, because we are going to access 246 * protected structure entries. We do this before the 247 * POLLED_IO_CONSOLE_OPEN_OUTPUT so that we serialize 248 * registration. 249 */ 250 mutex_enter(&polled_output_device.polled_device_lock); 251 252 /* 253 * Save the polled_io pointers so that we can access 254 * them later. 255 */ 256 polled_output_device.polled_io = polled_io; 257 258 mutex_exit(&polled_output_device.polled_device_lock); 259 260 if (!polled_debug) { 261 /* 262 * Tell the generic console framework to 263 * repoint firmware's stdout to the framebuffer. 264 */ 265 (void) polled_io_take_console(type, 0); 266 } 267 268 break; 269 } 270 } 271 272 /* 273 * This is the routine that is called to throw the switch from the 274 * firmware's ownership of stdout/stdin to the kernel. 275 */ 276 /* ARGSUSED */ 277 static int 278 polled_io_take_console( 279 polled_io_console_type_t type, 280 int flags 281 ) 282 { 283 284 #ifdef sun4v 285 if (domaining_enabled()) 286 return (DDI_SUCCESS); 287 #endif 288 289 switch (type) { 290 case POLLED_IO_CONSOLE_INPUT: 291 /* 292 * Call into firmware to switch to the kernel I/O handling. 293 * We will save the old value of stdin so that we can 294 * restore it if the device is released. 295 */ 296 #ifdef DEBUG_OBP 297 /* 298 * This code is useful to trace through 299 * what the prom is doing 300 */ 301 prom_interpret( 302 "stdin @ swap ! trace-on \" /os-io\" input trace-off", 303 (uintptr_t)&polled_input_device.polled_old_handle, 304 0, 0, 0, 0); 305 #endif 306 307 prom_interpret( 308 "stdin @ swap ! \" /os-io\" open-dev stdin !", 309 (uintptr_t)&polled_input_device.polled_old_handle, 310 0, 0, 0, 0); 311 312 break; 313 314 case POLLED_IO_CONSOLE_OUTPUT: 315 /* 316 * Call into firmware to switch to the kernel I/O handling. 317 * We will save the old value of stdout so that we can 318 * restore it if the device is released. 319 */ 320 prom_interpret("stdout @ swap ! \" /os-io\" open-dev stdout !", 321 (uintptr_t)&polled_output_device.polled_old_handle, 322 0, 0, 0, 0); 323 324 break; 325 } 326 327 return (DDI_SUCCESS); 328 } 329 330 /* 331 * This is the routine that the firmware calls to save any state information 332 * before using the input device. This routine, and all of the 333 * routines that it calls, are responsible for saving any state 334 * information so that it can be restored when debug mode is over. 335 * 336 * WARNING: This routine runs in debug mode. 337 */ 338 static void 339 polled_give_input(cell_t *cif) 340 { 341 cons_polledio_t *polled_io; 342 uint_t out_args; 343 344 /* 345 * Calculate the offset of the return arguments 346 */ 347 out_args = CIF_MIN_SIZE + p1275_cell2uint(cif[CIF_NUMBER_IN_ARGS]); 348 349 /* 350 * There is one argument being passed back to firmware. 351 */ 352 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 353 cif[out_args] = p1275_uint2cell(CIF_SUCCESS); 354 355 /* 356 * We check to see if there is an 357 * input device that has been registered. 358 */ 359 polled_io = polled_input_device.polled_io; 360 361 if (polled_io == NULL) { 362 return; 363 } 364 365 /* 366 * Call down to the lower layers to save the state. 367 */ 368 polled_io->cons_polledio_enter(polled_io->cons_polledio_argument); 369 } 370 371 /* 372 * This is the routine that the firmware calls 373 * when it wants to read a character. 374 * We will call to the lower layers to see if there is any input data 375 * available. 376 * 377 * WARNING: This routine runs in debug mode. 378 */ 379 static void 380 polled_read(cell_t *cif) 381 { 382 uint_t actual; 383 cons_polledio_t *polled_io; 384 uint_t in_args; 385 uint_t out_args; 386 uchar_t *buffer; 387 uint_t buflen; 388 uchar_t key; 389 390 /* 391 * The number of arguments passed in by the firmware 392 */ 393 in_args = p1275_cell2uint(cif[CIF_NUMBER_IN_ARGS]); 394 395 /* 396 * Calculate the location of the first out arg. This location is 397 * CIF_MIN_SIZE plus the in argument locations. 398 */ 399 out_args = CIF_MIN_SIZE + in_args; 400 401 /* 402 * The firmware should pass in a pointer to a buffer, and the 403 * number of characters it expects or expects to write. 404 * If 2 arguments are not passed in, then return an error. 405 */ 406 if (in_args != 2) { 407 408 /* 409 * Tell firmware how many arguments we are passing back. 410 */ 411 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 412 413 /* 414 * Tell the firmware that we cannot give it any characters. 415 */ 416 cif[out_args] = p1275_uint2cell(CIF_FAILURE); 417 418 return; 419 } 420 421 /* 422 * Get the address of where to copy the characters into. 423 */ 424 buffer = (uchar_t *)(uintptr_t)p1275_cell2uint(cif[CIF_MIN_SIZE+0]); 425 426 /* 427 * Get the length of the buffer that we can copy characters into. 428 */ 429 buflen = p1275_cell2uint(cif[CIF_MIN_SIZE+1]); 430 431 /* 432 * Make sure there is enough room in the buffer to copy the 433 * characters into. 434 */ 435 if (buflen == 0) { 436 437 /* 438 * Tell the OBP that we cannot give it any characters. 439 */ 440 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 441 442 /* 443 * Tell the firmware that we cannot give it any characters. 444 */ 445 cif[out_args] = p1275_uint2cell(CIF_FAILURE); 446 447 return; 448 } 449 450 /* 451 * Pass back whether or not the operation was a success or 452 * failure plus the actual number of bytes in the buffer. 453 * Tell firmware how many arguments we are passing back. 454 */ 455 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)2); 456 457 /* 458 * Initialize the cif to be "no characters" 459 */ 460 cif[out_args+0] = p1275_uint2cell(CIF_SUCCESS); 461 cif[out_args+1] = p1275_uint2cell(CIF_NO_CHARACTERS); 462 463 /* 464 * We check to see if there is an 465 * input device that has been registered. 466 */ 467 polled_io = polled_input_device.polled_io; 468 469 if (polled_io == NULL || 470 polled_io->cons_polledio_ischar == NULL) { 471 472 /* 473 * The cif structure is already set up to return 474 * no characters. 475 */ 476 477 return; 478 } 479 480 actual = 0; 481 482 /* 483 * Obtain the characters 484 */ 485 while (polled_io->cons_polledio_ischar( 486 polled_io->cons_polledio_argument) == B_TRUE) { 487 488 /* 489 * Make sure that we don't overrun the buffer. 490 */ 491 if (actual == buflen) { 492 493 break; 494 } 495 496 /* 497 * Call down to the device to copy the input data into the 498 * buffer. 499 */ 500 key = polled_io->cons_polledio_getchar( 501 polled_io->cons_polledio_argument); 502 503 *(buffer + actual) = key; 504 505 actual++; 506 } 507 508 /* 509 * There is a special return code when there is no data. 510 */ 511 if (actual == 0) { 512 513 /* 514 * The cif structure is already set up to return 515 * no characters. 516 */ 517 518 return; 519 } 520 521 /* 522 * Tell firmware how many characters we are sending it. 523 */ 524 cif[out_args+0] = p1275_uint2cell((uint_t)CIF_SUCCESS); 525 cif[out_args+1] = p1275_uint2cell((uint_t)actual); 526 } 527 528 /* 529 * This is the routine that firmware calls when it is giving up control of the 530 * input device. This routine, and the lower layer routines that it calls, 531 * are responsible for restoring the controller state to the state it was 532 * in before firmware took control. 533 * 534 * WARNING: This routine runs in debug mode. 535 */ 536 static void 537 polled_take_input(cell_t *cif) 538 { 539 cons_polledio_t *polled_io; 540 uint_t out_args; 541 542 /* 543 * Calculate the offset of the return arguments 544 */ 545 out_args = CIF_MIN_SIZE + p1275_cell2uint(cif[CIF_NUMBER_IN_ARGS]); 546 547 /* 548 * There is one argument being passed back to firmware. 549 */ 550 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 551 cif[out_args] = p1275_uint2cell(CIF_SUCCESS); 552 553 /* 554 * We check the pointer to see if there is an 555 * input device that has been registered. 556 */ 557 polled_io = polled_input_device.polled_io; 558 559 if (polled_io == NULL) { 560 return; 561 } 562 563 /* 564 * Call down to the lower layers to save the state. 565 */ 566 polled_io->cons_polledio_exit(polled_io->cons_polledio_argument); 567 } 568 569 /* 570 * This is the routine that the firmware calls when 571 * it wants to write a character. 572 * 573 * WARNING: This routine runs in debug mode. 574 */ 575 static void 576 polled_write(cell_t *cif) 577 { 578 cons_polledio_t *polled_io; 579 uint_t in_args; 580 uint_t out_args; 581 uchar_t *buffer; 582 uint_t buflen; 583 584 /* 585 * The number of arguments passed in by the firmware 586 */ 587 in_args = p1275_cell2uint(cif[CIF_NUMBER_IN_ARGS]); 588 589 /* 590 * Calculate the location of the first out arg. This location is 591 * CIF_MIN_SIZE (name + no. in args + no. out args) plus the 592 * in argument locations. 593 */ 594 out_args = CIF_MIN_SIZE + in_args; 595 596 /* 597 * The firmware should pass in a pointer to a buffer, and the 598 * number of characters it expects or expects to write. 599 * If 2 arguments are not passed in, then return an error. 600 */ 601 if (in_args != 2) { 602 603 /* 604 * Tell firmware how many arguments we are passing back. 605 */ 606 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 607 608 609 /* 610 * Tell the firmware that we cannot give it any characters. 611 */ 612 cif[out_args] = p1275_uint2cell(CIF_FAILURE); 613 614 return; 615 } 616 617 /* 618 * Get the address of where to copy the characters into. 619 */ 620 buffer = (uchar_t *)(uintptr_t)p1275_cell2uint(cif[CIF_MIN_SIZE+0]); 621 622 /* 623 * Get the length of the buffer that we can copy characters into. 624 */ 625 buflen = p1275_cell2uint(cif[CIF_MIN_SIZE+1]); 626 627 /* 628 * Make sure there is enough room in the buffer to copy the 629 * characters into. 630 */ 631 if (buflen == 0) { 632 633 /* 634 * Tell the OBP that we cannot give it any characters. 635 */ 636 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)1); 637 638 /* 639 * Tell the firmware that we cannot give it any characters. 640 */ 641 cif[out_args] = p1275_uint2cell(CIF_FAILURE); 642 643 return; 644 } 645 646 647 /* 648 * Tell the firmware how many arguments we are passing back. 649 */ 650 cif[CIF_NUMBER_OUT_ARGS] = p1275_uint2cell((uint_t)2); 651 652 /* 653 * Initialize the cif to success 654 */ 655 cif[out_args+0] = p1275_uint2cell(CIF_SUCCESS); 656 cif[out_args+1] = p1275_uint2cell(0); 657 658 /* 659 * We check the pointer to see if there is an 660 * input device that has been registered. 661 */ 662 polled_io = polled_output_device.polled_io; 663 664 if (polled_io == NULL) { 665 666 /* 667 * The cif is already initialized 668 */ 669 return; 670 } 671 672 polled_io_cons_write(buffer, (size_t)buflen); 673 674 /* 675 * Tell the firmware how many characters we are sending it. 676 */ 677 cif[out_args+0] = p1275_uint2cell((uint_t)CIF_SUCCESS); 678 cif[out_args+1] = p1275_uint2cell((uint_t)buflen); 679 } 680