|
|
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.