2 * Mach Operating System
3 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
26 * from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
27 * $FreeBSD: src/sys/boot/pc98/boot2/io.c,v 1.2.2.1 2001/10/07 13:22:38 nyan Exp $
28 * $DragonFly: src/sys/boot/pc98/boot2/Attic/io.c,v 1.2 2003/06/17 04:28:18 dillon Exp $
32 #include <machine/cpufunc.h>
33 #include <sys/reboot.h>
35 #include <pc98/pc98/pc98.h>
39 static int getchar(int in_buf);
42 * Gate A20 for high memory
51 /* printf - only handles %d as decimal, %c as char, %s as string */
54 printf(const char *format, ...)
56 int *dataptr = (int *)&format;
60 while ((c = *format++))
64 switch (c = *format++) {
67 char buf[10], *ptr = buf;
81 unsigned int num = *dataptr++, dig;
82 char buf[8], *ptr = buf;
84 *ptr++ = (dig=(num&0xf)) > 9?
93 case 'c': putchar((*dataptr++)&0xff); break;
95 char *ptr = (char *)*dataptr++;
108 if (loadflags & RB_DUAL) {
111 } else if (loadflags & RB_SERIAL)
123 if (loadflags & RB_DUAL) {
126 else if (serial_ischar())
130 } else if (loadflags & RB_SERIAL)
149 * This routine uses an inb to an unused port, the time to execute that
150 * inb is approximately 1.25uS. This value is pretty constant across
151 * all CPU's and all buses, with the exception of some PCI implentations
152 * that do not forward this I/O address to the ISA bus as they know it
153 * is not a valid ISA bus address, those machines execute this inb in
156 * XXX this should be converted to use bios_tick.
164 (void)outb(0x5f,0); /* about 600ns */
178 * Checking the keyboard has the side effect of enabling clock
179 * interrupts so that bios_tick works. Check the keyboard to
180 * get this side effect even if we only want the serial status.
184 if (loadflags & RB_DUAL) {
187 } else if (!(loadflags & RB_SERIAL))
189 return (serial_ischar());
192 static __inline unsigned
193 pword(unsigned physaddr)
196 static int counter = 0;
199 for (i = 0; i < 512; i++)
207 * Give the fs prefix separately because gas omits it for
208 * "movl %fs:0x46c, %eax".
210 __asm __volatile("fs; movl %1, %0" : "=r" (result)
211 : "m" (*(unsigned *)physaddr));
219 #define bios_tick pword(0x46c)
221 #define BIOS_TICK_MS 1
223 #define BIOS_TICK_MS 55
225 unsigned initial_bios_tick;
229 for (initial_bios_tick = bios_tick;
230 bios_tick - initial_bios_tick < BOOTWAIT / BIOS_TICK_MS;)
234 switch(*ptr = getchar(ptr - buf) & 0xff) {
240 if (ptr > buf) ptr--;
247 #error "TIMEOUT without BOOTWAIT"
249 for (initial_bios_tick = bios_tick;;) {
252 if (bios_tick - initial_bios_tick >=
253 TIMEOUT / BIOS_TICK_MS)
262 strcmp(const char *s1, const char *s2)
274 strcasecmp(const char *s1, const char *s2)
277 * We only consider ASCII chars and don't anticipate
278 * control characters (they are invalid in filenames
281 while ((*s1 & 0x5f) == (*s2 & 0x5f)) {
291 bcopy(const void *from, void *to, size_t len)
293 char *fp = (char *)from;
294 char *tp = (char *)to;
300 /* To quote Ken: "You are not expected to understand this." :) */
305 putchar((char)tw_chars);
306 tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24);
310 static unsigned short *Crtat = (unsigned short *)0;
316 static unsigned short *crtat;
317 unsigned char sys_type;
322 sys_type = *(unsigned char *)V(0xA1501);
323 if (sys_type & 0x08) {
324 Crtat = (unsigned short *)V(0xE0000);
329 Crtat = (unsigned short *)V(0xA0000);
340 } while ((int)crtat % 16);
346 crtat -= (crtat - Crtat) % col;
352 *crtat = (c == 0x5c ? 0xfc : c);
353 *(crtat++ + 0x1000) = 0xe1;
357 if (crtat >= Crtat + col * row) {
359 for (i = 1; i < row; i++) {
360 bcopy((void *)(cp+col), (void *)cp, col*2);
363 for (i = 0; i < col; i++) {
369 while((inb(0x60) & 0x04) == 0) {}
371 outb(0x60, pos & 0xff);
372 outb(0x60, pos >> 8);
375 void machine_check(void)
380 u_char epson_machine_id = *(unsigned char *)V(0xA1624);
382 /* PC98_SYSTEM_PARAMETER(0x501) */
383 ret = ((*(unsigned char*)V(0xA1501)) & 0x08) >> 3;
386 while (inb(0x60) & 0x20) {}
387 while (!(inb(0x60) & 0x20)) {}
393 /* M_NORMAL, use CG window (all NEC OK) */
395 for (i = 0; i < 4; i++) {
396 data += *((unsigned long*)V(0xA4000) + i);/* 0xa4000 */
398 if (data == 0x6efc58fc) { /* DA data */
403 ret |= (inb(0x42) & 0x20) ? M_8M : 0;
405 /* PC98_SYSTEM_PARAMETER(0x400) */
406 if ((*(unsigned char*)V(0xA1400)) & 0x80) {
409 if (ret & M_NEC_PC98) {
410 /* PC98_SYSTEM_PARAMETER(0x458) */
411 if ((*(unsigned char*)V(0xA1458)) & 0x80) {
418 switch (epson_machine_id) {
419 case 0x20: /* note A */
420 case 0x22: /* note W */
421 case 0x27: /* note AE */
422 case 0x2a: /* note WR */
429 (*(unsigned long *)V(0xA1620)) = ret;