|
|
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: #include <mach/machine/code16.h>
25: #include <mach/machine/vm_types.h>
26: #include <mach/machine/far_ptr.h>
27: #include <mach/machine/asm.h>
28:
29: #include "i16_a20.h"
30: #include "phys_mem.h"
31: #include "debug.h"
32:
33:
34: struct far_pointer_16 xms_control;
35:
36: #define CALL_XMS "lcallw "SEXT(xms_control)
37:
38:
39: static vm_offset_t xms_phys_free_mem;
40: static vm_size_t xms_phys_free_size;
41:
42: static short free_handle;
43: static char free_handle_allocated;
44: static char free_handle_locked;
45:
46:
47: CODE32
48:
49: void xms_mem_collect(void)
50: {
51: if (xms_phys_free_mem)
52: {
53: phys_mem_add(xms_phys_free_mem, xms_phys_free_size);
54: xms_phys_free_mem = 0;
55: }
56: }
57:
58: CODE16
59:
60: static void i16_xms_enable_a20(void)
61: {
62: short success;
63: asm volatile(CALL_XMS : "=a" (success) : "a" (0x0500) : "ebx");
64: if (!success)
65: i16_die("XMS error: can't enable A20 line");
66: }
67:
68: static void i16_xms_disable_a20(void)
69: {
70: short success;
71: asm volatile(CALL_XMS : "=a" (success) : "a" (0x0600) : "ebx");
72: if (!success)
73: i16_die("XMS error: can't disable A20 line");
74: }
75:
76: void i16_xms_check()
77: {
78: unsigned short rc;
79: unsigned short free_k;
80:
81: /* Check for an XMS server. */
82: asm volatile("
83: int $0x2f
84: " : "=a" (rc)
85: : "a" (0x4300));
86: if ((rc & 0xff) != 0x80)
87: return;
88:
89: /* Get XMS driver's control function. */
90: asm volatile("
91: pushl %%ds
92: pushl %%es
93: int $0x2f
94: movw %%es,%0
95: popl %%es
96: popl %%ds
97: " : "=r" (xms_control.seg), "=b" (xms_control.ofs)
98: : "a" (0x4310));
99:
100: /* See how much memory is available. */
101: asm volatile(CALL_XMS
102: : "=a" (free_k)
103: : "a" (0x0800)
104: : "ebx", "edx");
105: if (free_k * 1024 == 0)
106: return;
107:
108: xms_phys_free_size = (unsigned)free_k * 1024;
109:
110: /* Grab the biggest memory block we can get. */
111: asm volatile(CALL_XMS
112: : "=a" (rc), "=d" (free_handle)
113: : "a" (0x0900), "d" (free_k)
114: : "ebx");
115: if (!rc)
116: i16_die("XMS error: can't allocate extended memory");
117:
118: free_handle_allocated = 1;
119:
120: /* Lock it down. */
121: asm volatile(CALL_XMS "
122: shll $16,%%edx
123: movw %%bx,%%dx
124: " : "=a" (rc), "=d" (xms_phys_free_mem)
125: : "a" (0x0c00), "d" (free_handle)
126: : "ebx");
127: if (!rc)
128: i16_die("XMS error: can't lock down extended memory");
129:
130: free_handle_locked = 1;
131:
132: /* We need to update phys_mem_max here
133: instead of just letting phys_mem_add() do it
134: when the memory is collected with phys_mem_collect(),
135: because VCPI initialization needs to know the top of physical memory
136: before phys_mem_collect() is called.
137: See i16_vcpi.c for the gross details. */
138: if (phys_mem_max < xms_phys_free_mem + xms_phys_free_size)
139: phys_mem_max = xms_phys_free_mem + xms_phys_free_size;
140:
141: i16_enable_a20 = i16_xms_enable_a20;
142: i16_disable_a20 = i16_xms_disable_a20;
143:
144: do_debug(i16_puts("XMS detected"));
145: }
146:
147: void i16_xms_shutdown()
148: {
149: unsigned short rc;
150:
151: if (free_handle_locked)
152: {
153: /* Unlock our memory block. */
154: asm volatile(CALL_XMS
155: : "=a" (rc)
156: : "a" (0x0d00), "d" (free_handle)
157: : "ebx");
158: free_handle_locked = 0;
159: if (!rc)
160: i16_die("XMS error: can't unlock extended memory");
161: }
162:
163: if (free_handle_allocated)
164: {
165: /* Free the memory block. */
166: asm volatile(CALL_XMS
167: : "=a" (rc)
168: : "a" (0x0a00), "d" (free_handle)
169: : "ebx");
170: free_handle_allocated = 0;
171: if (!rc)
172: i16_die("XMS error: can't free extended memory");
173: }
174: }
175:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.