Annotation of XNU/osfmk/ppc/bat_init.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: #include <mach/std_types.h>
        !            23: #include <ppc/proc_reg.h>
        !            24: #include <ppc/boot.h>
        !            25: #include <ppc/mem.h>
        !            26: 
        !            27: #ifdef XXX_LOADER
        !            28: unsigned int kernel_seg_regs[] = {
        !            29:   KERNEL_SEG_REG0_VALUE,
        !            30:   KERNEL_SEG_REG1_VALUE,
        !            31:   SEG_REG_INVALID, /* 2 */
        !            32:   SEG_REG_INVALID, /* 3 */
        !            33:   SEG_REG_INVALID, /* 4 */
        !            34:   KERNEL_SEG_REG5_VALUE, /* 5 - I/O segment */
        !            35:   SEG_REG_INVALID, /* 6 */
        !            36:   SEG_REG_INVALID, /* 7 */
        !            37:   KERNEL_SEG_REG8_VALUE, /* 8-F are possible IO space */
        !            38:   KERNEL_SEG_REG9_VALUE,
        !            39:   KERNEL_SEG_REG10_VALUE,
        !            40:   KERNEL_SEG_REG11_VALUE,
        !            41:   KERNEL_SEG_REG12_VALUE,
        !            42:   KERNEL_SEG_REG13_VALUE,
        !            43:   KERNEL_SEG_REG14_VALUE, /* 14 - A/V video */
        !            44:   KERNEL_SEG_REG15_VALUE /* 15 - NuBus etc */
        !            45: };
        !            46: #else
        !            47: extern unsigned int kernel_seg_regs[];
        !            48: #endif
        !            49: 
        !            50: // The sophisticated BAT manager
        !            51: 
        !            52: unsigned int mappedSegments = 0;
        !            53: unsigned int availableBATs = 0xE;              // BAT0 used, 1-3 available
        !            54: 
        !            55: vm_offset_t
        !            56: PEResidentAddress( vm_offset_t address, vm_size_t length )
        !            57: {
        !            58:     if( mappedSegments & (1 << (15 & (address >> 28))))
        !            59:        return( address);
        !            60:     else
        !            61:        return( 0);
        !            62: }
        !            63: 
        !            64: vm_offset_t
        !            65: PEMapSegment( vm_offset_t address, vm_size_t length )
        !            66: {
        !            67:     vm_offset_t                retAddress;
        !            68:     bat_t              bat;
        !            69:     int                        batNum;
        !            70: 
        !            71:     retAddress = PEResidentAddress( address, length );
        !            72:     if( retAddress)
        !            73:        return( retAddress);
        !            74: 
        !            75:     if( length < (256 * 1024))
        !            76:        return( 0);
        !            77:     if( availableBATs == 0)
        !            78:        return( 0);
        !            79: 
        !            80:     for( batNum = 0;
        !            81:         (0 == (availableBATs & (1 << batNum)));
        !            82:         batNum++);
        !            83: 
        !            84:     bat.upper.word          = address & 0xf0000000;
        !            85:     bat.lower.word          = bat.upper.word;
        !            86: 
        !            87:     bat.upper.bits.bl    = 0x7ff;      /* size = 256M */
        !            88:     bat.upper.bits.vs    = 1;
        !            89:     bat.upper.bits.vp    = 0;          /* user disabled */
        !            90: 
        !            91:     bat.lower.bits.wimg  = PTE_WIMG_IO;
        !            92:     bat.lower.bits.pp    = 2;          /* read/write access */
        !            93:     
        !            94:     // Update the shadow bats.
        !            95:     shadow_BAT.DBATs[batNum].upper = bat.upper.word;
        !            96:     shadow_BAT.DBATs[batNum].lower = bat.lower.word;
        !            97:     
        !            98:     sync();isync();
        !            99:     switch( batNum) {                  // !%$@!! mtdbat needs literal
        !           100:        case 0:
        !           101:            mtdbatu( 0, BAT_INVALID);   /* invalidate old mapping */
        !           102:            mtdbatl( 0, bat.lower.word);
        !           103:            mtdbatu( 0, bat.upper.word);
        !           104:            break;
        !           105:        case 1:
        !           106:            mtdbatu( 1, BAT_INVALID);
        !           107:            mtdbatl( 1, bat.lower.word);
        !           108:            mtdbatu( 1, bat.upper.word);
        !           109:            break;
        !           110:        case 2:
        !           111:            mtdbatu( 2, BAT_INVALID);
        !           112:            mtdbatl( 2, bat.lower.word);
        !           113:            mtdbatu( 2, bat.upper.word);
        !           114:            break;
        !           115:        case 3:
        !           116:            mtdbatu( 3, BAT_INVALID);
        !           117:            mtdbatl( 3, bat.lower.word);
        !           118:            mtdbatu( 3, bat.upper.word);
        !           119:            break;
        !           120:     }
        !           121:     sync();isync();
        !           122: 
        !           123:     availableBATs &= ~(1 << batNum);
        !           124:     mappedSegments |= (1 << (15 & (address >> 28)));
        !           125: 
        !           126:     return( address);
        !           127: }
        !           128: 
        !           129: void initialize_bats(boot_args *args)
        !           130: {
        !           131:        int i;
        !           132: 
        !           133:        /* Give ourselves the virtual map that we would like */
        !           134:        bat_t                 bat;
        !           135: 
        !           136:        /* Make sure that the BATs map what we expect. Note
        !           137:         * that we assume BAT0 maps kernel text & data.
        !           138:         *
        !           139:         * Except, oops, none of the BATs have ever been set.
        !           140:         * Developer worked only by fluke.
        !           141:         */
        !           142: 
        !           143:        bat.upper.word       = 0;
        !           144:        bat.upper.bits.bepi  = 0x0;     /* start at logical addr 0M */
        !           145:        /*
        !           146:         * We should be smarter here about picking an
        !           147:         * amount to map
        !           148:         */
        !           149:        bat.upper.bits.bl    = 0x7ff;   /* size = 256M */
        !           150:        bat.upper.bits.vs    = 1;
        !           151:        bat.upper.bits.vp    = 0;
        !           152: 
        !           153:        bat.lower.word       = 0;
        !           154:        bat.lower.bits.brpn  = 0x0;     /* start at physical addr 0 */
        !           155:        bat.lower.bits.wimg  = PTE_WIMG_DEFAULT;
        !           156:        bat.lower.bits.pp    = 2;       /* read/write access */
        !           157: 
        !           158:        /* Mustn't cause any data traffic here,
        !           159:         * we're modifying our data BAT register!
        !           160:         */
        !           161: 
        !           162:        sync();
        !           163:        mtdbatu(0, BAT_INVALID);        /* invalidate old mapping */
        !           164:        isync();
        !           165:        mtdbatl(0, bat.lower.word);
        !           166:        isync();
        !           167:        mtdbatu(0, bat.upper.word);     /* update with new mapping */
        !           168:        isync();
        !           169:        mtibatl(0, bat.lower.word);
        !           170:        isync();
        !           171:        mtibatu(0, bat.upper.word);     /* update with new mapping */
        !           172:        isync();
        !           173: 
        !           174:        sync();isync();
        !           175:        mtdbatu(1,BAT_INVALID); mtdbatl(1,BAT_INVALID);
        !           176:        mtibatu(1,BAT_INVALID); mtibatl(1,BAT_INVALID);
        !           177:        mtdbatu(2,BAT_INVALID); mtdbatl(2,BAT_INVALID);
        !           178:        mtibatu(2,BAT_INVALID); mtibatl(2,BAT_INVALID);
        !           179:        mtdbatu(3,BAT_INVALID); mtdbatl(3,BAT_INVALID);
        !           180:        mtibatu(3,BAT_INVALID); mtibatl(3,BAT_INVALID);
        !           181:        sync();isync();
        !           182: 
        !           183:        PEMapSegment( 0xf0000000, 0x10000000);
        !           184:        if( args->Video.v_baseAddr)
        !           185:          PEMapSegment( args->Video.v_baseAddr, 0x10000000);
        !           186: 
        !           187:        /* Set up segment registers as VM through space 0 */
        !           188:        isync();
        !           189:        for (i=0; i<=15; i++) {
        !           190:          mtsrin(KERNEL_SEG_REG0_VALUE | i, i * 0x10000000);
        !           191:        }
        !           192:        isync();
        !           193: }
        !           194: 
        !           195: /*
        !           196:  * Adjust the size of the region mapped by a BAT
        !           197:  * to to be just large enough to include the specified
        !           198:  * offset, and return the offset of the new end of the region.
        !           199:  * Note that both 'offsets' are really *lengths*, i.e. the
        !           200:  * offset of the end of the mapped region from the beginning.
        !           201:  * Either the instruction or data BATs (or both) can be specified.
        !           202:  * If the new length is greater than the size mappable by a BAT,
        !           203:  * then that value is just returned and no changes are made.
        !           204:  */
        !           205: vm_offset_t
        !           206: adjust_bat_limit(
        !           207:     vm_offset_t                new_minimum,
        !           208:     int                        batn,
        !           209:     boolean_t          ibat,
        !           210:     boolean_t          dbat
        !           211: )
        !           212: {
        !           213:     vm_offset_t                new_limit;
        !           214: 
        !           215:     if (new_minimum <= 256*1024*1024) {
        !           216:        unsigned int    bl = 0;
        !           217: 
        !           218:        new_limit = 128*1024;
        !           219:        while (new_limit < new_minimum) {
        !           220:            new_limit *= 2;
        !           221:            bl = (bl << 1) | 1;
        !           222:        }
        !           223: 
        !           224:        {
        !           225:            batu_t      batu;
        !           226: 
        !           227:            if (dbat) switch (batn) {
        !           228: 
        !           229:            case 0:
        !           230:                mfdbatu(batu, 0 );
        !           231:                batu.bits.bl = bl;
        !           232: 
        !           233:                sync(); isync();
        !           234:                mtdbatu( 0, batu);
        !           235:                sync(); isync();
        !           236: 
        !           237:                break;
        !           238: 
        !           239:            case 1:
        !           240:                mfdbatu(batu, 1 );
        !           241:                batu.bits.bl = bl;
        !           242: 
        !           243:                sync(); isync();
        !           244:                mtdbatu( 1, batu);
        !           245:                sync(); isync();
        !           246: 
        !           247:                break;
        !           248: 
        !           249:            case 2:
        !           250:                mfdbatu(batu, 2 );
        !           251:                batu.bits.bl = bl;
        !           252: 
        !           253:                sync(); isync();
        !           254:                mtdbatu( 2, batu);
        !           255:                sync(); isync();
        !           256: 
        !           257:                break;
        !           258: 
        !           259:            case 3:
        !           260:                mfdbatu(batu, 3 );
        !           261:                batu.bits.bl = bl;
        !           262: 
        !           263:                sync(); isync();
        !           264:                mtdbatu( 3, batu);
        !           265:                sync(); isync();
        !           266: 
        !           267:                break;
        !           268:            }
        !           269: 
        !           270:            if (ibat) switch (batn) {
        !           271: 
        !           272:            case 0:
        !           273:                mfibatu(batu, 0 );
        !           274:                batu.bits.bl = bl;
        !           275: 
        !           276:                sync(); isync();
        !           277:                mtibatu( 0, batu);
        !           278:                sync(); isync();
        !           279: 
        !           280:                break;
        !           281: 
        !           282:            case 1:
        !           283:                mfibatu(batu, 1 );
        !           284:                batu.bits.bl = bl;
        !           285: 
        !           286:                sync(); isync();
        !           287:                mtibatu( 1, batu);
        !           288:                sync(); isync();
        !           289: 
        !           290:                break;
        !           291: 
        !           292:            case 2:
        !           293:                mfibatu(batu, 2 );
        !           294:                batu.bits.bl = bl;
        !           295: 
        !           296:                sync(); isync();
        !           297:                mtibatu( 2, batu);
        !           298:                sync(); isync();
        !           299: 
        !           300:                break;
        !           301: 
        !           302:            case 3:
        !           303:                mfibatu(batu, 3 );
        !           304:                batu.bits.bl = bl;
        !           305: 
        !           306:                sync(); isync();
        !           307:                mtibatu( 3, batu);
        !           308:                sync(); isync();
        !           309: 
        !           310:                break;
        !           311:            }
        !           312:        }
        !           313:     }
        !           314:     else
        !           315:        new_limit = new_minimum;
        !           316: 
        !           317:     return (new_limit);
        !           318: }

unix.superglobalmegacorp.com

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