Annotation of src/sys/arch/powerpc/oea/ofw_consinit.c, Revision 1.6.14.2
1.6.14.1 mjf 1: /* $NetBSD$ */
1.2 garbled 2:
3: /*-
4: * Copyright (c) 2007 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Tim Rightnour
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: #include <sys/cdefs.h>
1.6.14.1 mjf 33: __KERNEL_RCSID(0, "$NetBSD$");
1.2 garbled 34:
35: #include <sys/param.h>
36: #include <sys/buf.h>
37: #include <sys/tty.h>
38:
39: #include <machine/autoconf.h>
40: #include <machine/trap.h>
41: #include <machine/bus.h>
42:
43: #include <powerpc/ofw_cons.h>
44:
45: #include <dev/cons.h>
46: #include <dev/ofw/openfirm.h>
47:
48: #include <dev/wscons/wsksymvar.h>
49: #include <dev/wscons/wscons_callbacks.h>
50:
51: #include <machine/stdarg.h>
52:
53: #include "akbd.h"
54: #include "adbkbd.h"
1.5 macallan 55: #include "wsdisplay.h"
1.2 garbled 56: #include "ofb.h"
57: #include "isa.h"
58:
59: #include "zsc.h"
60: #if NZSC > 0
61: #include <machine/z8530var.h>
62: #endif
63:
64: #include "adb.h"
65: #if (NADB > 0)
66: #include <macppc/dev/adbvar.h>
67: #endif
68:
69: #include "ukbd.h"
70: #if (NUKBD > 0)
71: #include <dev/usb/ukbdvar.h>
72: struct usb_kbd_ihandles {
73: struct usb_kbd_ihandles *next;
74: int ihandle;
75: };
76: #endif
77:
78: #include "zstty.h"
79: #if (NZSTTY > 0)
80: #include <dev/ic/z8530reg.h>
81: extern struct consdev consdev_zs;
82: #endif
83:
84: #include "pckbc.h"
85: #if (NPCKBC > 0)
86: #include <dev/isa/isareg.h>
87: #include <dev/ic/i8042reg.h>
88: #include <dev/ic/pckbcvar.h>
89: #endif
90:
91: extern int console_node, console_instance;
92:
1.3 garbled 93: int chosen, stdin, stdout;
1.2 garbled 94: int ofkbd_ihandle;
95:
96: static void cninit_kd(void);
97: static void ofwoea_bootstrap_console(void);
1.3 garbled 98: static int ofwbootcons_cngetc(dev_t);
99: static void ofwbootcons_cnputc(dev_t, int);
1.2 garbled 100:
101: /*#define OFDEBUG*/
102:
1.3 garbled 103: struct consdev consdev_ofwbootcons = {
104: NULL, NULL,
105: ofwbootcons_cngetc,
106: ofwbootcons_cnputc,
107: nullcnpollc,
108: NULL, NULL, NULL, NODEV, CN_INTERNAL,
109: };
110:
1.2 garbled 111: #ifdef OFDEBUG
112: void ofprint(const char *, ...);
113:
114: void ofprint(const char *blah, ...)
115: {
116: va_list va;
117: char buf[256];
118: int len;
119:
120: va_start(va, blah);
121: len = vsnprintf(buf, sizeof(buf), blah, va);
122: OF_write(console_instance, buf, len);
123: }
124:
125: #define OFPRINTF ofprint
126: #else
127: #define OFPRINTF while(0) printf
128: #endif
129:
130: void
131: cninit(void)
132: {
1.6 garbled 133: char name[32];
1.2 garbled 134:
135: ofwoea_bootstrap_console();
136:
137: OFPRINTF("console node: %08x\n", console_node);
138:
139: if (console_node == -1)
140: goto nocons;
141:
1.6 garbled 142: memset(name, 0, sizeof(name));
143: if (OF_getprop(console_node, "device_type", name, sizeof(name)) == -1)
1.2 garbled 144: goto nocons;
145:
1.6 garbled 146: OFPRINTF("console type: %s\n", name);
1.2 garbled 147:
1.6 garbled 148: if (strcmp(name, "serial") == 0) {
1.2 garbled 149: struct consdev *cp;
150:
1.3 garbled 151: #ifdef PMAC_G5
1.2 garbled 152: /* The MMU hasn't been initialized yet, use failsafe for now */
153: cp = &failsafe_cons;
154: cn_tab = cp;
155: (*cp->cn_probe)(cp);
156: (*cp->cn_init)(cp);
157: aprint_verbose("Early G5 console initialized\n");
1.3 garbled 158: return;
159: #endif /* PMAC_G5 */
160:
161: #if (NZSTTY > 0) && !defined(MAMBO)
1.2 garbled 162: OF_getprop(console_node, "name", name, sizeof(name));
163: if (strcmp(name, "ch-a") == 0 || strcmp(name, "ch-b") == 0) {
164: cp = &consdev_zs;
165: (*cp->cn_probe)(cp);
166: (*cp->cn_init)(cp);
167: cn_tab = cp;
168: }
169: return;
170: #endif /* NZTTY */
171:
1.6 garbled 172: /* fallback to OFW boot console */
173: cp = &consdev_ofwbootcons;
174: cn_tab = cp;
1.2 garbled 175: return;
176: }
1.6 garbled 177: else
178: cninit_kd();
1.2 garbled 179: nocons:
180: return;
181: }
182:
183:
184: static void
185: cninit_kd(void)
186: {
1.3 garbled 187: int kstdin, node;
1.2 garbled 188: char name[16];
189: #if (NAKBD > 0) || (NADBKBD > 0)
190: int akbd;
191: #endif
192: #if NUKBD > 0
193: struct usb_kbd_ihandles *ukbds;
194: int ukbd;
195: #endif
196:
197: /*
198: * Attach the console output now (so we can see debugging messages,
199: * if any).
200: */
1.5 macallan 201: #if NWSDISPLAY > 0
1.6 garbled 202: rascons_cnattach();
1.4 garbled 203: #endif
1.2 garbled 204:
205: /*
206: * We must determine which keyboard type we have.
207: */
1.3 garbled 208: if (OF_getprop(chosen, "stdin", &kstdin, sizeof(kstdin))
209: != sizeof(kstdin)) {
1.2 garbled 210: printf("WARNING: no `stdin' property in /chosen\n");
211: return;
212: }
213:
1.3 garbled 214: node = OF_instance_to_package(kstdin);
1.2 garbled 215: memset(name, 0, sizeof(name));
216: OF_getprop(node, "name", name, sizeof(name));
217: if (strcmp(name, "keyboard") != 0) {
218: printf("WARNING: stdin is not a keyboard: %s\n", name);
219: return;
220: }
221:
222: #if NAKBD > 0
223: memset(name, 0, sizeof(name));
224: OF_getprop(OF_parent(node), "name", name, sizeof(name));
225: if (strcmp(name, "adb") == 0) {
226: printf("console keyboard type: ADB\n");
227: akbd_cnattach();
228: goto kbd_found;
229: }
230: #endif
231: #if NADBKBD > 0
232: memset(name, 0, sizeof(name));
233: OF_getprop(OF_parent(node), "name", name, sizeof(name));
234: if (strcmp(name, "adb") == 0) {
235: printf("console keyboard type: ADB\n");
236: adbkbd_cnattach();
237: goto kbd_found;
238: }
239: #endif
240: #if NPCKBC > 0
241: memset(name, 0, sizeof(name));
242: OF_getprop(OF_parent(node), "name", name, sizeof(name));
243: if (strcmp(name, "keyboard") == 0) {
244: printf("console keyboard type: PC Keyboard\n");
245: pckbc_cnattach(&genppc_isa_io_space_tag, IO_KBD, KBCMDP,
246: PCKBC_KBD_SLOT);
247: goto kbd_found;
248: }
249: #endif
250:
251: /*
252: * It is not obviously an ADB/PC keyboard. Could be USB,
253: * or ADB on some firmware versions (e.g.: iBook G4)
254: * This is not enough, we have a few more problems:
255: *
256: * (1) The stupid Macintosh firmware uses a
257: * `psuedo-hid' (no typo) or `pseudo-hid',
258: * which apparently merges all keyboards
259: * input into a single input stream.
260: * Because of this, we can't actually
261: * determine which controller or keyboard
262: * is really the console keyboard!
263: *
264: * (2) Even if we could, the keyboard can be USB,
265: * and this requires a lot of the kernel to
266: * be running in order for it to work.
267: *
268: * (3) If the keyboard is behind isa, we don't have enough
269: * kernel setup to use it yet, so punt to the ofroutines.
270: *
271: * So, what we do is this:
272: *
273: * (1) First check for OpenFirmware implementation
274: * that will not let us distinguish between
275: * USB and ADB. In that situation, try attaching
276: * anything as we can, and hope things get better
277: * at autoconfiguration time.
278: *
279: * (2) Assume the keyboard is USB.
280: * Tell the ukbd driver that it is the console.
281: * At autoconfiguration time, it will attach the
282: * first USB keyboard instance as the console
283: * keyboard.
284: *
285: * (3) Until then, so that we have _something_, we
286: * use the OpenFirmware I/O facilities to read
287: * the keyboard.
288: */
289:
290: /*
291: * stdin is /pseudo-hid/keyboard. There is no
292: * `adb-kbd-ihandle or `usb-kbd-ihandles methods
293: * available. Try attaching as ADB.
1.6.14.2! mjf 294: * But only if ADB support is actually present.
1.2 garbled 295: *
296: * XXX This must be called before pmap_bootstrap().
297: */
298: if (strcmp(name, "pseudo-hid") == 0) {
1.6.14.2! mjf 299: int adb_node;
! 300:
! 301: adb_node = OF_finddevice("/pci/mac-io/via-pmu/adb");
! 302: if (adb_node > 0) {
! 303: printf("ADB support found\n");
1.2 garbled 304: #if NAKBD > 0
1.6.14.2! mjf 305: akbd_cnattach();
1.2 garbled 306: #endif
307: #if NADBKBD > 0
1.6.14.2! mjf 308: adbkbd_cnattach();
! 309: #endif
! 310: } else {
! 311: /* must be USB */
! 312: printf("No ADB support present, assuming USB "
! 313: "keyboard\n");
! 314: #if NUKBD > 0
! 315: ukbd_cnattach();
1.2 garbled 316: #endif
1.6.14.2! mjf 317: }
1.2 garbled 318: goto kbd_found;
319: }
320:
321: /*
322: * stdin is /psuedo-hid/keyboard. Test `adb-kbd-ihandle and
323: * `usb-kbd-ihandles to figure out the real keyboard(s).
324: *
325: * XXX This must be called before pmap_bootstrap().
326: */
327:
328: #if NUKBD > 0
329: if (OF_call_method("`usb-kbd-ihandles", stdin, 0, 1, &ukbds) >= 0 &&
330: ukbds != NULL && ukbds->ihandle != 0 &&
331: OF_instance_to_package(ukbds->ihandle) != -1) {
332: printf("usb-kbd-ihandles matches\n");
333: printf("console keyboard type: USB\n");
334: ukbd_cnattach();
335: goto kbd_found;
336: }
337: /* Try old method name. */
1.3 garbled 338: if (OF_call_method("`usb-kbd-ihandle", kstdin, 0, 1, &ukbd) >= 0 &&
1.2 garbled 339: ukbd != 0 &&
340: OF_instance_to_package(ukbd) != -1) {
341: printf("usb-kbd-ihandle matches\n");
342: printf("console keyboard type: USB\n");
1.3 garbled 343: kstdin = ukbd;
1.2 garbled 344: ukbd_cnattach();
345: goto kbd_found;
346: }
347: #endif
348:
349: #if (NAKBD > 0) || (NADBKBD > 0)
1.3 garbled 350: if (OF_call_method("`adb-kbd-ihandle", kstdin, 0, 1, &akbd) >= 0 &&
1.2 garbled 351: akbd != 0 &&
352: OF_instance_to_package(akbd) != -1) {
353: printf("adb-kbd-ihandle matches\n");
354: printf("console keyboard type: ADB\n");
1.3 garbled 355: kstdin = akbd;
1.2 garbled 356: #if NAKBD > 0
357: akbd_cnattach();
358: #endif
359: #if NADBKBD > 0
360: adbkbd_cnattach();
361: #endif
362: goto kbd_found;
363: }
364: #endif
365:
366: #if NUKBD > 0
367: /*
368: * XXX Old firmware does not have `usb-kbd-ihandles method. Assume
369: * XXX USB keyboard anyway.
370: */
371: printf("defaulting to USB...");
372: printf("console keyboard type: USB\n");
373: ukbd_cnattach();
374: goto kbd_found;
375: #endif
376:
377: /*
378: * No keyboard is found. Just return.
379: */
380: printf("no console keyboard\n");
381: return;
382:
383: kbd_found:;
1.6.14.2! mjf 384: #if NAKBD + NUKBD + NADBKBD + NPCKBC > 0
1.2 garbled 385: /*
386: * XXX This is a little gross, but we don't get to call
387: * XXX wskbd_cnattach() twice.
388: */
1.3 garbled 389: ofkbd_ihandle = kstdin;
1.2 garbled 390: #if NWSDISPLAY > 0
391: wsdisplay_set_cons_kbd(ofkbd_cngetc, NULL, NULL);
392: #endif
393: #endif
394: }
395:
396: /*
397: * Bootstrap console keyboard routines, using OpenFirmware I/O.
398: */
399: int
400: ofkbd_cngetc(dev_t dev)
401: {
402: u_char c = '\0';
403: int len;
404:
405: do {
406: len = OF_read(ofkbd_ihandle, &c, 1);
407: } while (len != 1);
408:
409: return c;
410: }
411:
1.3 garbled 412: /*
413: * Bootstrap console support functions
414: */
415:
416: static int
417: ofwbootcons_cngetc(dev_t dev)
418: {
419: unsigned char ch = '\0';
420: int l;
421:
422: while ((l = OF_read(stdin, &ch, 1)) != 1)
423: if (l != -2 && l != 0)
424: return -1;
425: return ch;
426: }
427:
428: static void
429: ofwbootcons_cnputc(dev_t dev, int c)
430: {
431: char ch = c;
432:
433: OF_write(stdout, &ch, 1);
434: }
435:
1.2 garbled 436: void
437: ofwoea_consinit(void)
438: {
439: static int initted = 0;
440:
441: if (initted)
442: return;
443:
444: initted = 1;
445: cninit();
446: }
447:
448: static void
449: ofwoea_bootstrap_console(void)
450: {
1.3 garbled 451: int node;
1.2 garbled 452:
453: chosen = OF_finddevice("/chosen");
454: if (chosen == -1)
455: goto nocons;
456:
457: if (OF_getprop(chosen, "stdout", &stdout,
458: sizeof(stdout)) != sizeof(stdout))
459: goto nocons;
1.3 garbled 460: if (OF_getprop(chosen, "stdin", &stdin,
461: sizeof(stdin)) != sizeof(stdin))
462: goto nocons;
1.2 garbled 463: node = OF_instance_to_package(stdout);
464: console_node = node;
465: console_instance = stdout;
466:
467: return;
468: nocons:
469: panic("No /chosen could be found!\n");
470: console_node = -1;
471: return;
472: }
CVSweb <webmaster@jp.NetBSD.org>