|
|
1.1 root 1: /*
2: * Copyright (c) 1995-1994 The University of Utah and
3: * the Computer Systems Laboratory at the University of Utah (CSL).
4: * All rights reserved.
5: *
6: * Permission to use, copy, modify and distribute this software is hereby
7: * granted provided that (1) source code retains these copyright, permission,
8: * and disclaimer notices, and (2) redistributions including binaries
9: * reproduce the notices in supporting documentation, and (3) all advertising
10: * materials mentioning features or use of this software display the following
11: * acknowledgement: ``This product includes software developed by the
12: * Computer Systems Laboratory at the University of Utah.''
13: *
14: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
15: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
16: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17: *
18: * CSL requests users of this software to return to [email protected] any
19: * improvements that they make and grant CSL redistribution rights.
20: *
21: * Author: Bryan Ford, University of Utah CSL
22: */
23:
24:
25: #include <mach/machine/pio.h>
26: #include <mach/machine/code16.h>
27:
28: #include "i16_a20.h"
29:
30:
31: /* Keyboard stuff for turning on the A20 address line (gak!). */
32: #define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
33: #define K_STATUS 0x64 /* keyboard status (read-only) */
34: #define K_CMD 0x64 /* keybd ctlr command (write-only) */
35:
36: #define K_OBUF_FUL 0x01 /* output buffer full */
37: #define K_IBUF_FUL 0x02 /* input buffer full */
38:
39: #define KC_CMD_WIN 0xd0 /* read output port */
40: #define KC_CMD_WOUT 0xd1 /* write output port */
41:
42: #define KB_ENABLE_A20 0xdf /* Linux and my BIOS uses this,
43: and I trust them more than Mach 3.0,
44: but I'd like to know what the difference is
45: and if it matters. */
46: /*0x9f*/ /* enable A20,
47: enable output buffer full interrupt
48: enable data line
49: disable clock line */
50: #define KB_DISABLE_A20 0xdd
51:
52:
53: CODE16
54:
55:
56: /*
57: This routine ensures that the keyboard command queue is empty
58: (after emptying the output buffers)
59:
60: No timeout is used - if this hangs there is something wrong with
61: the machine, and we probably couldn't proceed anyway.
62: XXX should at least die properly
63: */
64: static void i16_empty_8042(void)
65: {
66: int status;
67:
68: retry:
69: i16_nanodelay(1000);
70: status = i16_inb(K_STATUS);
71:
72: if (status & K_OBUF_FUL)
73: {
74: i16_nanodelay(1000);
75: i16_inb(K_RDWR);
76: goto retry;
77: }
78:
79: if (status & K_IBUF_FUL)
80: goto retry;
81: }
82:
83: int i16_raw_test_a20(void);
84:
85: /* Enable the A20 address line. */
86: void i16_raw_enable_a20(void)
87: {
88: int v;
89:
90: /* XXX try int 15h function 24h */
91:
92: if (i16_raw_test_a20())
93: return;
94:
95: /* PS/2 */
96: v = i16_inb(0x92);
97: i16_nanodelay(1000);
98: i16_outb(0x92,v | 2);
99:
100: if (i16_raw_test_a20())
101: return;
102:
103: /* AT */
104: i16_empty_8042();
105: i16_outb(K_CMD, KC_CMD_WOUT);
106: i16_empty_8042();
107: i16_outb(K_RDWR, KB_ENABLE_A20);
108: i16_empty_8042();
109:
110: /* Wait until the a20 line gets enabled. */
111: while (!i16_raw_test_a20());
112: }
113:
114: /* Disable the A20 address line. */
115: void i16_raw_disable_a20(void)
116: {
117: int v;
118:
119: if (!i16_raw_test_a20())
120: return;
121:
122: /* PS/2 */
123: v = i16_inb(0x92);
124: i16_nanodelay(1000);
125: i16_outb(0x92, v & ~2);
126:
127: if (!i16_raw_test_a20())
128: return;
129:
130: /* AT */
131: i16_empty_8042();
132: i16_outb(K_CMD, KC_CMD_WOUT);
133: i16_empty_8042();
134: i16_outb(K_RDWR, KB_DISABLE_A20);
135: i16_empty_8042();
136:
137: /* Wait until the a20 line gets disabled. */
138: while (i16_raw_test_a20());
139: }
140:
141:
142: void (*i16_enable_a20)(void) = i16_raw_enable_a20;
143: void (*i16_disable_a20)(void) = i16_raw_disable_a20;
144:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.