Annotation of coherent/b/kernel/i286/mmu.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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