Annotation of coherent/d/PS2_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:        /*printf("ptov: gp=%lx, paddr=%lx, n=%lx\n", gp, paddr, n); */
                    287: 
                    288:        /*
                    289:         * Disable interrupts.
                    290:         */
                    291:        s = sphi();
                    292: 
                    293:        /*
                    294:         * Set limit.
                    295:         */
                    296:        sfword( gp+0, (unsigned) (n - 1) );
                    297: 
                    298:        /*
                    299:         * Set low word of base, high byte of base.
                    300:         */
                    301:        sfword( gp+2, FP_OFF(paddr) );
                    302:        sfbyte( gp+4, FP_SEL(paddr) );
                    303: 
                    304:        /*
                    305:         * Set access byte: Present[80], Descriptor[10], Writable[02].
                    306:         */
                    307:        sfbyte( gp+5, 0x92 );
                    308: 
                    309:        /*
                    310:         * Clear reserved word.
                    311:         */
                    312:        sfword( gp+6, 0 );
                    313: 
                    314:        /*
                    315:         * Enable interrupts.
                    316:         */
                    317:        spl( s );
                    318: 
                    319:        /*
                    320:         * Return virtual address.
                    321:         */
                    322:        return( fp );
                    323: }
                    324: 
                    325: /**
                    326:  *
                    327:  * faddr_t
                    328:  * ptovx(paddr)        -- physical to virtual [address] for executable segment
                    329:  * paddr_t paddr;
                    330:  *
                    331:  *     Input:  paddr = physical address.
                    332:  *
                    333:  *     Return: Corresponding segment:offset virtual address, or 0.
                    334:  *
                    335:  */
                    336: 
                    337: faddr_t
                    338: ptovx(paddr)
                    339: paddr_t paddr;
                    340: {
                    341:        faddr_t fp;
                    342:        faddr_t gp;
                    343:        int s;
                    344: 
                    345: #if REAL_MODE > 0
                    346:        /*
                    347:         * Virtual Address Mode Disabled.
                    348:         */
                    349:        if ( gdtsel == 0 )
                    350:                return( ((paddr >> 4) << 16) + (paddr % 16) );
                    351: #endif
                    352: 
                    353:        /*
                    354:         * Allocate virtual selector.
                    355:         */
                    356:        if ( (fp = gdtalloc()) == 0 )
                    357:                panic( "ptov:ip=%x: out of gdt's\n", ((char*) &paddr)[-1] );
                    358: 
                    359:        /*
                    360:         * Create far pointer to appropriate gdt entry.
                    361:         */
                    362:        FP_SEL(gp) = gdtsel;
                    363:        FP_OFF(gp) = FP_SEL(fp);
                    364: 
                    365:        /*
                    366:         * Disable interrupts.
                    367:         */
                    368:        s = sphi();
                    369: 
                    370:        /*
                    371:         * Set limit.
                    372:         */
                    373:        sfword( gp+0, (unsigned) (0xffff) );
                    374: 
                    375:        /*
                    376:         * Set low word of base, high byte of base.
                    377:         */
                    378:        sfword( gp+2, FP_OFF(paddr) );
                    379:        sfbyte( gp+4, FP_SEL(paddr) );
                    380: 
                    381:        /*
                    382:         * Set access byte: Present[80], Descriptor[10], Conforming[4]
                    383:         *                  Executable[08], Readable[02].
                    384:         */
                    385:        sfbyte( gp+5, 0x9a );
                    386: 
                    387:        /*
                    388:         * Clear reserved word.
                    389:         */
                    390:        sfword( gp+6, 0 );
                    391: 
                    392:        /*
                    393:         * Enable interrupts.
                    394:         */
                    395:        spl( s );
                    396: 
                    397:        /*
                    398:         * Return virtual address.
                    399:         */
                    400:        return( fp );
                    401: }
                    402: 
                    403: /**
                    404:  *
                    405:  * paddr_t
                    406:  * vtop( fp )                  -- virtual to physical [address]
                    407:  * faddr_t fp;
                    408:  *
                    409:  *     Input:  fp = segment:offset virtual address.
                    410:  *
                    411:  *     Return:  * = corresponding physical address.
                    412:  *             -1 = invalid virtual address.
                    413:  */
                    414: paddr_t
                    415: vtop( fp )
                    416: faddr_t fp;
                    417: {
                    418:        faddr_t gp;
                    419:        paddr_t paddr;
                    420: 
                    421: #if REAL_MODE > 0
                    422:        /*
                    423:         * Virtual Address Mode Disabled.
                    424:         */
                    425:        if ( gdtsel == 0 )
                    426:                return( (FP_SEL(fp) << 4L) + FP_OFF(fp) );
                    427: #endif
                    428: 
                    429:        /*
                    430:         * Convert virtual address to point to appropriate gdt entry.
                    431:         */
                    432:        FP_SEL(gp) = gdtsel;
                    433:        FP_OFF(gp) = FP_SEL(fp);
                    434: 
                    435:        /*
                    436:         * Validity check - Selector must be Present[80] and Descriptor[10].
                    437:         */
                    438:        if ( (ffbyte(gp+5) & 0x90) != 0x90 ) {
                    439:                panic( "vtop:ip=%x: sel %x invalid\n",
                    440:                        ((char **) &fp)[-1],
                    441:                        FP_SEL(fp) );
                    442:        }
                    443: 
                    444:        /*
                    445:         * Extract physical address from gdt entry.
                    446:         */
                    447:        FP_OFF(paddr) = ffword(gp+2);
                    448:        FP_SEL(paddr) = ffbyte(gp+4);
                    449: 
                    450:        /*
                    451:         * Adjust physical address by virtual address offset.
                    452:         */
                    453:        paddr += FP_OFF(fp);
                    454: 
                    455:        /*
                    456:         * Return physical address.
                    457:         */
                    458:        return( paddr );
                    459: }
                    460: 
                    461: /**
                    462:  *
                    463:  * void
                    464:  * vrelse( fp )                -- release virtual address
                    465:  * faddr_t fp;
                    466:  *
                    467:  */
                    468: 
                    469: void
                    470: vrelse( fp )
                    471: faddr_t fp;
                    472: {
                    473:        faddr_t gp;
                    474: 
                    475: #if REAL_MODE > 0
                    476:        /*
                    477:         * Virtual Address Mode Disabled.
                    478:         */
                    479:        if ( gdtsel == 0 )
                    480:                return;
                    481: #endif
                    482: 
                    483:        /*
                    484:         * Validity check.
                    485:         */
                    486:        if ( (FP_SEL(fp) == 0) || (FP_SEL(fp) & 7) )
                    487:                panic( "vrelse: sel %x invalid\n", FP_SEL(fp) );
                    488: 
                    489:        /*
                    490:         * Construct virtual address to point to appropriate gdt entry.
                    491:         */
                    492:        FP_SEL(gp) = gdtsel;
                    493:        FP_OFF(gp) = FP_SEL(fp);
                    494: 
                    495:        /*
                    496:         * Virtual selector already released, or not a segment descriptor.
                    497:         */
                    498:        if ( (ffbyte(gp+5) & 0x10) != 0x10 ) {
                    499:                panic( "vrelse:ip=%x: sel %x already released\n",
                    500:                        ((char **) &fp)[-1],
                    501:                        FP_SEL(fp) );
                    502:        }
                    503: 
                    504:        /*
                    505:         * Release virtual selector.
                    506:         */
                    507:        sfbyte( gp+5, 0 );
                    508: }

unix.superglobalmegacorp.com

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