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