Annotation of coherent/d/286_KERNEL/USRSRC/286/mmu.c, revision 1.1.1.1

1.1       root        1: /* $Header: /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v 1.1 88/03/24 17:33:41 src Exp $
                      2:  *
                      3:  *     The  information  contained herein  is a trade secret  of INETCO
                      4:  *     Systems, and is confidential information.   It is provided under
                      5:  *     a license agreement,  and may be copied or disclosed  only under
                      6:  *     the terms of that agreement.   Any reproduction or disclosure of
                      7:  *     this  material  without  the express  written  authorization  of
                      8:  *     INETCO Systems or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     Copyright (c) 1987
                     11:  *     An unpublished work by INETCO Systems, Ltd.
                     12:  *     All rights reserved.
                     13:  */
                     14: 
                     15: /*
                     16:  * Coherent.
                     17:  * Memory Management Unit.
                     18:  *
                     19:  * $Log:       /usr/src/sys/i8086/ibm_at/RCS/mmu.c,v $
                     20:  * Revision 1.1        88/03/24  17:33:41      src
                     21:  * Initial revision
                     22:  * 
                     23:  * 88/03/04    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
                     24:  * Real-mode code ifdef'ed out [REAL_MODE].
                     25:  *
                     26:  * 88/02/16    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
                     27:  * vtop() now incorporates offset from virtual address into physical address.
                     28:  *
                     29:  * 87/11/13    Allan Cornish   /usr/src/sys/i8086/ibm_at/mmu.c
                     30:  * Initial version.
                     31:  */
                     32: #include <sys/coherent.h>
                     33: #include <sys/seg.h>
                     34: #include <sys/mmu.h>
                     35: 
                     36: /**
                     37:  *
                     38:  * static faddr_t
                     39:  * gdtalloc()          -- search for empty global descriptor table entry
                     40:  */
                     41: static faddr_t
                     42: gdtalloc()
                     43: {
                     44:        register saddr_t sel;
                     45:        static saddr_t osel;
                     46:        faddr_t fp;
                     47:        int s;
                     48: 
                     49:        /*
                     50:         * Disable interrupts.
                     51:         */
                     52:        s = sphi();
                     53: 
                     54:        /*
                     55:         * Search for idle virtual selector.
                     56:         */
                     57:        for ( fp = 0, sel = osel + 8; sel != osel; sel += 8 ) {
                     58: 
                     59:                /*
                     60:                 * Selector 0 is NOT usable.
                     61:                 */
                     62:                if ( sel == 0 )
                     63:                        continue;
                     64: 
                     65:                /*
                     66:                 * Selector is available.
                     67:                 */
                     68:                if ( ffbyte( sel+5, gdtsel ) != 0 )
                     69:                        continue;
                     70: 
                     71:                /*
                     72:                 * Mark selector as being Descriptor[10].
                     73:                 */
                     74:                sfbyte( sel+5, gdtsel, 0x10 );
                     75: 
                     76:                /*
                     77:                 * Record selector for next search.
                     78:                 */
                     79:                osel = sel;
                     80: 
                     81:                FP_SEL(fp) = sel;
                     82:                break;
                     83:        }
                     84: 
                     85:        /*
                     86:         * Enable interrupts.
                     87:         */
                     88:        spl( s );
                     89: 
                     90:        return( fp );
                     91: }
                     92: 
                     93: /**
                     94:  *
                     95:  * void
                     96:  * vprint( fp )                        -- print virtual address information.
                     97:  * faddr_t fp;
                     98:  *
                     99:  *     Input:  fp = segment:offset pair for virtual address in question.
                    100:  *
                    101:  *     Action: Print information about virtual address.
                    102:  */
                    103: 
                    104: void
                    105: vprint( fp )
                    106: faddr_t fp;
                    107: {
                    108:        faddr_t gp;
                    109:        paddr_t paddr;
                    110: 
                    111: #if REAL_MODE > 0
                    112:        /*
                    113:         * Virtual Address Mode Disabled.
                    114:         */
                    115:        if ( gdtsel == 0 )
                    116:                return;
                    117: #endif
                    118: 
                    119:        /*
                    120:         * Create far pointer to appropriate gdt entry.
                    121:         */
                    122:        FP_SEL(gp) = gdtsel;
                    123:        FP_OFF(gp) = FP_SEL(fp) & ~7;
                    124: 
                    125:        FP_OFF(paddr) = ffword(gp+2);
                    126:        FP_SEL(paddr) = ffbyte(gp+4);
                    127: 
                    128:        /*
                    129:         * Print information about gdt entry.
                    130:         */
                    131:        printf("sel=%x paddr=%X lim=%x flags=%x\n",
                    132:                FP_OFF(gp), paddr, ffword(gp), ffbyte(gp+5) );
                    133: }
                    134: 
                    135: /**
                    136:  *
                    137:  * void
                    138:  * vremap( sp )                        -- (re)map segment virtual address
                    139:  * SEG * sp;
                    140:  *
                    141:  *     Input:  sp = pointer to segment structure to be (re)mapped.
                    142:  *
                    143:  *     Action: Update segment information.
                    144:  */
                    145: void
                    146: vremap( segp )
                    147: SEG * segp;
                    148: {
                    149:        register SEG * sp = segp;
                    150:        register int m;
                    151:        faddr_t gp;
                    152:        int s;
                    153: 
                    154: #if REAL_MODE > 0
                    155:        /*
                    156:         * Virtual Address Mode disabled.
                    157:         */
                    158:        if ( gdtsel == 0 ) {
                    159:                /*
                    160:                 * Calculate virtual address as shifted physical address.
                    161:                 */
                    162:                FP_SEL(sp->s_faddr) = sp->s_paddr >> 4;
                    163:                FP_OFF(sp->s_faddr) = sp->s_paddr & 15;
                    164:                return;
                    165:        }
                    166: #endif
                    167: 
                    168:        /*
                    169:         * Create far pointer to appropriate gdt entry.
                    170:         */
                    171:        FP_SEL(gp) = gdtsel;
                    172:        FP_OFF(gp) = FP_SEL(sp->s_faddr);
                    173: 
                    174:        /*
                    175:         * Allocate virtual selector if not already specified.
                    176:         */
                    177:        if ( FP_SEL(sp->s_faddr) == 0 )  {
                    178:                if ( (sp->s_faddr = gdtalloc()) == 0 )
                    179:                        panic( "vremap: out of gdt's\n" );
                    180:                FP_OFF(gp) = FP_SEL(sp->s_faddr);
                    181:        }
                    182: 
                    183:        /*
                    184:         * Ensure selector is valid gdt at privilege level 0.
                    185:         */
                    186:        if ( FP_SEL(sp->s_faddr) & 7 ) {
                    187:                panic("vremap( faddr=%X, ip=%x ) - not gdt at level 0\n",
                    188:                        sp->s_faddr, (&segp)[-1] );
                    189:        }
                    190: 
                    191:        /*
                    192:         * Verify selector is not free.
                    193:         */
                    194:        if ( ffbyte( gp+5 ) == 0 ) {
                    195:                panic("vremap( faddr=%X, ip=%x ) - selector is free\n",
                    196:                        sp->s_faddr, (&segp)[-1] );
                    197:        }
                    198: 
                    199:        /*
                    200:         * Disable interrupts.
                    201:         */
                    202:        s = sphi();
                    203: 
                    204:        /*
                    205:         * Set limit.
                    206:         */
                    207:        sfword( gp+0, (unsigned) (sp->s_size - 1) );
                    208: 
                    209:        /*
                    210:         * Set low word of base, high byte of base.
                    211:         */
                    212:        sfword( gp+2, FP_OFF(sp->s_paddr) );
                    213:        sfbyte( gp+4, FP_SEL(sp->s_paddr) );
                    214: 
                    215:        /*
                    216:         * Set access byte:
                    217:         *      Code = Present[80],Descriptor[10],Executable[08],Readable[02].
                    218:         *      Data = Present[80],Descriptor[10],               Writable[02].
                    219:         */
                    220:        m = 0x12;
                    221:        if ( sp->s_flags & SFCORE )
                    222:                m |= 0x80;
                    223:        if ( sp->s_flags & SFTEXT )
                    224:                m |= 0x08;
                    225:        sfbyte( gp+5, m );
                    226: 
                    227:        /*
                    228:         * Clear reserved word.
                    229:         */
                    230:        sfword( gp+6, 0 );
                    231: 
                    232:        /*
                    233:         * Enable interrupts.
                    234:         */
                    235:        spl(s);
                    236: }
                    237: 
                    238: /**
                    239:  *
                    240:  * faddr_t
                    241:  * ptov( paddr, n )            -- physical to virtual [address]
                    242:  * paddr_t paddr;
                    243:  * fsize_t n;
                    244:  *
                    245:  *     Input:  paddr = physical address.
                    246:  *             n = size in bytes.
                    247:  *
                    248:  *     Return: Corresponding segment:offset virtual address, or 0.
                    249:  *
                    250:  *     Notes:  Limited to 20 bit physical addresses.
                    251:  *             This routine is not functional in protected mode.
                    252:  */
                    253: 
                    254: faddr_t
                    255: ptov( paddr, n )
                    256: paddr_t paddr;
                    257: fsize_t n;
                    258: {
                    259:        faddr_t fp;
                    260:        faddr_t gp;
                    261:        int s;
                    262: 
                    263: #if REAL_MODE > 0
                    264:        /*
                    265:         * Virtual Address Mode Disabled.
                    266:         */
                    267:        if ( gdtsel == 0 )
                    268:                return( ((paddr >> 4) << 16) + (paddr % 16) );
                    269: #endif
                    270: 
                    271:        /*
                    272:         * Allocate virtual selector.
                    273:         */
                    274:        if ( (fp = gdtalloc()) == 0 )
                    275:                panic( "ptov:ip=%x: out of gdt's\n", ((char*) &paddr)[-1] );
                    276: 
                    277:        /*
                    278:         * Create far pointer to appropriate gdt entry.
                    279:         */
                    280:        FP_SEL(gp) = gdtsel;
                    281:        FP_OFF(gp) = FP_SEL(fp);
                    282: 
                    283:        /*
                    284:         * Disable interrupts.
                    285:         */
                    286:        s = sphi();
                    287: 
                    288:        /*
                    289:         * Set limit.
                    290:         */
                    291:        sfword( gp+0, (unsigned) (n - 1) );
                    292: 
                    293:        /*
                    294:         * Set low word of base, high byte of base.
                    295:         */
                    296:        sfword( gp+2, FP_OFF(paddr) );
                    297:        sfbyte( gp+4, FP_SEL(paddr) );
                    298: 
                    299:        /*
                    300:         * Set access byte: Present[80], Descriptor[10], Writable[02].
                    301:         */
                    302:        sfbyte( gp+5, 0x92 );
                    303: 
                    304:        /*
                    305:         * Clear reserved word.
                    306:         */
                    307:        sfword( gp+6, 0 );
                    308: 
                    309:        /*
                    310:         * Enable interrupts.
                    311:         */
                    312:        spl( s );
                    313: 
                    314:        /*
                    315:         * Return virtual address.
                    316:         */
                    317:        return( fp );
                    318: }
                    319: 
                    320: /**
                    321:  *
                    322:  * paddr_t
                    323:  * vtop( fp )                  -- virtual to physical [address]
                    324:  * faddr_t fp;
                    325:  *
                    326:  *     Input:  fp = segment:offset virtual address.
                    327:  *
                    328:  *     Return:  * = corresponding physical address.
                    329:  *             -1 = invalid virtual address.
                    330:  */
                    331: paddr_t
                    332: vtop( fp )
                    333: faddr_t fp;
                    334: {
                    335:        faddr_t gp;
                    336:        paddr_t paddr;
                    337: 
                    338: #if REAL_MODE > 0
                    339:        /*
                    340:         * Virtual Address Mode Disabled.
                    341:         */
                    342:        if ( gdtsel == 0 )
                    343:                return( (FP_SEL(fp) << 4L) + FP_OFF(fp) );
                    344: #endif
                    345: 
                    346:        /*
                    347:         * Convert virtual address to point to appropriate gdt entry.
                    348:         */
                    349:        FP_SEL(gp) = gdtsel;
                    350:        FP_OFF(gp) = FP_SEL(fp);
                    351: 
                    352:        /*
                    353:         * Validity check - Selector must be Present[80] and Descriptor[10].
                    354:         */
                    355:        if ( (ffbyte(gp+5) & 0x90) != 0x90 ) {
                    356:                panic( "vtop:ip=%x: sel %x invalid\n",
                    357:                        ((char **) &fp)[-1],
                    358:                        FP_SEL(fp) );
                    359:        }
                    360: 
                    361:        /*
                    362:         * Extract physical address from gdt entry.
                    363:         */
                    364:        FP_OFF(paddr) = ffword(gp+2);
                    365:        FP_SEL(paddr) = ffbyte(gp+4);
                    366: 
                    367:        /*
                    368:         * Adjust physical address by virtual address offset.
                    369:         */
                    370:        paddr += FP_OFF(fp);
                    371: 
                    372:        /*
                    373:         * Return physical address.
                    374:         */
                    375:        return( paddr );
                    376: }
                    377: 
                    378: /**
                    379:  *
                    380:  * void
                    381:  * vrelse( fp )                -- release virtual address
                    382:  * faddr_t fp;
                    383:  *
                    384:  */
                    385: 
                    386: void
                    387: vrelse( fp )
                    388: faddr_t fp;
                    389: {
                    390:        faddr_t gp;
                    391: 
                    392: #if REAL_MODE > 0
                    393:        /*
                    394:         * Virtual Address Mode Disabled.
                    395:         */
                    396:        if ( gdtsel == 0 )
                    397:                return;
                    398: #endif
                    399: 
                    400:        /*
                    401:         * Validity check.
                    402:         */
                    403:        if ( (FP_SEL(fp) == 0) || (FP_SEL(fp) & 7) )
                    404:                panic( "vrelse: sel %x invalid\n", FP_SEL(fp) );
                    405: 
                    406:        /*
                    407:         * Construct virtual address to point to appropriate gdt entry.
                    408:         */
                    409:        FP_SEL(gp) = gdtsel;
                    410:        FP_OFF(gp) = FP_SEL(fp);
                    411: 
                    412:        /*
                    413:         * Virtual selector already released, or not a segment descriptor.
                    414:         */
                    415:        if ( (ffbyte(gp+5) & 0x10) != 0x10 ) {
                    416:                panic( "vrelse:ip=%x: sel %x already released\n",
                    417:                        ((char **) &fp)[-1],
                    418:                        FP_SEL(fp) );
                    419:        }
                    420: 
                    421:        /*
                    422:         * Release virtual selector.
                    423:         */
                    424:        sfbyte( gp+5, 0 );
                    425: }

unix.superglobalmegacorp.com

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