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
print_console()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
set_graphics(console,port,arg)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
set_serial(console,port,arg)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
set_console(console)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
Xconsole()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
print_keyboard()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
set_keyboard(keyboard)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
Xkeyboard()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
bus_walk(struct device_path * idp,int maxmod)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
pci_bus_walk(struct device_path * idp,struct iodc_data * mptr,struct pdc_memmap * memmap)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
dino_conf_read(u_int hpa,int dev,int fn,u_int reg)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
elroy_conf_read(u_int hpa,int dev,int fn,u_int reg)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
path_match(struct device_path * dev1,struct device_path * dev2)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
path_shift(struct device_path * dp,int nmod)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
register_device(devlist,cnt,dp,mptr,type,first)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