[BACK]Return to pte.h CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / include

Annotation of sys/arch/sparc/include/pte.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pte.h,v 1.6 2007/05/29 09:54:21 sobrado Exp $ */
                      2: /*     $NetBSD: pte.h,v 1.19 1997/08/05 11:00:10 pk Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1996
                      6:  *     The President and Fellows of Harvard College. All rights reserved.
                      7:  * Copyright (c) 1992, 1993
                      8:  *     The Regents of the University of California.  All rights reserved.
                      9:  *
                     10:  * This software was developed by the Computer Systems Engineering group
                     11:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                     12:  * contributed to Berkeley.
                     13:  *
                     14:  * All advertising materials mentioning features or use of this software
                     15:  * must display the following acknowledgements:
                     16:  *     This product includes software developed by Harvard University.
                     17:  *     This product includes software developed by the University of
                     18:  *     California, Lawrence Berkeley Laboratory.
                     19:  *
                     20:  * Redistribution and use in source and binary forms, with or without
                     21:  * modification, are permitted provided that the following conditions
                     22:  * are met:
                     23:  * 1. Redistributions of source code must retain the above copyright
                     24:  *    notice, this list of conditions and the following disclaimer.
                     25:  * 2. Redistributions in binary form must reproduce the above copyright
                     26:  *    notice, this list of conditions and the following disclaimer in the
                     27:  *    documentation and/or other materials provided with the distribution.
                     28:  * 3. All advertising materials mentioning features or use of this software
                     29:  *    must display the following acknowledgements:
                     30:  *     This product includes software developed by Harvard University.
                     31:  *     This product includes software developed by the University of
                     32:  *     California, Berkeley and its contributors.
                     33:  * 4. Neither the name of the University nor the names of its contributors
                     34:  *    may be used to endorse or promote products derived from this software
                     35:  *    without specific prior written permission.
                     36:  *
                     37:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     38:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     39:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     40:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     41:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     42:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     43:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     44:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     45:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     46:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     47:  * SUCH DAMAGE.
                     48:  *
                     49:  *     @(#)pte.h       8.1 (Berkeley) 6/11/93
                     50:  */
                     51:
                     52: /*
                     53:  * Sun-4 (sort of), 4c (SparcStation), and 4m Page Table Entries
                     54:  * (Sun calls them `Page Map Entries').
                     55:  */
                     56:
                     57: #ifndef _LOCORE
                     58: /*
                     59:  * Segment maps contain `pmeg' (Page Map Entry Group) numbers.
                     60:  * A PMEG is simply an index that names a group of 32 (sun4) or
                     61:  * 64 (sun4c) PTEs.
                     62:  * Depending on the CPU model, we need 7 (sun4c) to 10 (sun4/400) bits
                     63:  * to hold the hardware MMU resource number.
                     64:  */
                     65: typedef u_short pmeg_t;                /* 10 bits needed per Sun-4 segmap entry */
                     66: /*
                     67:  * Region maps contain `smeg' (Segment Entry Group) numbers.
                     68:  * An SMEG is simply an index that names a group of 64 PMEGs.
                     69:  */
                     70: typedef u_char smeg_t;         /* 8 bits needed per Sun-4 regmap entry */
                     71: #endif
                     72:
                     73: /*
                     74:  * Address translation works as follows:
                     75:  *
                     76:  * (for sun4c and 2-level sun4)
                     77:  *     1. test va<31:29> -- these must be 000 or 111 (or you get a fault)
                     78:  *     2. concatenate context_reg<2:0> and va<29:18> to get a 15 bit number;
                     79:  *        use this to index the segment maps, yielding a 7 or 9 bit value.
                     80:  * (for 3-level sun4)
                     81:  *     1. concatenate context_reg<3:0> and va<31:24> to get a 8 bit number;
                     82:  *        use this to index the region maps, yielding a 10 bit value.
                     83:  *     2. take the value from (1) above and concatenate va<17:12> to
                     84:  *        get a `segment map entry' index.  This gives a 9 bit value.
                     85:  * (for sun4c)
                     86:  *     3. take the value from (2) above and concatenate va<17:12> to
                     87:  *        get a `page map entry' index.  This gives a 32-bit PTE.
                     88:  * (for sun4)
                     89:  *     3. take the value from (2 or 3) above and concatenate va<17:13> to
                     90:  *        get a `page map entry' index.  This gives a 32-bit PTE.
                     91:  **
                     92:  * For sun4m:
                     93:  *     1. Use context_reg<3:0> to index the context table (located at
                     94:  *        (context_reg << 2) | ((ctx_tbl_ptr_reg >> 2) << 6) ). This
                     95:  *        gives a 32-bit page-table-descriptor (PTP).
                     96:  *     2. Use va<31:24> to index the region table located by the PTP from (1):
                     97:  *        PTP<31:6> << 10. This gives another PTP for the segment tables
                     98:  *     3. Use va<23:18> to index the segment table located by the PTP from (2)
                     99:  *        as follows: PTP<31:4> << 8. This gives another PTP for the page tbl.
                    100:  *     4. Use va<17:12> to index the page table given by (3)'s PTP:
                    101:  *        PTP<31:4> << 8. This gives a 32-bit PTE.
                    102:  *
                    103:  * In other words:
                    104:  *
                    105:  *     struct sun4_3_levelmmu_virtual_addr {
                    106:  *             u_int   va_reg:8,       (virtual region)
                    107:  *                     va_seg:6,       (virtual segment)
                    108:  *                     va_pg:5,        (virtual page within segment)
                    109:  *                     va_off:13;      (offset within page)
                    110:  *     };
                    111:  *     struct sun4_virtual_addr {
                    112:  *             u_int   :2,             (required to be the same as bit 29)
                    113:  *                     va_seg:12,      (virtual segment)
                    114:  *                     va_pg:5,        (virtual page within segment)
                    115:  *                     va_off:13;      (offset within page)
                    116:  *     };
                    117:  *     struct sun4c_virtual_addr {
                    118:  *             u_int   :2,             (required to be the same as bit 29)
                    119:  *                     va_seg:12,      (virtual segment)
                    120:  *                     va_pg:6,        (virtual page within segment)
                    121:  *                     va_off:12;      (offset within page)
                    122:  *     };
                    123:  *
                    124:  *     struct sun4m_virtual_addr {
                    125:  *             u_int   va_reg:8,       (virtual region)
                    126:  *                     va_seg:6,       (virtual segment within region)
                    127:  *                     va_pg:6,        (virtual page within segment)
                    128:  *                     va_off:12;      (offset within page)
                    129:  *     };
                    130:  *
                    131:  * Then, given any `va':
                    132:  *
                    133:  *     extern smeg_t regmap[16][1<<8];         (3-level MMU only)
                    134:  *     extern pmeg_t segmap[8][1<<12];         ([16][1<<12] for sun4)
                    135:  *     extern int ptetable[128][1<<6];         ([512][1<<5] for sun4)
                    136:  *
                    137:  *     extern u_int  s4m_ctxmap[16];           (sun4m SRMMU only)
                    138:  *     extern u_int  s4m_regmap[16][1<<8];     (sun4m SRMMU only)
                    139:  *     extern u_int  s4m_segmap[1<<8][1<<6];   (sun4m SRMMU only)
                    140:  *     extern u_int  s4m_pagmap[1<<14][1<<6];  (sun4m SRMMU only)
                    141:  *
                    142:  * (the above being in the hardware, accessed as Alternate Address Spaces on
                    143:  *  all machines but the Sun4m SRMMU, in which case the tables are in physical
                    144:  *  kernel memory. In the 4m architecture, the tables are not layed out as
                    145:  *  2-dim arrays, but are sparsely allocated as needed, and point to each
                    146:  *  other.)
                    147:  *
                    148:  *     if (cputyp==CPU_SUN4M)          // SPARC Reference MMU
                    149:  *             regptp = s4m_ctxmap[curr_ctx];
                    150:  *             if (!(regptp & SRMMU_TEPTD)) TRAP();
                    151:  *             segptp = *(u_int *)(((regptp & ~0x3) << 4) | va.va_reg);
                    152:  *             if (!(segptp & SRMMU_TEPTD)) TRAP();
                    153:  *             pagptp = *(u_int *)(((segptp & ~0x3) << 4) | va.va_seg);
                    154:  *             if (!(pagptp & SRMMU_TEPTD)) TRAP();
                    155:  *             pte = *(u_int *)(((pagptp & ~0x3) << 4) | va.va_pg);
                    156:  *             if (!(pte & SRMMU_TEPTE)) TRAP();       // like PG_V
                    157:  *             if (usermode && PTE_PROT_LEVEL(pte) > 0x5) TRAP();
                    158:  *             if (writing && !PTE_PROT_LEVEL_ALLOWS_WRITING(pte)) TRAP();
                    159:  *             if (!(pte & SRMMU_PG_C)) DO_NOT_USE_CACHE_FOR_THIS_ACCESS();
                    160:  *             pte |= SRMMU_PG_R;
                    161:  *             if (writing) pte |= SRMMU_PG_M;
                    162:  *             physaddr = ((pte & SRMMU_PG_PFNUM) << SRMMU_PGSHIFT)|va.va_off;
                    163:  *             return;
                    164:  *     if (mmu_3l)
                    165:  *             physreg = regmap[curr_ctx][va.va_reg];
                    166:  *             physseg = segmap[physreg][va.va_seg];
                    167:  *     else
                    168:  *             physseg = segmap[curr_ctx][va.va_seg];
                    169:  *     pte = ptetable[physseg][va.va_pg];
                    170:  *     if (!(pte & PG_V)) TRAP();
                    171:  *     if (writing && !pte.pg_w) TRAP();
                    172:  *     if (usermode && pte.pg_s) TRAP();
                    173:  *     if (pte & PG_NC) DO_NOT_USE_CACHE_FOR_THIS_ACCESS();
                    174:  *     pte |= PG_U;                                    (mark used/accessed)
                    175:  *     if (writing) pte |= PG_M;                       (mark modified)
                    176:  *     ptetable[physseg][va.va_pg] = pte;
                    177:  *     physadr = ((pte & PG_PFNUM) << PGSHIFT) | va.va_off;
                    178:  */
                    179:
                    180: #if defined(SUN4_MMU3L) && !defined(SUN4)
                    181: #error "configuration error"
                    182: #endif
                    183:
                    184: #define        NBPRG   (1 << 24)       /* bytes per region */
                    185: #define        RGSHIFT 24              /* log2(NBPRG) */
                    186: #define        RGOFSET (NBPRG - 1)     /* mask for region offset */
                    187: #define NSEGRG (NBPRG / NBPSG) /* segments per region */
                    188:
                    189: #define        NBPSG   (1 << 18)       /* bytes per segment */
                    190: #define        SGSHIFT 18              /* log2(NBPSG) */
                    191: #define        SGOFSET (NBPSG - 1)     /* mask for segment offset */
                    192:
                    193: /* number of PTEs that map one segment (not number that fit in one segment!) */
                    194: #if defined(SUN4) && (defined(SUN4C) || defined(SUN4M))
                    195: extern int nptesg;
                    196: #define        NPTESG  nptesg          /* (which someone will have to initialize) */
                    197: #else
                    198: #define        NPTESG  (NBPSG / NBPG)
                    199: #endif
                    200:
                    201: /* virtual address to virtual region number */
                    202: #define        VA_VREG(va)     (((unsigned int)(va) >> RGSHIFT) & 255)
                    203:
                    204: /* virtual address to virtual segment number */
                    205: #define        VA_VSEG(va)     (((unsigned int)(va) >> SGSHIFT) & 63)
                    206:
                    207: /* virtual address to virtual page number, for Sun-4 and Sun-4c */
                    208: #define        VA_SUN4_VPG(va)         (((int)(va) >> 13) & 31)
                    209: #define        VA_SUN4C_VPG(va)        (((int)(va) >> 12) & 63)
                    210: #define VA_SUN4M_VPG(va)       (((int)(va) >> 12) & 63)
                    211:
                    212: /* virtual address to offset within page */
                    213: #define VA_SUN4_OFF(va)        (((int)(va)) & 0x1FFF)
                    214: #define VA_SUN4C_OFF(va)       (((int)(va)) & 0xFFF)
                    215: #define VA_SUN4M_OFF(va)       (((int)(va)) & 0xFFF)
                    216:
                    217: /* truncate virtual address to region base */
                    218: #define        VA_ROUNDDOWNTOREG(va)   ((int)(va) & ~RGOFSET)
                    219:
                    220: /* truncate virtual address to segment base */
                    221: #define        VA_ROUNDDOWNTOSEG(va)   ((int)(va) & ~SGOFSET)
                    222:
                    223: /* virtual segment to virtual address (must sign extend on holy MMUs!) */
                    224: #define        VRTOVA(vr)      ((CPU_ISSUN4M || HASSUN4_MMU3L) \
                    225:        ? ((int)(vr) << RGSHIFT)                        \
                    226:        : (((int)(vr) << (RGSHIFT+2)) >> 2))
                    227: #define        VSTOVA(vr,vs)   ((CPU_ISSUN4M || HASSUN4_MMU3L) \
                    228:        ? (((int)(vr) << RGSHIFT) + ((int)(vs) << SGSHIFT))     \
                    229:        : ((((int)(vr) << (RGSHIFT+2)) >> 2) + ((int)(vs) << SGSHIFT)))
                    230:
                    231: extern int mmu_has_hole;
                    232: #define VA_INHOLE(va)  (mmu_has_hole \
                    233:        ? ( (unsigned int)(((int)(va) >> PG_VSHIFT) + 1) > 1) \
                    234:        : 0)
                    235:
                    236: /* Define the virtual address space hole */
                    237: #define MMU_HOLE_START 0x20000000
                    238: #define MMU_HOLE_END   0xe0000000
                    239:
                    240: #if defined(SUN4M)             /* Optimization: sun4m, sun4c have same page */
                    241: #if defined(SUN4)              /* size, so they're used interchangeably */
                    242: #define VA_VPG(va)     (cputyp==CPU_SUN4 ? VA_SUN4_VPG(va) : VA_SUN4C_VPG(va))
                    243: #define VA_OFF(va)     (cputyp==CPU_SUN4 ? VA_SUN4_OFF(va) : VA_SUN4C_OFF(va))
                    244: #else
                    245: #define VA_VPG(va)     VA_SUN4M_VPG(va)
                    246: #define VA_OFF(va)     VA_SUN4M_OFF(va)
                    247: #endif /* defined SUN4 */
                    248: #else /* 4m not defined */
                    249: #if defined(SUN4) && defined(SUN4C)
                    250: #define VA_VPG(va)     (cputyp==CPU_SUN4C ? VA_SUN4C_VPG(va) : VA_SUN4_VPG(va))
                    251: #define VA_OFF(va)     (cputyp==CPU_SUN4C ? VA_SUN4C_OFF(va) : VA_SUN4_OFF(va))
                    252: #endif
                    253: #if defined(SUN4C) && !defined(SUN4)
                    254: #define VA_VPG(va)     VA_SUN4C_VPG(va)
                    255: #define VA_OFF(va)     VA_SUN4C_OFF(va)
                    256: #endif
                    257: #if !defined(SUN4C) && defined(SUN4)
                    258: #define        VA_VPG(va)      VA_SUN4_VPG(va)
                    259: #define VA_OFF(va)     VA_SUN4_OFF(va)
                    260: #endif
                    261: #endif /* defined 4m */
                    262:
                    263: /* there is no `struct pte'; we just use `int'; this is for non-4M only */
                    264: #define        PG_V            0x80000000
                    265: #define        PG_PROT         0x60000000      /* both protection bits */
                    266: #define        PG_W            0x40000000      /* allowed to write */
                    267: #define        PG_S            0x20000000      /* supervisor only */
                    268: #define        PG_NC           0x10000000      /* non-cacheable */
                    269: #define        PG_TYPE         0x0c000000      /* both type bits */
                    270:
                    271: #define        PG_OBMEM        0x00000000      /* on board memory */
                    272: #define        PG_OBIO         0x04000000      /* on board I/O (incl. SBus on 4c) */
                    273: #define        PG_VME16        0x08000000      /* 16-bit-data VME space */
                    274: #define        PG_VME32        0x0c000000      /* 32-bit-data VME space */
                    275: #if defined(SUN4M)
                    276: #define PG_SUN4M_OBMEM 0x0             /* No type bits=>obmem on 4m */
                    277: #define PG_SUN4M_OBIO  0xf             /* obio maps to 0xf on 4M */
                    278: #define SRMMU_PGTYPE   0xf0000000      /* Top 4 bits of pte PPN give type */
                    279: #endif
                    280:
                    281: #define        PG_U            0x02000000
                    282: #define        PG_M            0x01000000
                    283: #define PG_IOC         0x00800000
                    284: #define        PG_MBZ          0x00780000      /* unused; must be zero (oh really?) */
                    285: #define        PG_PFNUM        0x0007ffff      /* n.b.: only 16 bits on sun4c */
                    286:
                    287: #define        PG_TNC_SHIFT    26              /* shift to get PG_TYPE + PG_NC */
                    288: #define        PG_M_SHIFT      24              /* shift to get PG_M, PG_U */
                    289: #define PG_M_SHIFT4M   5               /* shift to get SRMMU_PG_M,R on 4m */
                    290: /*efine        PG_NOACC        0               ** XXX */
                    291: #define        PG_KR           0x20000000
                    292: #define        PG_KW           0x60000000
                    293: #define        PG_URKR         0
                    294: #define        PG_UW           0x40000000
                    295:
                    296: #ifdef KGDB
                    297: /* but we will define one for gdb anyway */
                    298: struct pte {
                    299:        u_int   pg_v:1,
                    300:                pg_w:1,
                    301:                pg_s:1,
                    302:                pg_nc:1;
                    303:        enum pgtype { pg_obmem, pg_obio, pg_vme16, pg_vme32 } pg_type:2;
                    304:        u_int   pg_u:1,
                    305:                pg_m:1,
                    306:                pg_mbz:5,
                    307:                pg_pfnum:19;
                    308: };
                    309: #if defined(SUN4M)
                    310: struct srmmu_pte {
                    311:        u_int   pg_pfnum:20,
                    312:                pg_c:1,
                    313:                pg_m:1,
                    314:                pg_u:1;
                    315:        enum pgprot { pprot_r_r, pprot_rw_rw, pprot_rx_rx, pprot_rwx_rwx,
                    316:                      pprot_x_x, pprot_r_rw, pprot_n_rx, pprot_n_rwx }
                    317:                pg_prot:3;      /* prot. bits: pprot_<user>_<supervisor> */
                    318:        u_int   pg_must_be_2:2;
                    319: };
                    320: #endif
                    321: #endif
                    322:
                    323: /*
                    324:  * These are needed in the register window code
                    325:  * to check the validity of (ostensible) user stack PTEs.
                    326:  */
                    327: #define        PG_VSHIFT       29              /* (va>>vshift)==0 or -1 => valid */
                    328:        /* XXX fix this name, it is a va shift not a pte bit shift! */
                    329:
                    330: #define        PG_PROTSHIFT    29
                    331: #define        PG_PROTUWRITE   6               /* PG_V,PG_W,!PG_S */
                    332: #define        PG_PROTUREAD    4               /* PG_V,!PG_W,!PG_S */
                    333:
                    334: /* %%%: Fix above and below for 4m? */
                    335:
                    336: /* static __inline int PG_VALID(void *va) {
                    337:        register int t = va; t >>= PG_VSHIFT; return (t == 0 || t == -1);
                    338: } */
                    339:
                    340:
                    341: /*
                    342:  * Here are the bit definitions for 4M/SRMMU pte's
                    343:  */
                    344:                /* MMU TABLE ENTRIES */
                    345: #define SRMMU_TEINVALID        0x0             /* invalid (serves as !valid bit) */
                    346: #define        SRMMU_TEPTD     0x1             /* Page Table Descriptor */
                    347: #define SRMMU_TEPTE    0x2             /* Page Table Entry */
                    348: #define SRMMU_TERES    0x3             /* reserved */
                    349: #define SRMMU_TETYPE   0x3             /* mask for table entry type */
                    350:                /* PTE FIELDS */
                    351: #define SRMMU_PPNMASK  0xFFFFFF00
                    352: #define SRMMU_PPNSHIFT 0x8
                    353: #define SRMMU_PPNPASHIFT 0x4           /* shift to put ppn into PAddr */
                    354: #define SRMMU_L1PPNSHFT        0x14
                    355: #define SRMMU_L1PPNMASK        0xFFF00000
                    356: #define SRMMU_L2PPNSHFT 0xE
                    357: #define SRMMU_L2PPNMASK        0xFC000
                    358: #define SRMMU_L3PPNSHFT        0x8
                    359: #define SRMMU_L3PPNMASK 0x3F00
                    360:                /* PTE BITS */
                    361: #define SRMMU_PG_C     0x80            /* cacheable */
                    362: #define SRMMU_PG_M     0x40            /* modified (dirty) */
                    363: #define SRMMU_PG_R     0x20            /* referenced */
                    364: #define SRMMU_PGBITSMSK        0xE0
                    365:                /* PTE PROTECTION */
                    366: #define SRMMU_PROT_MASK        0x1C            /* Mask protection bits out of pte */
                    367: #define SRMMU_PROT_SHFT        0x2
                    368: #define PPROT_R_R      0x0             /* These are in the form:       */
                    369: #define PPROT_RW_RW    0x4             /*      PPROT_<u>_<s>           */
                    370: #define PPROT_RX_RX    0x8             /* where <u> is the user-mode   */
                    371: #define PPROT_RWX_RWX  0xC             /* permission, and <s> is the   */
                    372: #define PPROT_X_X      0x10            /* supervisor mode permission.  */
                    373: #define PPROT_R_RW     0x14            /* R=read, W=write, X=execute   */
                    374: #define PPROT_N_RX     0x18            /* N=none.                      */
                    375: #define PPROT_N_RWX    0x1C
                    376: #define PPROT_WRITE    0x4             /* set iff write priv. allowed  */
                    377: #define PPROT_S                0x18            /* effective S bit */
                    378: #define PPROT_U2S_OMASK 0x18           /* OR with prot. to revoke user priv */
                    379:                /* TABLE SIZES */
                    380: #define SRMMU_L1SIZE   0x100
                    381: #define SRMMU_L2SIZE   0x40
                    382: #define SRMMU_L3SIZE   0x40
                    383:
                    384: /*
                    385:  * IOMMU PTE bits.
                    386:  */
                    387: #define IOPTE_PPN_MASK  0x07ffff00
                    388: #define IOPTE_PPN_SHIFT 8
                    389: #define IOPTE_RSVD      0x000000f1
                    390: #define IOPTE_WRITE     0x00000004
                    391: #define IOPTE_VALID     0x00000002

CVSweb