Annotation of kernel/machdep/i386/desc_inline.h, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.