Home | History | Annotate | Line # | Download | only in zboot
unixcons.c revision 1.1.28.1
      1       1.1  nonaka /*	$NetBSD: unixcons.c,v 1.1.28.1 2014/08/20 00:03:30 tls Exp $	*/
      2       1.1  nonaka 
      3       1.1  nonaka /*
      4       1.1  nonaka  * Copyright (c) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org>
      5       1.1  nonaka  * All rights reserved.
      6       1.1  nonaka  *
      7       1.1  nonaka  * Redistribution and use in source and binary forms, with or without
      8       1.1  nonaka  * modification, are permitted provided that the following conditions
      9       1.1  nonaka  * are met:
     10       1.1  nonaka  * 1. Redistributions of source code must retain the above copyright
     11       1.1  nonaka  *    notice, this list of conditions and the following disclaimer.
     12       1.1  nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  nonaka  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  nonaka  *    documentation and/or other materials provided with the distribution.
     15       1.1  nonaka  *
     16       1.1  nonaka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17       1.1  nonaka  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18       1.1  nonaka  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19       1.1  nonaka  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20       1.1  nonaka  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21       1.1  nonaka  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22       1.1  nonaka  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23       1.1  nonaka  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24       1.1  nonaka  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25       1.1  nonaka  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26       1.1  nonaka  */
     27       1.1  nonaka 
     28       1.1  nonaka #include "boot.h"
     29       1.1  nonaka #include "bootinfo.h"
     30       1.1  nonaka #include "unixdev.h"
     31       1.1  nonaka 
     32       1.1  nonaka #include "compat_linux.h"
     33       1.1  nonaka #include "termios.h"
     34       1.1  nonaka 
     35       1.1  nonaka struct btinfo_console bi_cons;
     36       1.1  nonaka 
     37       1.1  nonaka static int iodev = CONSDEV_GLASS;
     38       1.1  nonaka static int infd = 0;
     39       1.1  nonaka static int outfd = 1;
     40       1.1  nonaka 
     41       1.1  nonaka static const char *comdevname[] = {
     42       1.1  nonaka 	"/dev/ttyS0",
     43       1.1  nonaka };
     44       1.1  nonaka 
     45       1.1  nonaka static void common_putc(int fd, int c);
     46       1.1  nonaka static int common_getc(int fd, int timo);
     47       1.1  nonaka 
     48       1.1  nonaka void
     49       1.1  nonaka consinit(int dev, int speed)
     50       1.1  nonaka {
     51       1.1  nonaka 	struct linux_termios termios;
     52       1.1  nonaka 	int fd;
     53       1.1  nonaka 
     54       1.1  nonaka 	switch (dev) {
     55       1.1  nonaka 	case CONSDEV_COM0:
     56       1.1  nonaka 		iodev = dev;
     57       1.1  nonaka 		break;
     58       1.1  nonaka 
     59       1.1  nonaka 	case CONSDEV_GLASS:
     60       1.1  nonaka 	default:
     61       1.1  nonaka  glass_console:
     62       1.1  nonaka 		iodev = CONSDEV_GLASS;
     63       1.1  nonaka 		break;
     64       1.1  nonaka 	}
     65       1.1  nonaka 
     66       1.1  nonaka 	if (infd >= 0 && infd == outfd) {
     67       1.1  nonaka 		uclose(infd);
     68       1.1  nonaka 		infd = 0;
     69       1.1  nonaka 		outfd = 1;
     70       1.1  nonaka 	}
     71       1.1  nonaka 
     72       1.1  nonaka 	if (iodev == CONSDEV_GLASS) {
     73       1.1  nonaka 		infd = 0;
     74       1.1  nonaka 		outfd = 1;
     75       1.1  nonaka 
     76       1.1  nonaka 		strlcpy(bi_cons.devname, "glass", sizeof(bi_cons.devname));
     77       1.1  nonaka 		bi_cons.addr = -1;
     78       1.1  nonaka 		bi_cons.speed = -1;
     79       1.1  nonaka 	} else {
     80       1.1  nonaka 		fd = uopen(comdevname[iodev - CONSDEV_COM0], LINUX_O_RDWR);
     81       1.1  nonaka 		if (fd < 0)
     82       1.1  nonaka 			goto glass_console;
     83       1.1  nonaka 		infd = outfd = fd;
     84       1.1  nonaka 
     85       1.1  nonaka 		/* set speed */
     86       1.1  nonaka 		linux_tcgetattr(fd, &termios);
     87       1.1  nonaka 		if (linux_cfsetspeed(&termios, speed) < 0) {
     88       1.1  nonaka 			speed = 9600;
     89       1.1  nonaka 			if (linux_cfsetspeed(&termios, speed) < 0)
     90       1.1  nonaka 				goto glass_console;
     91       1.1  nonaka 		}
     92       1.1  nonaka 		if (linux_tcsetattr(fd, LINUX_TCSETS, &termios) < 0)
     93       1.1  nonaka 			goto glass_console;
     94       1.1  nonaka 
     95       1.1  nonaka 		snprintf(bi_cons.devname, sizeof(bi_cons.devname), "com%d",
     96       1.1  nonaka 		    iodev - CONSDEV_COM0);
     97       1.1  nonaka 		bi_cons.addr = -1;
     98       1.1  nonaka 		bi_cons.speed = speed;
     99       1.1  nonaka 	}
    100       1.1  nonaka 	BI_ADD(&bi_cons, BTINFO_CONSDEV, sizeof(bi_cons));
    101       1.1  nonaka }
    102       1.1  nonaka 
    103       1.1  nonaka void
    104       1.1  nonaka putchar(int c)
    105       1.1  nonaka {
    106       1.1  nonaka 
    107       1.1  nonaka 	common_putc(outfd, c);
    108       1.1  nonaka }
    109       1.1  nonaka 
    110       1.1  nonaka int
    111       1.1  nonaka getchar(void)
    112       1.1  nonaka {
    113       1.1  nonaka 
    114       1.1  nonaka 	return common_getc(infd, 1);
    115       1.1  nonaka }
    116       1.1  nonaka 
    117       1.1  nonaka static void
    118       1.1  nonaka common_putc(int fd, int c)
    119       1.1  nonaka {
    120       1.1  nonaka 
    121       1.1  nonaka 	(void)uwrite(fd, &c, 1);
    122       1.1  nonaka }
    123       1.1  nonaka 
    124       1.1  nonaka static int
    125       1.1  nonaka common_getc(int fd, int timo)
    126       1.1  nonaka {
    127       1.1  nonaka 	struct linux_timeval tv;
    128       1.1  nonaka 	fd_set fdset;
    129       1.1  nonaka 	int nfds, n;
    130       1.1  nonaka 	char c;
    131       1.1  nonaka 
    132       1.1  nonaka 	for (; timo < 0 || timo > 0; --timo) {
    133       1.1  nonaka 		tv.tv_sec = 1;
    134       1.1  nonaka 		tv.tv_usec = 0;
    135       1.1  nonaka 		FD_ZERO(&fdset);
    136       1.1  nonaka 
    137       1.1  nonaka 		nfds = 1;
    138       1.1  nonaka 		FD_SET(fd, &fdset);
    139       1.1  nonaka 
    140       1.1  nonaka 		n = uselect(nfds, &fdset, NULL, NULL, &tv);
    141       1.1  nonaka 		if (n > 0)
    142       1.1  nonaka 			break;
    143       1.1  nonaka 	}
    144       1.1  nonaka 
    145       1.1  nonaka 	if (timo > 0) {
    146       1.1  nonaka 		for (fd = 0; fd < nfds; fd++) {
    147       1.1  nonaka 			if (FD_ISSET(fd, &fdset)) {
    148       1.1  nonaka 				return (uread(fd, &c, 1) < 1 ? -1 : c);
    149       1.1  nonaka 			}
    150       1.1  nonaka 		}
    151       1.1  nonaka 	}
    152       1.1  nonaka 	return -1;
    153       1.1  nonaka }
    154       1.1  nonaka 
    155       1.1  nonaka int
    156       1.1  nonaka awaitkey(int timeout, int tell)
    157       1.1  nonaka {
    158       1.1  nonaka 	struct linux_termios orig_termios, raw_termios;
    159       1.1  nonaka 	int c = 0;
    160       1.1  nonaka 	int i;
    161       1.1  nonaka 
    162       1.1  nonaka 	/* set raw mode */
    163       1.1  nonaka 	linux_tcgetattr(infd, &orig_termios);
    164       1.1  nonaka 	raw_termios = orig_termios;
    165       1.1  nonaka 	linux_cfmakeraw(&raw_termios);
    166       1.1  nonaka 	linux_tcsetattr(infd, LINUX_TCSETS, &raw_termios);
    167       1.1  nonaka 
    168       1.1  nonaka 	for (i = timeout; i > 0; i--) {
    169       1.1  nonaka 		if (tell) {
    170       1.1  nonaka 			char numbuf[20];
    171       1.1  nonaka 			int len, j;
    172       1.1  nonaka 
    173  1.1.28.1     tls 			len = snprintf(numbuf, sizeof(numbuf), "%d ", i);
    174       1.1  nonaka 			for (j = 0; j < len; j++)
    175       1.1  nonaka 				numbuf[len + j] = '\b';
    176       1.1  nonaka 			numbuf[len + j] = '\0';
    177  1.1.28.1     tls 			printf("%s", numbuf);
    178       1.1  nonaka 		}
    179       1.1  nonaka 		c = common_getc(infd, 1);
    180       1.1  nonaka 		if (c == 0)
    181       1.1  nonaka 			c = -1;
    182       1.1  nonaka 		if (c >= 0)
    183       1.1  nonaka 			break;
    184       1.1  nonaka 	}
    185       1.1  nonaka 	if (i == 0)
    186       1.1  nonaka 		c = '\0';
    187       1.1  nonaka 
    188       1.1  nonaka 	/* set original mode */
    189       1.1  nonaka 	linux_tcsetattr(infd, LINUX_TCSETS, &orig_termios);
    190       1.1  nonaka 
    191       1.1  nonaka 	if (tell)
    192       1.1  nonaka 		printf("0 \n");
    193       1.1  nonaka 
    194       1.1  nonaka 	return c;
    195       1.1  nonaka }
    196       1.1  nonaka 
    197       1.1  nonaka void dummycall2(void);
    198       1.1  nonaka void
    199       1.1  nonaka dummycall2(void)
    200       1.1  nonaka {
    201       1.1  nonaka 
    202       1.1  nonaka 	(void)linux_termio_to_bsd_termios;
    203       1.1  nonaka 	(void)bsd_termios_to_linux_termio;
    204       1.1  nonaka 	(void)linux_termios_to_bsd_termios;
    205       1.1  nonaka 	(void)bsd_termios_to_linux_termios;
    206       1.1  nonaka }
    207