Annotation of Gnu-Mach/i386/intel/pmap.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File:   pmap.h
        !            28:  *
        !            29:  *     Authors:  Avadis Tevanian, Jr., Michael Wayne Young
        !            30:  *     Date:   1985
        !            31:  *
        !            32:  *     Machine-dependent structures for the physical map module.
        !            33:  */
        !            34: 
        !            35: #ifndef        _PMAP_MACHINE_
        !            36: #define _PMAP_MACHINE_ 1
        !            37: 
        !            38: #ifndef        ASSEMBLER
        !            39: 
        !            40: #include <kern/zalloc.h>
        !            41: #include <kern/lock.h>
        !            42: #include <mach/machine/vm_param.h>
        !            43: #include <mach/vm_statistics.h>
        !            44: #include <mach/kern_return.h>
        !            45: 
        !            46: /*
        !            47:  *     Define the generic in terms of the specific
        !            48:  */
        !            49: 
        !            50: #if    i386
        !            51: #define        INTEL_PGBYTES           I386_PGBYTES
        !            52: #define INTEL_PGSHIFT          I386_PGSHIFT
        !            53: #define        intel_btop(x)           i386_btop(x)
        !            54: #define        intel_ptob(x)           i386_ptob(x)
        !            55: #define        intel_round_page(x)     i386_round_page(x)
        !            56: #define        intel_trunc_page(x)     i386_trunc_page(x)
        !            57: #define trunc_intel_to_vm(x)   trunc_i386_to_vm(x)
        !            58: #define round_intel_to_vm(x)   round_i386_to_vm(x)
        !            59: #define vm_to_intel(x)         vm_to_i386(x)
        !            60: #endif i386
        !            61: #if    i860
        !            62: #define        INTEL_PGBYTES           I860_PGBYTES
        !            63: #define INTEL_PGSHIFT          I860_PGSHIFT
        !            64: #define        intel_btop(x)           i860_btop(x)
        !            65: #define        intel_ptob(x)           i860_ptob(x)
        !            66: #define        intel_round_page(x)     i860_round_page(x)
        !            67: #define        intel_trunc_page(x)     i860_trunc_page(x)
        !            68: #define trunc_intel_to_vm(x)   trunc_i860_to_vm(x)
        !            69: #define round_intel_to_vm(x)   round_i860_to_vm(x)
        !            70: #define vm_to_intel(x)         vm_to_i860(x)
        !            71: #endif i860
        !            72: 
        !            73: /*
        !            74:  *     i386/i486/i860 Page Table Entry
        !            75:  */
        !            76: 
        !            77: typedef unsigned int   pt_entry_t;
        !            78: #define PT_ENTRY_NULL  ((pt_entry_t *) 0)
        !            79: 
        !            80: #endif ASSEMBLER
        !            81: 
        !            82: #define INTEL_OFFMASK  0xfff   /* offset within page */
        !            83: #define PDESHIFT       22      /* page descriptor shift */
        !            84: #define PDEMASK                0x3ff   /* mask for page descriptor index */
        !            85: #define PTESHIFT       12      /* page table shift */
        !            86: #define PTEMASK                0x3ff   /* mask for page table index */
        !            87: 
        !            88: /*
        !            89:  *     Convert linear offset to page descriptor index
        !            90:  */
        !            91: #define lin2pdenum(a)  (((a) >> PDESHIFT) & PDEMASK)
        !            92: 
        !            93: /*
        !            94:  *     Convert page descriptor index to linear address
        !            95:  */
        !            96: #define pdenum2lin(a)  ((vm_offset_t)(a) << PDESHIFT)
        !            97: 
        !            98: /*
        !            99:  *     Convert linear offset to page table index
        !           100:  */
        !           101: #define ptenum(a)      (((a) >> PTESHIFT) & PTEMASK)
        !           102: 
        !           103: #define NPTES  (intel_ptob(1)/sizeof(pt_entry_t))
        !           104: #define NPDES  (intel_ptob(1)/sizeof(pt_entry_t))
        !           105: 
        !           106: /*
        !           107:  *     Hardware pte bit definitions (to be used directly on the ptes
        !           108:  *     without using the bit fields).
        !           109:  */
        !           110: 
        !           111: #if    i860
        !           112: #define INTEL_PTE_valid                0x00000001
        !           113: #else
        !           114: #define INTEL_PTE_VALID                0x00000001
        !           115: #endif
        !           116: #define INTEL_PTE_WRITE                0x00000002
        !           117: #define INTEL_PTE_USER         0x00000004
        !           118: #define INTEL_PTE_WTHRU                0x00000008
        !           119: #define INTEL_PTE_NCACHE       0x00000010
        !           120: #define INTEL_PTE_REF          0x00000020
        !           121: #define INTEL_PTE_MOD          0x00000040
        !           122: #define INTEL_PTE_WIRED                0x00000200
        !           123: #define INTEL_PTE_PFN          0xfffff000
        !           124: 
        !           125: #if    i860
        !           126: #if    NOCACHE
        !           127: #define        INTEL_PTE_VALID         (INTEL_PTE_valid        \
        !           128:                                |INTEL_PTE_WTHRU        \
        !           129:                                |INTEL_PTE_NCACHE       \
        !           130:                                |INTEL_PTE_REF          \
        !           131:                                |INTEL_PTE_MOD          \
        !           132:                                )
        !           133: #else  NOCACHE
        !           134: #define        INTEL_PTE_VALID         (INTEL_PTE_valid        \
        !           135:                                |INTEL_PTE_REF          \
        !           136:                                |INTEL_PTE_MOD          \
        !           137:                                )
        !           138: #endif NOCACHE
        !           139: #endif i860
        !           140: 
        !           141: #define        pa_to_pte(a)            ((a) & INTEL_PTE_PFN)
        !           142: #define        pte_to_pa(p)            ((p) & INTEL_PTE_PFN)
        !           143: #define        pte_increment_pa(p)     ((p) += INTEL_OFFMASK+1)
        !           144: 
        !           145: /*
        !           146:  *     Convert page table entry to kernel virtual address
        !           147:  */
        !           148: #define ptetokv(a)     (phystokv(pte_to_pa(a)))
        !           149: 
        !           150: #ifndef        ASSEMBLER
        !           151: typedef        volatile long   cpu_set;        /* set of CPUs - must be <= 32 */
        !           152:                                        /* changed by other processors */
        !           153: 
        !           154: struct pmap {
        !           155:        pt_entry_t      *dirbase;       /* page directory pointer register */
        !           156:        int             ref_count;      /* reference count */
        !           157:        decl_simple_lock_data(,lock)
        !           158:                                        /* lock on map */
        !           159:        struct pmap_statistics  stats;  /* map statistics */
        !           160:        cpu_set         cpus_using;     /* bitmap of cpus using pmap */
        !           161: };
        !           162: 
        !           163: typedef struct pmap    *pmap_t;
        !           164: 
        !           165: #define PMAP_NULL      ((pmap_t) 0)
        !           166: 
        !           167: #if    i860
        !           168: /*#define      set_dirbase(dirbase)    flush_and_ctxsw(dirbase)*//*akp*/
        !           169: #else
        !           170: #define        set_dirbase(dirbase)    set_cr3(dirbase)
        !           171: #endif
        !           172: 
        !           173: #if    NCPUS > 1
        !           174: /*
        !           175:  *     List of cpus that are actively using mapped memory.  Any
        !           176:  *     pmap update operation must wait for all cpus in this list.
        !           177:  *     Update operations must still be queued to cpus not in this
        !           178:  *     list.
        !           179:  */
        !           180: cpu_set                cpus_active;
        !           181: 
        !           182: /*
        !           183:  *     List of cpus that are idle, but still operating, and will want
        !           184:  *     to see any kernel pmap updates when they become active.
        !           185:  */
        !           186: cpu_set                cpus_idle;
        !           187: 
        !           188: /*
        !           189:  *     Quick test for pmap update requests.
        !           190:  */
        !           191: volatile
        !           192: boolean_t      cpu_update_needed[NCPUS];
        !           193: 
        !           194: /*
        !           195:  *     External declarations for PMAP_ACTIVATE.
        !           196:  */
        !           197: 
        !           198: void           process_pmap_updates();
        !           199: void           pmap_update_interrupt();
        !           200: extern pmap_t  kernel_pmap;
        !           201: 
        !           202: #endif NCPUS > 1
        !           203: 
        !           204: /*
        !           205:  *     Machine dependent routines that are used only for i386/i486/i860.
        !           206:  */
        !           207: 
        !           208: pt_entry_t *pmap_pte(pmap_t pmap, vm_offset_t addr);
        !           209: 
        !           210: /*
        !           211:  *     Macros for speed.
        !           212:  */
        !           213: 
        !           214: #if    NCPUS > 1
        !           215: 
        !           216: /*
        !           217:  *     For multiple CPUS, PMAP_ACTIVATE and PMAP_DEACTIVATE must manage
        !           218:  *     fields to control TLB invalidation on other CPUS.
        !           219:  */
        !           220: 
        !           221: #define        PMAP_ACTIVATE_KERNEL(my_cpu)    {                               \
        !           222:                                                                        \
        !           223:        /*                                                              \
        !           224:         *      Let pmap updates proceed while we wait for this pmap.   \
        !           225:         */                                                             \
        !           226:        i_bit_clear((my_cpu), &cpus_active);                            \
        !           227:                                                                        \
        !           228:        /*                                                              \
        !           229:         *      Lock the pmap to put this cpu in its active set.        \
        !           230:         *      Wait for updates here.                                  \
        !           231:         */                                                             \
        !           232:        simple_lock(&kernel_pmap->lock);                                \
        !           233:                                                                        \
        !           234:        /*                                                              \
        !           235:         *      Process invalidate requests for the kernel pmap.        \
        !           236:         */                                                             \
        !           237:        if (cpu_update_needed[(my_cpu)])                                \
        !           238:            process_pmap_updates(kernel_pmap);                          \
        !           239:                                                                        \
        !           240:        /*                                                              \
        !           241:         *      Mark that this cpu is using the pmap.                   \
        !           242:         */                                                             \
        !           243:        i_bit_set((my_cpu), &kernel_pmap->cpus_using);                  \
        !           244:                                                                        \
        !           245:        /*                                                              \
        !           246:         *      Mark this cpu active - IPL will be lowered by           \
        !           247:         *      load_context().                                         \
        !           248:         */                                                             \
        !           249:        i_bit_set((my_cpu), &cpus_active);                              \
        !           250:                                                                        \
        !           251:        simple_unlock(&kernel_pmap->lock);                              \
        !           252: }
        !           253: 
        !           254: #define        PMAP_DEACTIVATE_KERNEL(my_cpu)  {                               \
        !           255:        /*                                                              \
        !           256:         *      Mark pmap no longer in use by this cpu even if          \
        !           257:         *      pmap is locked against updates.                         \
        !           258:         */                                                             \
        !           259:        i_bit_clear((my_cpu), &kernel_pmap->cpus_using);                \
        !           260: }
        !           261: 
        !           262: #define PMAP_ACTIVATE_USER(pmap, th, my_cpu)   {                       \
        !           263:        register pmap_t         tpmap = (pmap);                         \
        !           264:                                                                        \
        !           265:        if (tpmap == kernel_pmap) {                                     \
        !           266:            /*                                                          \
        !           267:             *  If this is the kernel pmap, switch to its page tables.  \
        !           268:             */                                                         \
        !           269:            set_dirbase(kvtophys(tpmap->dirbase));                      \
        !           270:        }                                                               \
        !           271:        else {                                                          \
        !           272:            /*                                                          \
        !           273:             *  Let pmap updates proceed while we wait for this pmap.   \
        !           274:             */                                                         \
        !           275:            i_bit_clear((my_cpu), &cpus_active);                        \
        !           276:                                                                        \
        !           277:            /*                                                          \
        !           278:             *  Lock the pmap to put this cpu in its active set.        \
        !           279:             *  Wait for updates here.                                  \
        !           280:             */                                                         \
        !           281:            simple_lock(&tpmap->lock);                                  \
        !           282:                                                                        \
        !           283:            /*                                                          \
        !           284:             *  No need to invalidate the TLB - the entire user pmap    \
        !           285:             *  will be invalidated by reloading dirbase.               \
        !           286:             */                                                         \
        !           287:            set_dirbase(kvtophys(tpmap->dirbase));                      \
        !           288:                                                                        \
        !           289:            /*                                                          \
        !           290:             *  Mark that this cpu is using the pmap.                   \
        !           291:             */                                                         \
        !           292:            i_bit_set((my_cpu), &tpmap->cpus_using);                    \
        !           293:                                                                        \
        !           294:            /*                                                          \
        !           295:             *  Mark this cpu active - IPL will be lowered by           \
        !           296:             *  load_context().                                         \
        !           297:             */                                                         \
        !           298:            i_bit_set((my_cpu), &cpus_active);                          \
        !           299:                                                                        \
        !           300:            simple_unlock(&tpmap->lock);                                \
        !           301:        }                                                               \
        !           302: }
        !           303: 
        !           304: #define PMAP_DEACTIVATE_USER(pmap, thread, my_cpu)     {               \
        !           305:        register pmap_t         tpmap = (pmap);                         \
        !           306:                                                                        \
        !           307:        /*                                                              \
        !           308:         *      Do nothing if this is the kernel pmap.                  \
        !           309:         */                                                             \
        !           310:        if (tpmap != kernel_pmap) {                                     \
        !           311:            /*                                                          \
        !           312:             *  Mark pmap no longer in use by this cpu even if          \
        !           313:             *  pmap is locked against updates.                         \
        !           314:             */                                                         \
        !           315:            i_bit_clear((my_cpu), &(pmap)->cpus_using);                 \
        !           316:        }                                                               \
        !           317: }
        !           318: 
        !           319: #define MARK_CPU_IDLE(my_cpu)  {                                       \
        !           320:        /*                                                              \
        !           321:         *      Mark this cpu idle, and remove it from the active set,  \
        !           322:         *      since it is not actively using any pmap.  Signal_cpus   \
        !           323:         *      will notice that it is idle, and avoid signaling it,    \
        !           324:         *      but will queue the update request for when the cpu      \
        !           325:         *      becomes active.                                         \
        !           326:         */                                                             \
        !           327:        int     s = splvm();                                            \
        !           328:        i_bit_set((my_cpu), &cpus_idle);                                \
        !           329:        i_bit_clear((my_cpu), &cpus_active);                            \
        !           330:        splx(s);                                                        \
        !           331: }
        !           332: 
        !           333: #define MARK_CPU_ACTIVE(my_cpu)        {                                       \
        !           334:                                                                        \
        !           335:        int     s = splvm();                                            \
        !           336:        /*                                                              \
        !           337:         *      If a kernel_pmap update was requested while this cpu    \
        !           338:         *      was idle, process it as if we got the interrupt.        \
        !           339:         *      Before doing so, remove this cpu from the idle set.     \
        !           340:         *      Since we do not grab any pmap locks while we flush      \
        !           341:         *      our TLB, another cpu may start an update operation      \
        !           342:         *      before we finish.  Removing this cpu from the idle      \
        !           343:         *      set assures that we will receive another update         \
        !           344:         *      interrupt if this happens.                              \
        !           345:         */                                                             \
        !           346:        i_bit_clear((my_cpu), &cpus_idle);                              \
        !           347:                                                                        \
        !           348:        if (cpu_update_needed[(my_cpu)])                                \
        !           349:            pmap_update_interrupt();                                    \
        !           350:                                                                        \
        !           351:        /*                                                              \
        !           352:         *      Mark that this cpu is now active.                       \
        !           353:         */                                                             \
        !           354:        i_bit_set((my_cpu), &cpus_active);                              \
        !           355:        splx(s);                                                        \
        !           356: }
        !           357: 
        !           358: #else  NCPUS > 1
        !           359: 
        !           360: /*
        !           361:  *     With only one CPU, we just have to indicate whether the pmap is
        !           362:  *     in use.
        !           363:  */
        !           364: 
        !           365: #define        PMAP_ACTIVATE_KERNEL(my_cpu)    {                               \
        !           366:        kernel_pmap->cpus_using = TRUE;                                 \
        !           367: }
        !           368: 
        !           369: #define        PMAP_DEACTIVATE_KERNEL(my_cpu)  {                               \
        !           370:        kernel_pmap->cpus_using = FALSE;                                \
        !           371: }
        !           372: 
        !           373: #define        PMAP_ACTIVATE_USER(pmap, th, my_cpu)    {                       \
        !           374:        register pmap_t         tpmap = (pmap);                         \
        !           375:                                                                        \
        !           376:        set_dirbase(kvtophys(tpmap->dirbase));                          \
        !           377:        if (tpmap != kernel_pmap) {                                     \
        !           378:            tpmap->cpus_using = TRUE;                                   \
        !           379:        }                                                               \
        !           380: }
        !           381: 
        !           382: #define PMAP_DEACTIVATE_USER(pmap, thread, cpu)        {                       \
        !           383:        if ((pmap) != kernel_pmap)                                      \
        !           384:            (pmap)->cpus_using = FALSE;                                 \
        !           385: }
        !           386: 
        !           387: #endif NCPUS > 1
        !           388: 
        !           389: #define PMAP_CONTEXT(pmap, thread)
        !           390: 
        !           391: #define        pmap_kernel()                   (kernel_pmap)
        !           392: #define pmap_resident_count(pmap)      ((pmap)->stats.resident_count)
        !           393: #define pmap_phys_address(frame)       ((vm_offset_t) (intel_ptob(frame)))
        !           394: #define pmap_phys_to_frame(phys)       ((int) (intel_btop(phys)))
        !           395: #define        pmap_copy(dst_pmap,src_pmap,dst_addr,len,src_addr)
        !           396: #define        pmap_attribute(pmap,addr,size,attr,value) \
        !           397:                                        (KERN_INVALID_ADDRESS)
        !           398: 
        !           399: #endif ASSEMBLER
        !           400: 
        !           401: #endif _PMAP_MACHINE_

unix.superglobalmegacorp.com

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