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
polled_io_init(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
polled_io_register_callbacks(cons_polledio_t * polled_io,int flags)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
polled_io_cons_write(uchar_t * text,size_t len)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
polled_io_register(cons_polledio_t * polled_io,polled_io_console_type_t type,int flags)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
polled_io_take_console(polled_io_console_type_t type,int flags)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
polled_give_input(cell_t * cif)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
polled_read(cell_t * cif)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
polled_take_input(cell_t * cif)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
polled_write(cell_t * cif)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