[BACK]Return to ofw_consinit.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / powerpc / oea

Annotation of src/sys/arch/powerpc/oea/ofw_consinit.c, Revision 1.2

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

CVSweb <webmaster@jp.NetBSD.org>