xref: /openbsd/sys/arch/hppa/stand/libsa/cmd_hppa.c (revision a6445c1d)
1 /*	$OpenBSD: cmd_hppa.c,v 1.12 2010/12/06 22:51:45 jasper Exp $	*/
2 
3 /*
4  * Copyright (c) 2002, 2009 Miodrag Vallat
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 /* would come from <sys/param.h> if -D_KERNEL */
31 #define offsetof(s, e) ((size_t)&((s *)0)->e)
32 
33 #include <machine/iomod.h>
34 #include <machine/pdc.h>
35 
36 #include <arch/hppa/dev/cpudevs.h>
37 #include <arch/hppa/dev/elroyreg.h>
38 
39 #include <dev/pci/pcireg.h>
40 #include <dev/pci/pcidevs.h>
41 
42 #include <libsa.h>
43 #include "cmd.h"
44 #include "dev_hppa.h"	/* pdc */
45 
46 extern struct stable_storage sstor;
47 extern int sstorsiz;
48 
49 /* storage sizes we're interested in */
50 #define	CONSOLEOFFSET \
51 	offsetof(struct stable_storage, ss_console)
52 #define	CONSOLESIZE \
53 	(offsetof(struct stable_storage, ss_console) + \
54 	 sizeof(struct device_path))
55 
56 #define	KEYBOARDOFFSET \
57 	offsetof(struct stable_storage, ss_keyboard)
58 #define	KEYBOARDSIZE \
59 	(offsetof(struct stable_storage, ss_keyboard) + \
60 	 sizeof(struct device_path))
61 
62 /*
63  * Table for the possible console devices found during the device walk.
64  */
65 struct consoledev {
66 	struct device_path dp;
67 	int	type;
68 	int	iodc_type;
69 	int	iodc_model;
70 };
71 
72 #define	PS2		1
73 #define	HIL		2
74 #define	USB		3
75 #define	SERIAL		4
76 #define	GRAPHICS	5
77 
78 #define	MAX_SERIALS	4
79 #define	MAX_KEYBOARDS	4
80 #define	MAX_GRAPHICS	4
81 
82 struct consoledev serials[MAX_SERIALS];
83 struct consoledev keyboards[MAX_KEYBOARDS];
84 struct consoledev graphics[MAX_GRAPHICS];
85 
86 int walked;
87 
88 void	bus_walk(struct device_path *, int);
89 uint32_t dino_conf_read(u_int, int, int, u_int);
90 uint32_t elroy_conf_read(u_int, int, int, u_int);
91 int	path_match(struct device_path *, struct device_path *);
92 void	path_shift(struct device_path *, int);
93 void	pci_bus_walk(struct device_path *, struct iodc_data *,
94 	    struct pdc_memmap *);
95 void	register_device(struct consoledev *, int, struct device_path *,
96 	    struct iodc_data *, int, int);
97 
98 int	Xconsole(void);
99 void	print_console(void);
100 int	set_graphics(struct device_path *, int, char *);
101 int	set_serial(struct device_path *, int, char *);
102 int	set_console(struct device_path *);
103 
104 int	Xkeyboard(void);
105 void	print_keyboard(void);
106 int	set_keyboard(struct device_path *);
107 
108 struct cmd_table cmd_machine[] = {
109 	{ "console",	CMDT_CMD,	Xconsole },
110 	{ "keyboard",	CMDT_CMD,	Xkeyboard },
111 	{ NULL, },
112 };
113 
114 /* value to console speed table */
115 const int i_speeds[] = {
116 	50,
117 	75,
118 	110,
119 	150,
120 	300,
121 	600,
122 	1200,
123 	2400,
124 	4800,
125 	7200,
126 	9600,
127 	19200,
128 	38400,
129 	57600,
130 	115200,
131 	230400,
132 };
133 
134 const char *c_speeds[] = {
135 	"50",
136 	"75",
137 	"110",
138 	"150",
139 	"300",
140 	"600",
141 	"1200",
142 	"2400",
143 	"4800",
144 	"7200",
145 	"9600",
146 	"19200",
147 	"38400",
148 	"57600",
149 	"115200",
150 	"230400",
151 };
152 
153 /* values to console parity table */
154 const char *parities[] = {
155 	"none",
156 	"odd",
157 	"<unknown parity>",
158 	"even",
159 };
160 
161 /*
162  * C O N S O L E   S E T T I N G S
163  */
164 
165 void
166 print_console()
167 {
168 	int port, mode, speed, parity, bits;
169 	int i;
170 
171 #ifdef DEBUG
172 	printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
173 	    sstor.ss_console.dp_flags,
174 	    sstor.ss_console.dp_mod,
175 	    sstor.ss_console.dp_bc[0],
176 	    sstor.ss_console.dp_bc[1],
177 	    sstor.ss_console.dp_bc[2],
178 	    sstor.ss_console.dp_bc[3],
179 	    sstor.ss_console.dp_bc[4],
180 	    sstor.ss_console.dp_bc[5]);
181 
182 	printf("console path %x/%x/%x/%x/%x/%x\n",
183 	    sstor.ss_console.dp_layers[0],
184 	    sstor.ss_console.dp_layers[1],
185 	    sstor.ss_console.dp_layers[2],
186 	    sstor.ss_console.dp_layers[3],
187 	    sstor.ss_console.dp_layers[4],
188 	    sstor.ss_console.dp_layers[5]);
189 #endif
190 
191 	printf("Console path: ");
192 
193 	/* look for a serial console */
194 	for (port = i = 0; i < MAX_SERIALS; i++)
195 		if (path_match(&serials[i].dp, &sstor.ss_console)) {
196 			port = i + 1;
197 			break;
198 		}
199 
200 	if (port == 0) {
201 		/*
202 		 * Graphics console
203 		 */
204 
205 		for (port = i = 0; i < MAX_GRAPHICS; i++)
206 			if (path_match(&graphics[i].dp, &sstor.ss_console)) {
207 				port = i;
208 				break;
209 			}
210 
211 		/*
212 		 * If the console could still not be identified, consider
213 		 * it is a simplified encoding for the default graphics
214 		 * console. Hence port == 0, no need to check.
215 		 */
216 		if (port == 0)
217 			printf("graphics");
218 		else
219 			printf("graphics_%d", port);
220 
221 		mode = sstor.ss_console.dp_layers[0];
222 		if (mode != 0)
223 			printf(".%d", mode);
224 	} else {
225 		/*
226 		 * Serial console
227 		 */
228 
229 		if (port == 1)
230 			printf("rs232");
231 		else
232 			printf("rs232_%d", port);
233 
234 		speed = PZL_SPEED(sstor.ss_console.dp_layers[0]);
235 		printf(".%d", i_speeds[speed]);
236 
237 		bits = PZL_BITS(sstor.ss_console.dp_layers[0]);
238 		printf(".%d", bits);
239 
240 		parity = PZL_PARITY(sstor.ss_console.dp_layers[0]);
241 		printf(".%s", parities[parity]);
242 	}
243 
244 	printf("\n");
245 }
246 
247 int
248 set_graphics(console, port, arg)
249 	struct device_path *console;
250 	int port;
251 	char *arg;
252 {
253 	int maxmode, mode = 0;
254 	char *digit;
255 
256 	/* head */
257 	if (graphics[port].type == 0) {
258 		printf("no such device found\n");
259 		return 0;
260 	}
261 
262 	/* mode */
263 	if (arg != NULL) {
264 		for (digit = arg; *digit != '\0'; digit++) {
265 			if (*digit >= '0' && *digit <= '9')
266 				mode = 10 * mode + (*digit - '0');
267 			else {
268 				printf("invalid mode specification, %s\n", arg);
269 				return 0;
270 			}
271 		}
272 
273 		if (mode <= 0) {
274 			printf("invalid mode specification, %s\n", arg);
275 			return 0;
276 		}
277 	}
278 
279 	/*
280 	 * If we are just changing the mode of the same graphics
281 	 * console, check that our mode is in the valid range.
282 	 */
283 	if (path_match(&graphics[port].dp, &sstor.ss_console)) {
284 		maxmode = sstor.ss_console.dp_layers[1];
285 
286 		/* pick back same mode if unspecified */
287 		if (mode == 0)
288 			mode = sstor.ss_console.dp_layers[0];
289 
290 		if (mode > maxmode) {
291 			printf("invalid mode value, available range is 1-%d\n",
292 			    maxmode);
293 			return 0;
294 		}
295 	} else {
296 		if (mode == 0)
297 			mode = 1;
298 		maxmode = mode;
299 	}
300 
301 	*console = graphics[port].dp;
302 	console->dp_layers[0] = mode;
303 	console->dp_layers[1] = maxmode;
304 	console->dp_layers[2] = console->dp_layers[3] =
305 	console->dp_layers[4] = console->dp_layers[5] = 0;
306 
307 	return 1;
308 }
309 
310 int
311 set_serial(console, port, arg)
312 	struct device_path *console;
313 	int port;
314 	char *arg;
315 {
316 	char *dot;
317 	int i;
318 	int speed, parity, bits;
319 
320 	/* port */
321 	port--;
322 	if (serials[port].type == 0) {
323 		printf("no such device found\n");
324 		return 0;
325 	}
326 
327 	/* speed */
328 	dot = strchr(arg, '.');
329 	if (dot != NULL)
330 		*dot++ = '\0';
331 
332 	speed = 0;
333 	if (arg == NULL || *arg == '\0') {
334 		for (i = 0; i < nitems(i_speeds); i++)
335 			if (i_speeds[i] == 9600) {
336 				speed = i;
337 				break;
338 			}
339 	} else {
340 		for (i = 0; i < nitems(c_speeds); i++)
341 			if (strcmp(arg, c_speeds[i]) == 0) {
342 				speed = i;
343 				break;
344 			}
345 		if (speed == 0) {
346 			printf("invalid speed specification, %s\n", arg);
347 			return 0;
348 		}
349 	}
350 
351 	/* data bits */
352 	arg = dot;
353 	dot = strchr(arg, '.');
354 
355 	if (arg == NULL || *arg == '\0')
356 		bits = 8;
357 	else {
358 		if (dot == arg + 1)
359 			bits = *arg - '0';
360 		else
361 			bits = 0;
362 
363 		if (bits < 5 || bits > 8) {
364 			printf("invalid bits specification, %s\n", arg);
365 			return 0;
366 		}
367 	}
368 	if (dot != NULL)
369 		*dot++ = '\0';
370 
371 	/* parity */
372 	arg = dot;
373 	if (arg == NULL || *arg == '\0')
374 		parity = 0;	/* none */
375 	else {
376 		parity = -1;
377 		for (i = 0; i <= 3; i++)
378 			if (strcmp(arg, parities[i]) == 0) {
379 				parity = i;
380 				break;
381 			}
382 		if (parity == 2)
383 			parity = -1;	/* unknown parity */
384 	}
385 	if (parity < 0) {
386 		printf("invalid parity specification, %s\n", arg);
387 		return 0;
388 	}
389 
390 	*console = serials[port].dp;
391 	console->dp_layers[0] = PZL_ENCODE(bits, parity, speed);
392 
393 	return 1;
394 }
395 
396 int
397 set_console(console)
398 	struct device_path *console;
399 {
400 	char *arg = cmd.argv[1], *dot;
401 	int port;
402 
403 	/* extract first word */
404 	dot = strchr(arg, '.');
405 	if (dot != NULL)
406 		*dot++ = '\0';
407 
408 	/*
409 	 * Graphics console
410 	 */
411 	if (strcmp(arg, "graphics") == 0)
412 		return set_graphics(console, 0, dot);
413 	if (strncmp(arg, "graphics_", 9) == 0) {
414 		port = arg[9] - '0';
415 		if (port > 0 && port < MAX_GRAPHICS)
416 			return set_graphics(console, port, dot);
417 	}
418 
419 	/*
420 	 * Serial console
421 	 */
422 	if (strcmp(arg, "rs232") == 0)
423 		return set_serial(console, 1, dot);
424 	if (strncmp(arg, "rs232_", 6) == 0) {
425 		port = arg[6] - '0';
426 		if (port > 0 && port <= MAX_SERIALS)
427 			return set_serial(console, port, dot);
428 	}
429 
430 	printf("invalid device specification, %s\n", arg);
431 	return 0;
432 }
433 
434 int
435 Xconsole()
436 {
437 	struct device_path console;
438 	int rc;
439 
440 	/* walk the device list if not already done */
441 	if (walked == 0) {
442 		bus_walk(NULL, MAXMODBUS);
443 		walked++;
444 	}
445 
446 	if (sstorsiz < CONSOLESIZE) {
447 		printf("no console information in stable storage\n");
448 		return 0;
449 	}
450 
451 	if (cmd.argc == 1) {
452 		print_console();
453 	} else {
454 		console = sstor.ss_console;
455 		if (set_console(&console)) {
456 			if (memcmp(&sstor.ss_console, &console,
457 			    sizeof console) != 0) {
458 				sstor.ss_console = console;
459 
460 				/* alea jacta est */
461 				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
462 				    CONSOLEOFFSET, &sstor.ss_console,
463 				    sizeof(sstor.ss_console));
464 				if (rc != 0) {
465 					printf("failed to save console"
466 					    " settings, error %d\n", rc);
467 					/* read sstor again for safety */
468 					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
469 					    CONSOLEOFFSET, &sstor.ss_console,
470 					    sizeof(sstor.ss_console));
471 				} else
472 					printf("you will need to power-cycle "
473 					       "your machine for the changes "
474 					       "to take effect.\n");
475 			}
476 			print_console();
477 		}
478 	}
479 
480 	return 0;
481 }
482 
483 /*
484  * K E Y B O A R D   S E T T I N G S
485  */
486 
487 void
488 print_keyboard()
489 {
490 	int type;
491 	int i;
492 
493 #ifdef DEBUG
494 	printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
495 	    sstor.ss_keyboard.dp_flags,
496 	    sstor.ss_keyboard.dp_mod,
497 	    sstor.ss_keyboard.dp_bc[0],
498 	    sstor.ss_keyboard.dp_bc[1],
499 	    sstor.ss_keyboard.dp_bc[2],
500 	    sstor.ss_keyboard.dp_bc[3],
501 	    sstor.ss_keyboard.dp_bc[4],
502 	    sstor.ss_keyboard.dp_bc[5]);
503 
504 	printf("keyboard path %x/%x/%x/%x/%x/%x\n",
505 	    sstor.ss_keyboard.dp_layers[0],
506 	    sstor.ss_keyboard.dp_layers[1],
507 	    sstor.ss_keyboard.dp_layers[2],
508 	    sstor.ss_keyboard.dp_layers[3],
509 	    sstor.ss_keyboard.dp_layers[4],
510 	    sstor.ss_keyboard.dp_layers[5]);
511 #endif
512 
513 	printf("Keyboard path: ");
514 
515 	for (type = i = 0; i < MAX_KEYBOARDS; i++)
516 		if (path_match(&keyboards[i].dp, &sstor.ss_keyboard)) {
517 			type = keyboards[i].type;
518 			break;
519 		}
520 
521 	switch (type) {
522 	case USB:
523 		printf("usb");
524 		break;
525 	case HIL:
526 		printf("hil");
527 		break;
528 	case PS2:
529 		printf("ps2");
530 		break;
531 	default:
532 		printf("unknown");
533 		break;
534 	}
535 
536 	printf("\n");
537 }
538 
539 int
540 set_keyboard(keyboard)
541 	struct device_path *keyboard;
542 {
543 	int i;
544 	char *arg = cmd.argv[1];
545 	int type;
546 
547 	if (strcmp(arg, "hil") == 0)
548 		type = HIL;
549 	else if (strcmp(arg, "ps2") == 0)
550 		type = PS2;
551 	else if (strcmp(arg, "usb") == 0)
552 		type = USB;
553 	else {
554 		/* XXX should probably handle multiple USB controllers */
555 		printf("invalid device specification, %s\n", arg);
556 		return 0;
557 	}
558 
559 	for (i = 0; i < MAX_KEYBOARDS; i++)
560 		if (keyboards[i].type == type) {
561 			*keyboard = keyboards[i].dp;
562 			return 1;
563 		}
564 
565 	printf("no such device found\n");
566 	return 0;
567 }
568 
569 int
570 Xkeyboard()
571 {
572 	struct device_path keyboard;
573 	int rc;
574 
575 	/* walk the device list if not already done */
576 	if (walked == 0) {
577 		bus_walk(NULL, MAXMODBUS);
578 		walked++;
579 	}
580 
581 	if (sstorsiz < KEYBOARDSIZE) {
582 		printf("no keyboard information in stable storage\n");
583 		return 0;
584 	}
585 
586 	if (cmd.argc == 1) {
587 		print_keyboard();
588 	} else {
589 		keyboard = sstor.ss_keyboard;
590 		if (set_keyboard(&keyboard)) {
591 			if (memcmp(&sstor.ss_keyboard, &keyboard,
592 			    sizeof keyboard) != 0) {
593 				sstor.ss_keyboard = keyboard;
594 
595 				/* alea jacta est */
596 				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
597 				    KEYBOARDOFFSET, &sstor.ss_keyboard,
598 				    sizeof(sstor.ss_keyboard));
599 				if (rc != 0) {
600 					printf("failed to save keyboard"
601 					    " settings, error %d\n", rc);
602 					/* read sstor again for safety */
603 					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
604 					    KEYBOARDOFFSET, &sstor.ss_keyboard,
605 					    sizeof(sstor.ss_keyboard));
606 				} else
607 					printf("you will need to power-cycle "
608 					       "your machine for the changes "
609 					       "to take effect.\n");
610 			}
611 			print_keyboard();
612 		}
613 	}
614 
615 	return 0;
616 }
617 
618 /*
619  * U T I L I T I E S
620  */
621 
622 /*
623  * Bus walker.
624  * This routine will walk all the modules on a given bus, registering
625  * serial ports, keyboard and graphics devices as they are found.
626  */
627 void
628 bus_walk(struct device_path *idp, int maxmod)
629 {
630 	struct device_path dp;
631 	struct pdc_memmap memmap;
632 	struct iodc_data mptr;
633 	int err, i, kluge_ps2 = 0;	/* kluge, see below */
634 
635 	for (i = 0; i < maxmod; i++) {
636 		if (idp) {
637 			dp = *idp;
638 			path_shift(&dp, i);
639 		} else {
640 			dp.dp_flags = 0;
641 			dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] =
642 			dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1;
643 			dp.dp_mod = i;
644 			bzero(&dp.dp_layers, sizeof dp.dp_layers);
645 		}
646 
647 		if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 &&
648 		    (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0)
649 			continue;
650 
651 		if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa,
652 		    IODC_DATA, &mptr, sizeof(mptr))) < 0)
653 			continue;
654 
655 #ifdef DEBUG
656 		printf("device %d/%d/%d/%d/%d/%d "
657 		    "flags %d mod %x type %x model %x\n",
658 		    dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3],
659 		    dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod,
660 		    mptr.iodc_type, mptr.iodc_sv_model);
661 #endif
662 
663 		/*
664 		 * If the device can be considered as a valid rs232,
665 		 * graphics console or keyboard, register it.
666 		 *
667 		 * Unfortunately, devices which should be considered as
668 		 * ``main'' aren't necessarily seen first.
669 		 * The rules we try to enforce here are as follows:
670 		 * - GIO PS/2 ports wins over any other PS/2 port.
671 		 * - the first GIO serial found wins over any other
672 		 *   serial port.
673 		 * The second rule is a bit tricky to achieve, since on
674 		 * some machines (for example, 715/100XC), the two serial
675 		 * ports are not seen as attached to the same busses...
676 		 */
677 		switch (mptr.iodc_type) {
678 		case HPPA_TYPE_BCPORT:
679 			bus_walk(&dp, MAXMODBUS);
680 			break;
681 		case HPPA_TYPE_BRIDGE:
682 			if (mptr.iodc_sv_model == HPPA_BRIDGE_DINO) {
683 				pci_bus_walk(&dp, &mptr, &memmap);
684 				break;
685 			}
686 			/* FALLTHROUGH */
687 		case HPPA_TYPE_BHA:
688 			/* if there was no phantomas(4) here */
689 			if (dp.dp_bc[5] == -1)
690 				path_shift(&dp, 0);
691 			bus_walk(&dp, MAXMODBUS);
692 			break;
693 		case HPPA_TYPE_ADIRECT:
694 			switch (mptr.iodc_sv_model) {
695 			case HPPA_ADIRECT_RS232:
696 				register_device(serials, MAX_SERIALS,
697 				    &dp, &mptr, SERIAL, 0);
698 				break;
699 			case HPPA_ADIRECT_HIL:
700 				register_device(keyboards, MAX_KEYBOARDS,
701 				    &dp, &mptr, HIL, 0);
702 				break;
703 			case HPPA_ADIRECT_PEACOCK:
704 			case HPPA_ADIRECT_LEONARDO:
705 				register_device(graphics, MAX_GRAPHICS,
706 				    &dp, &mptr, GRAPHICS, 0);
707 				break;
708 			}
709 			break;
710 		case HPPA_TYPE_FIO:
711 			switch (mptr.iodc_sv_model) {
712 			case HPPA_FIO_HIL:
713 				register_device(keyboards, MAX_KEYBOARDS,
714 				    &dp, &mptr, HIL, 0);
715 				break;
716 			case HPPA_FIO_RS232:	/* com@gsc */
717 				register_device(serials, MAX_SERIALS,
718 				    &dp, &mptr, SERIAL, 0);
719 				break;
720 			case HPPA_FIO_DINOPCK:
721 				register_device(keyboards, MAX_KEYBOARDS,
722 				    &dp, &mptr, PS2, 0);
723 				break;
724 			case HPPA_FIO_GPCIO:
725 				/*
726 				 * KLUGE! At this point, there is no way to
727 				 * know if this port is the keyboard port or
728 				 * the mouse port.
729 				 * Let's assume the first port found is the
730 				 * keyboard, and ignore the others.
731 				 */
732 				if (kluge_ps2 != 0)
733 					break;
734 				register_device(keyboards, MAX_KEYBOARDS,
735 				    &dp, &mptr, PS2, 1);
736 				kluge_ps2++;
737 				break;
738 			case HPPA_FIO_GRS232:	/* com@dino, com@gsc */
739 			{
740 				int j, first;
741 
742 				/*
743 				 * If a GIO serial port is already registered,
744 				 * register as extra port...
745 				 */
746 				first = 1;
747 				for (j = 0; j < MAX_SERIALS; j++)
748 					if (serials[j].type == SERIAL &&
749 					    serials[j].iodc_type ==
750 					      HPPA_TYPE_FIO &&
751 					    serials[j].iodc_model ==
752 					      HPPA_FIO_GRS232) {
753 						first = 0;
754 						break;
755 					}
756 
757 				register_device(serials, MAX_SERIALS,
758 				    &dp, &mptr, SERIAL, first);
759 			}
760 				break;
761 			case HPPA_FIO_SGC:
762 				register_device(graphics, MAX_GRAPHICS,
763 				    &dp, &mptr, GRAPHICS, 0);
764 				break;
765 			case HPPA_FIO_GSGC:
766 				register_device(graphics, MAX_GRAPHICS,
767 				    &dp, &mptr, GRAPHICS, 1);
768 				break;
769 #if 0 /* can these really be used as console? */
770 			case HPPA_FIO_GRJ16:	/* com@gsc */
771 				register_device(serials, MAX_SERIALS,
772 				    &dp, &mptr, SERIAL, 0);
773 				break;
774 #endif
775 			}
776 			break;
777 		case HPPA_TYPE_IOA:
778 			switch (mptr.iodc_sv_model) {
779 			case HPPA_IOA_UTURN:
780 				bus_walk(&dp, MAXMODBUS - 1);
781 				break;
782 			}
783 			break;
784 		}
785 	}
786 }
787 
788 /*
789  * PCI bus walker.
790  * The PDC device enumeration stops at the PCI bridge level, however
791  * in order to properly handle console path on systems with PCI graphics
792  * and USB controllers, it is necessary to dig further.
793  *
794  * Note that there are apparently PDC routines to access bridge configuration
795  * space, but I have yet to find documentation about them.
796  *
797  * We ignore multi-function devices and subordinate PCI busses here, since
798  * PDC PCI device paths stop at the PCI device number, and subordinate
799  * busses are unlikely to be configured by the PDC.
800  */
801 
802 #define	ELROY_MODEL	0x78
803 #define	DINO_PAMR	0x804
804 #define	DINO_CFG_ADDR	0x64
805 #define	DINO_CFG_DATA	0x68
806 
807 void
808 pci_bus_walk(struct device_path *idp, struct iodc_data *mptr,
809     struct pdc_memmap *memmap)
810 {
811 	struct device_path dp;
812 	int dev, fn, nfuncs;
813 	uint32_t id, bhlcr, class;
814 	uint32_t (*conf_read)(u_int, int, int, u_int);
815 
816 	if (mptr->iodc_model == ELROY_MODEL)
817 		conf_read = elroy_conf_read;
818 	else
819 		conf_read = dino_conf_read;
820 
821 	for (dev = 0; dev < 32; dev++) {
822 		id = (*conf_read)(memmap->hpa, dev, 0, PCI_ID_REG);
823 
824 		if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || PCI_VENDOR(id) == 0)
825 			continue;
826 
827 		bhlcr = (*conf_read)(memmap->hpa, dev, 0, PCI_BHLC_REG);
828 		nfuncs = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1;
829 
830 		for (fn = 0; fn < nfuncs; fn++) {
831 			dp = *idp;
832 			path_shift(&dp, dev);
833 			path_shift(&dp, fn);
834 
835 			if (fn != 0)
836 				id = (*conf_read)(memmap->hpa, dev, fn,
837 				    PCI_ID_REG);
838 			class = (*conf_read)(memmap->hpa, dev, fn,
839 			    PCI_CLASS_REG);
840 
841 			/*
842 			 * We are only interested in two kinds of devices
843 			 * here: sti graphics, and USB controllers.
844 			 */
845 			if (PCI_CLASS(class) == PCI_CLASS_SERIALBUS &&
846 			    PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB) {
847 				/*
848 				 * Note about the last parameter of the
849 				 * register_device() call below being zero:
850 				 * machines with USB keyboards have neither
851 				 * PS/2 nor HIL controllers, so it doesn't
852 				 * matter what order the USB controllers are
853 				 * in.
854 				 * However machines with PS/2 keyboards
855 				 * might have an USB PCI card plugged in,
856 				 * which better appear after the PS/2
857 				 * keyboard.
858 				 */
859 				register_device(keyboards, MAX_KEYBOARDS,
860 				    &dp, mptr, USB, 0);
861 				continue;
862 			}
863 
864 			switch (PCI_VENDOR(id)) {
865 			case PCI_VENDOR_HP:
866 				switch (PCI_PRODUCT(id)) {
867 				case PCI_PRODUCT_HP_VISUALIZE_EG:
868 				case PCI_PRODUCT_HP_VISUALIZE_FX2:
869 				case PCI_PRODUCT_HP_VISUALIZE_FX4:
870 				case PCI_PRODUCT_HP_VISUALIZE_FX6:
871 				case PCI_PRODUCT_HP_VISUALIZE_FXE:
872 					register_device(graphics, MAX_GRAPHICS,
873 					    &dp, mptr, GRAPHICS, 0);
874 					break;
875 				}
876 				break;
877 			case PCI_VENDOR_NS:
878 				if (PCI_PRODUCT(id) == PCI_PRODUCT_NS_PC87560) {
879 					/* serial_2 */
880 					path_shift(&dp, 2);
881 					register_device(serials, MAX_SERIALS,
882 					    &dp, mptr, SERIAL, 1);
883 					/* serial_1 */
884 					dp.dp_mod = 1;
885 					register_device(serials, MAX_SERIALS,
886 					    &dp, mptr, SERIAL, 1);
887 				}
888 				break;
889 			}
890 		}
891 	}
892 }
893 
894 uint32_t
895 dino_conf_read(u_int hpa, int dev, int fn, u_int reg)
896 {
897 	volatile uint32_t *dino = (volatile uint32_t *)hpa;
898 	uint32_t pamr;
899 	uint32_t addr, id;
900 
901 	addr = (dev << 11) | (fn << 8) | reg;
902 
903 	pamr = dino[DINO_PAMR / 4];
904 	dino[DINO_PAMR / 4] = 0;
905 	dino[DINO_CFG_ADDR / 4] = addr;
906 	id = dino[DINO_CFG_DATA / 4];
907 	dino[DINO_PAMR / 4] = pamr;
908 
909 	return letoh32(id);
910 }
911 
912 uint32_t
913 elroy_conf_read(u_int hpa, int dev, int fn, u_int reg)
914 {
915 	volatile struct elroy_regs *elroy = (volatile struct elroy_regs *)hpa;
916 	uint32_t arb_mask, err_cfg, control;
917 	uint32_t addr, id;
918 
919 	addr = (dev << 11) | (fn << 8) | reg;
920 
921 	arb_mask = *(volatile uint32_t *)&elroy->arb_mask;
922 	err_cfg = *(volatile uint32_t *)&elroy->err_cfg;
923 	control = *(volatile uint32_t *)&elroy->control;
924 
925 	if (arb_mask == 0)
926 		*(volatile uint32_t *)&elroy->arb_mask =
927 		    htole32(ELROY_ARB_ENABLE);
928 	*(volatile uint32_t *)&elroy->err_cfg = err_cfg |
929 	    htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM);
930 	*(volatile uint32_t *)&elroy->control =
931 	    (control | htole32(ELROY_CONTROL_CE)) & ~htole32(ELROY_CONTROL_HF);
932 
933 	*(volatile uint32_t *)&elroy->pci_conf_addr = htole32(addr);
934 	addr = *(volatile uint32_t *)&elroy->pci_conf_addr;
935 	id = *(volatile uint32_t *)&elroy->pci_conf_data;
936 
937 	*(volatile uint32_t *)&elroy->control =
938 	    control | htole32(ELROY_CONTROL_CE | ELROY_CONTROL_CL);
939 	*(volatile uint32_t *)&elroy->control = control;
940 	*(volatile uint32_t *)&elroy->err_cfg = err_cfg;
941 	if (arb_mask == 0)
942 		*(volatile uint32_t *)&elroy->arb_mask = arb_mask;
943 
944 	return letoh32(id);
945 }
946 
947 /*
948  * Relaxed device comparison
949  */
950 int
951 path_match(struct device_path *dev1, struct device_path *dev2)
952 {
953 	return dev1->dp_mod == dev2->dp_mod &&
954 	    dev1->dp_bc[0] == dev2->dp_bc[0] &&
955 	    dev1->dp_bc[1] == dev2->dp_bc[1] &&
956 	    dev1->dp_bc[2] == dev2->dp_bc[2] &&
957 	    dev1->dp_bc[3] == dev2->dp_bc[3] &&
958 	    dev1->dp_bc[4] == dev2->dp_bc[4] &&
959 	    dev1->dp_bc[5] == dev2->dp_bc[5];
960 }
961 
962 /*
963  * Shift a device path, inserting a new value as dp_mod.
964  */
965 void
966 path_shift(struct device_path *dp, int nmod)
967 {
968 	dp->dp_bc[0] = dp->dp_bc[1];
969 	dp->dp_bc[1] = dp->dp_bc[2];
970 	dp->dp_bc[2] = dp->dp_bc[3];
971 	dp->dp_bc[3] = dp->dp_bc[4];
972 	dp->dp_bc[4] = dp->dp_bc[5];
973 	dp->dp_bc[5] = dp->dp_mod;
974 	dp->dp_mod = nmod;
975 }
976 
977 void
978 register_device(devlist, cnt, dp, mptr, type, first)
979 	struct consoledev *devlist;
980 	int cnt;
981 	struct device_path *dp;
982 	struct iodc_data *mptr;
983 	int type;
984 	int first;
985 {
986 	int i;
987 	struct consoledev *dev;
988 
989 	for (i = 0, dev = devlist; i < cnt; i++, dev++)
990 		if (dev->type == 0)
991 			break;
992 
993 	if (i == cnt) {
994 #ifdef DEBUG
995 		printf("can't register device, need more room!\n");
996 #endif
997 		return;
998 	}
999 
1000 	/*
1001 	 * If this is supposedly the main device, insert on top
1002 	 */
1003 	if (first != 0) {
1004 		memcpy(devlist + 1, devlist,
1005 		    (cnt - 1) * sizeof(struct consoledev));
1006 		dev = devlist;
1007 	}
1008 
1009 	dev->dp = *dp;
1010 	dev->type = type;
1011 	dev->iodc_type = mptr->iodc_type;
1012 	dev->iodc_model = mptr->iodc_sv_model;
1013 
1014 #ifdef DEBUG
1015 	printf("(registered as type %d)\n", type);
1016 #endif
1017 }
1018