1 /* $NetBSD: pcio.c,v 1.26 2009/06/29 09:23:16 mbalmer Exp $ */
4 * Copyright (c) 1996, 1997
5 * Matthias Drochner. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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 BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * needs lowlevel routines from conio.S and comio.S
34 #include <lib/libsa/stand.h>
35 #include <lib/libkern/libkern.h>
36 #include <sys/bootblock.h>
41 extern void conputc(int);
42 extern int congetc(void);
43 extern int conisshift(void);
44 extern int coniskey(void);
45 extern struct x86_boot_params boot_params
;
47 struct btinfo_console btinfo_console
;
53 #include "comio_direct.h"
55 #define cominit_x() btinfo_console.speed = \
56 cominit_d(btinfo_console.addr, btinfo_console.speed)
57 #define computc_x(ch) computc_d(ch, btinfo_console.addr)
58 #define comgetc_x() comgetc_d(btinfo_console.addr)
59 #define comstatus_x() comstatus_d(btinfo_console.addr)
62 #define cominit_x() cominit(iodev - CONSDEV_COM0)
63 #define computc_x(ch) computc(ch, iodev - CONSDEV_COM0)
64 #define comgetc_x() comgetc(iodev - CONSDEV_COM0)
65 #define comstatus_x() comstatus(iodev - CONSDEV_COM0)
67 #endif /* DIRECT_SERIAL */
69 static int getcomaddr(int);
70 #endif /* SUPPORT_SERIAL */
77 int prev
= biosgetsystime();
78 int tgt
= prev
+ (20 * us
) / 1000000;
81 while ((new = biosgetsystime()) < tgt
) {
82 if (new < prev
) /* XXX timer wrapped */
97 /* read in BIOS data area */
98 pvbcopy((void *)(0x400 + 2 * idx
), &addr
, 2);
104 clear_pc_screen(void)
106 #ifdef SUPPORT_SERIAL
107 /* Clear the screen if we are on a glass tty. */
108 if (iodev
== CONSDEV_PC
)
116 #ifdef SUPPORT_SERIAL
119 #if defined(DIRECT_SERIAL) && defined(CONSPEED)
120 btinfo_console
.speed
= CONSPEED
;
122 btinfo_console
.speed
= 9600;
127 for (i
= 0; i
< 3; i
++) {
128 iodev
= CONSDEV_COM0
+ i
;
129 btinfo_console
.addr
= getcomaddr(i
);
130 if (!btinfo_console
.addr
)
132 conputc('0' + i
); /* to tell user what happens */
136 * 1. successful output
137 * 2. optionally, keypress within 7s
139 if ( computc_x(':') &&
142 #ifdef COMCONS_KEYPRESS
147 #else /* ! DIRECT_SERIAL */
149 * serial console must have hardware handshake!
151 * 1. character output without error
152 * 2. status bits for modem ready set
153 * (status seems only useful after character output)
154 * 3. optionally, keypress within 7s
156 if (!(computc_x('@') & 0x80)
157 && (comstatus_x() & 0x00b0)
158 #ifdef COMCONS_KEYPRESS
163 #endif /* DIRECT_SERIAL */
173 btinfo_console
.addr
= getcomaddr(iodev
- CONSDEV_COM0
);
174 if (!btinfo_console
.addr
)
178 case CONSDEV_COM0KBD
:
179 case CONSDEV_COM1KBD
:
180 case CONSDEV_COM2KBD
:
181 case CONSDEV_COM3KBD
:
182 iodev
= dev
- CONSDEV_COM0KBD
+ CONSDEV_COM0
;
183 i
= iodev
- CONSDEV_COM0
;
184 btinfo_console
.addr
= getcomaddr(i
);
185 if (!btinfo_console
.addr
)
187 conputc('0' + i
); /* to tell user what happens */
191 * 1. successful output
192 * 2. optionally, keypress within 7s
194 if ( computc_x(':') &&
197 #ifdef COMCONS_KEYPRESS
202 #else /* ! DIRECT_SERIAL */
204 * serial console must have hardware handshake!
206 * 1. character output without error
207 * 2. status bits for modem ready set
208 * (status seems only useful after character output)
209 * 3. optionally, keypress within 7s
211 if (!(computc_x('@') & 0x80)
212 && (comstatus_x() & 0x00b0)
213 #ifdef COMCONS_KEYPRESS
218 #endif /* DIRECT_SERIAL */
226 strncpy(btinfo_console
.devname
, iodev
== CONSDEV_PC
? "pc" : "com", 16);
228 #else /* !SUPPORT_SERIAL */
229 btinfo_console
.devname
[0] = 'p';
230 btinfo_console
.devname
[1] = 'c';
231 btinfo_console
.devname
[2] = 0;
232 #endif /* SUPPORT_SERIAL */
235 static inline void internal_putchar(int);
238 internal_putchar(int c
)
240 #ifdef SUPPORT_SERIAL
245 #ifdef SUPPORT_SERIAL
261 internal_putchar('\r');
269 #ifdef SUPPORT_SERIAL
271 default: /* to make gcc -Wall happy... */
275 #ifdef CONSOLE_KEYMAP
277 char *cp
= strchr(CONSOLE_KEYMAP
, c
);
278 if (cp
!= 0 && cp
[1] != 0)
283 #ifdef SUPPORT_SERIAL
293 } while ((c
>> 8) == 0xe0); /* catch timeout */
296 printf("com input %x, status %x\n",
301 #endif /* DIRECT_SERIAL */
304 #endif /* SUPPORT_SERIAL */
310 #ifdef SUPPORT_SERIAL
312 default: /* to make gcc -Wall happy... */
315 return (intr
&& conisshift()) || coniskey();
316 #ifdef SUPPORT_SERIAL
322 return !!comstatus_x();
324 return !!(comstatus_x() & 0x0100);
327 #endif /* SUPPORT_SERIAL */
331 awaitkey(int timeout
, int tell
)
336 i
= timeout
* POLL_FREQ
;
339 if (tell
&& (i
% POLL_FREQ
) == 0) {
343 len
= snprintf(numbuf
, sizeof(numbuf
), "%d seconds. ",
345 if (len
> 0 && len
< sizeof(numbuf
)) {
348 printf("%s", numbuf
);
351 printf("%s", numbuf
);
355 /* flush input buffer */
363 wait(1000000 / POLL_FREQ
);
370 printf("0 seconds. \n");