|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1992 NeXT Computer, Inc. ! 27: * ! 28: * Intel386 Family: Descriptor manipulation. ! 29: * ! 30: * HISTORY ! 31: * ! 32: * 1 April 1992 ? at NeXT ! 33: * Created. ! 34: */ ! 35: ! 36: #import <mach/vm_param.h> /* for round_page() */ ! 37: ! 38: #import <architecture/i386/table.h> ! 39: ! 40: /* ! 41: * Convert a segment size ! 42: * into a page-granular limit. ! 43: */ ! 44: #define page_limit(size) \ ! 45: (i386_round_page(size) - I386_PGBYTES) ! 46: ! 47: /* ! 48: * Convert a segment size ! 49: * into a byte-granular limit. ! 50: */ ! 51: #define byte_limit(size) \ ! 52: ((size) - 1) ! 53: ! 54: /* ! 55: * These types allow the ! 56: * breaking up of base and ! 57: * limit values so that the ! 58: * descriptors can be filled ! 59: * in easily. ! 60: */ ! 61: ! 62: typedef union { ! 63: unsigned int word; ! 64: struct { ! 65: unsigned int base00 :16, ! 66: base16 :8, ! 67: base24 :8; ! 68: } fields; ! 69: } conv_base_t; ! 70: ! 71: typedef union { ! 72: unsigned int word; ! 73: struct { ! 74: unsigned int limit00 :16, ! 75: limit16 :4, ! 76: :12; ! 77: } fields_byte; ! 78: struct { ! 79: unsigned int :12, ! 80: limit00 :16, ! 81: limit16 :4; ! 82: } fields_page; ! 83: } conv_limit_t; ! 84: ! 85: /* ! 86: * Initialize a descriptor ! 87: * to map an LDT segment. ! 88: */ ! 89: ! 90: static inline ! 91: void ! 92: map_ldt(desc, base, size) ! 93: ldt_desc_t * desc; ! 94: vm_offset_t base; ! 95: vm_size_t size; ! 96: { ! 97: conv_base_t tbase; ! 98: conv_limit_t tlimit; ! 99: ! 100: tbase.word = base; ! 101: tlimit.word = byte_limit(size); ! 102: ! 103: desc->base00 = tbase.fields.base00; ! 104: desc->base16 = tbase.fields.base16; ! 105: desc->base24 = tbase.fields.base24; ! 106: desc->type = DESC_LDT; ! 107: desc->present = TRUE; ! 108: desc->granular = DESC_GRAN_BYTE; ! 109: desc->limit00 = tlimit.fields_byte.limit00; ! 110: desc->limit16 = tlimit.fields_byte.limit16; ! 111: } ! 112: ! 113: /* ! 114: * Initialize a descriptor ! 115: * to map a TSS. ! 116: */ ! 117: ! 118: static inline ! 119: void ! 120: map_tss(desc, base, size) ! 121: tss_desc_t * desc; ! 122: vm_offset_t base; ! 123: vm_size_t size; ! 124: { ! 125: conv_base_t tbase; ! 126: conv_limit_t tlimit; ! 127: ! 128: tbase.word = base; ! 129: tlimit.word = byte_limit(size); ! 130: ! 131: desc->base00 = tbase.fields.base00; ! 132: desc->base16 = tbase.fields.base16; ! 133: desc->base24 = tbase.fields.base24; ! 134: desc->type = DESC_TSS; ! 135: desc->dpl = KERN_PRIV; ! 136: desc->present = TRUE; ! 137: desc->granular = DESC_GRAN_BYTE; ! 138: desc->limit00 = tlimit.fields_byte.limit00; ! 139: desc->limit16 = tlimit.fields_byte.limit16; ! 140: } ! 141: ! 142: /* ! 143: * Initialize a descriptor ! 144: * to map a code segment. ! 145: */ ! 146: ! 147: static inline ! 148: void ! 149: map_code(desc, base, size, priv, exec_only) ! 150: code_desc_t * desc; ! 151: vm_offset_t base; ! 152: vm_size_t size; ! 153: int priv; ! 154: boolean_t exec_only; ! 155: { ! 156: conv_base_t tbase; ! 157: conv_limit_t tlimit; ! 158: ! 159: tbase.word = base; ! 160: ! 161: desc->base00 = tbase.fields.base00; ! 162: desc->base16 = tbase.fields.base16; ! 163: desc->base24 = tbase.fields.base24; ! 164: desc->type = exec_only? DESC_CODE_EXEC: DESC_CODE_READ; ! 165: desc->dpl = priv; ! 166: desc->present = TRUE; ! 167: desc->opsz = DESC_CODE_32B; ! 168: ! 169: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */ ! 170: tlimit.word = byte_limit(size); ! 171: ! 172: desc->granular = DESC_GRAN_BYTE; ! 173: desc->limit00 = tlimit.fields_byte.limit00; ! 174: desc->limit16 = tlimit.fields_byte.limit16; ! 175: } ! 176: else { ! 177: tlimit.word = page_limit(size); ! 178: ! 179: desc->granular = DESC_GRAN_PAGE; ! 180: desc->limit00 = tlimit.fields_page.limit00; ! 181: desc->limit16 = tlimit.fields_page.limit16; ! 182: } ! 183: } ! 184: ! 185: /* ! 186: * Initialize a descriptor ! 187: * to map a 16-bit code segment. ! 188: */ ! 189: ! 190: static inline ! 191: void ! 192: map_code_16(desc, base, size, priv, exec_only) ! 193: code_desc_t * desc; ! 194: vm_offset_t base; ! 195: vm_size_t size; ! 196: int priv; ! 197: boolean_t exec_only; ! 198: { ! 199: conv_base_t tbase; ! 200: conv_limit_t tlimit; ! 201: ! 202: tbase.word = base; ! 203: ! 204: desc->base00 = tbase.fields.base00; ! 205: desc->base16 = tbase.fields.base16; ! 206: desc->base24 = tbase.fields.base24; ! 207: desc->type = exec_only? DESC_CODE_EXEC: DESC_CODE_READ; ! 208: desc->dpl = priv; ! 209: desc->present = TRUE; ! 210: desc->opsz = DESC_CODE_16B; ! 211: ! 212: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */ ! 213: tlimit.word = byte_limit(size); ! 214: ! 215: desc->granular = DESC_GRAN_BYTE; ! 216: desc->limit00 = tlimit.fields_byte.limit00; ! 217: desc->limit16 = tlimit.fields_byte.limit16; ! 218: } ! 219: else { ! 220: tlimit.word = page_limit(size); ! 221: ! 222: desc->granular = DESC_GRAN_PAGE; ! 223: desc->limit00 = tlimit.fields_page.limit00; ! 224: desc->limit16 = tlimit.fields_page.limit16; ! 225: } ! 226: } ! 227: ! 228: /* ! 229: * Initialize a descriptor ! 230: * to map a data segment. ! 231: */ ! 232: ! 233: static inline ! 234: void ! 235: map_data(desc, base, size, priv, read_only) ! 236: data_desc_t * desc; ! 237: vm_offset_t base; ! 238: vm_size_t size; ! 239: int priv; ! 240: boolean_t read_only; ! 241: { ! 242: conv_base_t tbase; ! 243: conv_limit_t tlimit; ! 244: ! 245: tbase.word = base; ! 246: ! 247: desc->base00 = tbase.fields.base00; ! 248: desc->base16 = tbase.fields.base16; ! 249: desc->base24 = tbase.fields.base24; ! 250: desc->type = read_only? DESC_DATA_RONLY: DESC_DATA_WRITE; ! 251: desc->dpl = priv; ! 252: desc->present = TRUE; ! 253: desc->stksz = DESC_DATA_32B; ! 254: ! 255: if (byte_limit(size) < (1 << 20)) { /* 2 ^ 20 or 1MB */ ! 256: tlimit.word = byte_limit(size); ! 257: ! 258: desc->granular = DESC_GRAN_BYTE; ! 259: desc->limit00 = tlimit.fields_byte.limit00; ! 260: desc->limit16 = tlimit.fields_byte.limit16; ! 261: } ! 262: else { ! 263: tlimit.word = page_limit(size); ! 264: ! 265: desc->granular = DESC_GRAN_PAGE; ! 266: desc->limit00 = tlimit.fields_page.limit00; ! 267: desc->limit16 = tlimit.fields_page.limit16; ! 268: } ! 269: } ! 270: ! 271: /* ! 272: * Change a descriptor to ! 273: * map a different LDT. Only ! 274: * change the segment base. ! 275: */ ! 276: ! 277: static inline ! 278: void ! 279: remap_ldt(desc, base) ! 280: ldt_desc_t * desc; ! 281: vm_offset_t base; ! 282: { ! 283: conv_base_t tbase; ! 284: ! 285: tbase.word = base; ! 286: ! 287: desc->base00 = tbase.fields.base00; ! 288: desc->base16 = tbase.fields.base16; ! 289: desc->base24 = tbase.fields.base24; ! 290: } ! 291: ! 292: /* ! 293: * Change a descriptor to ! 294: * map a different TSS. Only ! 295: * change the segment base and ! 296: * reset the type field (busy bit). ! 297: */ ! 298: ! 299: static inline ! 300: void ! 301: remap_tss(desc, base) ! 302: tss_desc_t * desc; ! 303: vm_offset_t base; ! 304: { ! 305: conv_base_t tbase; ! 306: ! 307: tbase.word = base; ! 308: ! 309: desc->base00 = tbase.fields.base00; ! 310: desc->base16 = tbase.fields.base16; ! 311: desc->base24 = tbase.fields.base24; ! 312: desc->type = DESC_TSS; ! 313: } ! 314: ! 315: /* ! 316: * This type allows the ! 317: * breaking up of the offset ! 318: * value so that the gate ! 319: * can be filled in easily. ! 320: */ ! 321: ! 322: typedef union { ! 323: unsigned int word; ! 324: struct { ! 325: unsigned int offset00:16, ! 326: offset16:16; ! 327: } fields; ! 328: } conv_offset_t; ! 329: ! 330: /* ! 331: * Initialize a call gate. ! 332: */ ! 333: ! 334: static inline ! 335: void ! 336: make_call_gate(desc, seg, offset, priv, argcnt) ! 337: call_gate_t * desc; ! 338: sel_t seg; ! 339: vm_offset_t offset; ! 340: int priv, argcnt; ! 341: { ! 342: conv_offset_t toffset; ! 343: ! 344: toffset.word = offset; ! 345: ! 346: desc->offset00 = toffset.fields.offset00; ! 347: desc->offset16 = toffset.fields.offset16; ! 348: desc->seg = seg; ! 349: desc->argcnt = argcnt; ! 350: desc->type = DESC_CALL_GATE; ! 351: desc->dpl = priv; ! 352: desc->present = TRUE; ! 353: } ! 354: ! 355: /* ! 356: * Initialize a trap gate. ! 357: */ ! 358: ! 359: static inline ! 360: void ! 361: make_trap_gate(desc, seg, offset, priv) ! 362: trap_gate_t * desc; ! 363: sel_t seg; ! 364: vm_offset_t offset; ! 365: int priv; ! 366: { ! 367: conv_offset_t toffset; ! 368: ! 369: toffset.word = offset; ! 370: ! 371: desc->offset00 = toffset.fields.offset00; ! 372: desc->offset16 = toffset.fields.offset16; ! 373: desc->seg = seg; ! 374: desc->type = DESC_TRAP_GATE; ! 375: desc->dpl = priv; ! 376: desc->present = TRUE; ! 377: } ! 378: ! 379: /* ! 380: * Initialize an interrupt gate. ! 381: */ ! 382: ! 383: static inline ! 384: void ! 385: make_intr_gate(desc, seg, offset, priv) ! 386: intr_gate_t * desc; ! 387: sel_t seg; ! 388: vm_offset_t offset; ! 389: int priv; ! 390: { ! 391: conv_offset_t toffset; ! 392: ! 393: toffset.word = offset; ! 394: ! 395: desc->offset00 = toffset.fields.offset00; ! 396: desc->offset16 = toffset.fields.offset16; ! 397: desc->seg = seg; ! 398: desc->type = DESC_INTR_GATE; ! 399: desc->dpl = priv; ! 400: desc->present = TRUE; ! 401: } ! 402: ! 403: /* ! 404: * Initialize a task gate. ! 405: */ ! 406: ! 407: static inline ! 408: void ! 409: make_task_gate(desc, tss, priv) ! 410: task_gate_t * desc; ! 411: sel_t tss; ! 412: int priv; ! 413: { ! 414: desc->tss = tss; ! 415: desc->type = DESC_TASK_GATE; ! 416: desc->dpl = priv; ! 417: desc->present = TRUE; ! 418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.