The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/ppc/bat_init.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 // The sophisticated BAT manager
   28 
   29 unsigned int mappedSegments = 0;
   30 unsigned int availableBATs = 0xE;               // BAT0 used, 1-3 available
   31 
   32 vm_offset_t
   33 PEResidentAddress( vm_offset_t address, vm_size_t length )
   34 {
   35     if( mappedSegments & (1 << (15 & (address >> 28))))
   36         return( address);
   37     else
   38         return( 0);
   39 }
   40 
   41 vm_offset_t
   42 PEMapSegment( vm_offset_t address, vm_size_t length )
   43 {
   44     vm_offset_t         retAddress;
   45     bat_t               bat;
   46     int                 batNum;
   47 
   48     retAddress = PEResidentAddress( address, length );
   49     if( retAddress)
   50         return( retAddress);
   51 
   52     if( length < (256 * 1024))
   53         return( 0);
   54     if( availableBATs == 0)
   55         return( 0);
   56 
   57     for( batNum = 0;
   58          (0 == (availableBATs & (1 << batNum)));
   59          batNum++);
   60 
   61     bat.upper.word           = address & 0xf0000000;
   62     bat.lower.word           = bat.upper.word;
   63 
   64     bat.upper.bits.bl    = 0x7ff;       /* size = 256M */
   65     bat.upper.bits.vs    = 1;
   66     bat.upper.bits.vp    = 0;           /* user disabled */
   67 
   68     bat.lower.bits.wimg  = PTE_WIMG_IO;
   69     bat.lower.bits.pp    = 2;           /* read/write access */
   70     
   71     // Update the shadow bats.
   72     shadow_BAT.DBATs[batNum].upper = bat.upper.word;
   73     shadow_BAT.DBATs[batNum].lower = bat.lower.word;
   74     
   75     sync();isync();
   76     switch( batNum) {                   // !%$@!! mtdbat needs literal
   77         case 0:
   78             mtdbatu( 0, BAT_INVALID);   /* invalidate old mapping */
   79             mtdbatl( 0, bat.lower.word);
   80             mtdbatu( 0, bat.upper.word);
   81             break;
   82         case 1:
   83             mtdbatu( 1, BAT_INVALID);
   84             mtdbatl( 1, bat.lower.word);
   85             mtdbatu( 1, bat.upper.word);
   86             break;
   87         case 2:
   88             mtdbatu( 2, BAT_INVALID);
   89             mtdbatl( 2, bat.lower.word);
   90             mtdbatu( 2, bat.upper.word);
   91             break;
   92         case 3:
   93             mtdbatu( 3, BAT_INVALID);
   94             mtdbatl( 3, bat.lower.word);
   95             mtdbatu( 3, bat.upper.word);
   96             break;
   97     }
   98     sync();isync();
   99 
  100     availableBATs &= ~(1 << batNum);
  101     mappedSegments |= (1 << (15 & (address >> 28)));
  102 
  103     return( address);
  104 }
  105 
  106 void initialize_bats(boot_args *args)
  107 {
  108         int i;
  109 
  110         /* Give ourselves the virtual map that we would like */
  111         bat_t                 bat;
  112 
  113         /* Make sure that the BATs map what we expect. Note
  114          * that we assume BAT0 maps kernel text & data.
  115          *
  116          * Except, oops, none of the BATs have ever been set.
  117          * Developer worked only by fluke.
  118          */
  119 
  120         bat.upper.word       = 0;
  121         bat.upper.bits.bepi  = 0x0;     /* start at logical addr 0M */
  122         /*
  123          * We should be smarter here about picking an
  124          * amount to map
  125          */
  126         bat.upper.bits.bl    = 0x7ff;   /* size = 256M */
  127         bat.upper.bits.vs    = 1;
  128         bat.upper.bits.vp    = 0;
  129 
  130         bat.lower.word       = 0;
  131         bat.lower.bits.brpn  = 0x0;     /* start at physical addr 0 */
  132         bat.lower.bits.wimg  = PTE_WIMG_DEFAULT;
  133         bat.lower.bits.pp    = 2;       /* read/write access */
  134 
  135         /* Mustn't cause any data traffic here,
  136          * we're modifying our data BAT register!
  137          */
  138 
  139         sync();
  140         mtdbatu(0, BAT_INVALID);        /* invalidate old mapping */
  141         isync();
  142         mtdbatl(0, bat.lower.word);
  143         isync();
  144         mtdbatu(0, bat.upper.word);     /* update with new mapping */
  145         isync();
  146         mtibatl(0, bat.lower.word);
  147         isync();
  148         mtibatu(0, bat.upper.word);     /* update with new mapping */
  149         isync();
  150 
  151         sync();isync();
  152         mtdbatu(1,BAT_INVALID); mtdbatl(1,BAT_INVALID);
  153         mtibatu(1,BAT_INVALID); mtibatl(1,BAT_INVALID);
  154         mtdbatu(2,BAT_INVALID); mtdbatl(2,BAT_INVALID);
  155         mtibatu(2,BAT_INVALID); mtibatl(2,BAT_INVALID);
  156         mtdbatu(3,BAT_INVALID); mtdbatl(3,BAT_INVALID);
  157         mtibatu(3,BAT_INVALID); mtibatl(3,BAT_INVALID);
  158         sync();isync();
  159 
  160         PEMapSegment( 0xf0000000, 0x10000000);
  161         if( args->Video.v_baseAddr)
  162           PEMapSegment( args->Video.v_baseAddr, 0x10000000);
  163 
  164         /* Set up segment registers as VM through space 0 */
  165         isync();
  166         for (i=0; i<=15; i++) {
  167           mtsrin(KERNEL_SEG_REG0_VALUE | i, i * 0x10000000);
  168         }
  169         isync();
  170 }
  171 
  172 /*
  173  * Adjust the size of the region mapped by a BAT
  174  * to to be just large enough to include the specified
  175  * offset, and return the offset of the new end of the region.
  176  * Note that both 'offsets' are really *lengths*, i.e. the
  177  * offset of the end of the mapped region from the beginning.
  178  * Either the instruction or data BATs (or both) can be specified.
  179  * If the new length is greater than the size mappable by a BAT,
  180  * then that value is just returned and no changes are made.
  181  */
  182 vm_offset_t
  183 adjust_bat_limit(
  184     vm_offset_t         new_minimum,
  185     int                 batn,
  186     boolean_t           ibat,
  187     boolean_t           dbat
  188 )
  189 {
  190     vm_offset_t         new_limit;
  191 
  192     if (new_minimum <= 256*1024*1024) {
  193         unsigned int    bl = 0;
  194 
  195         new_limit = 128*1024;
  196         while (new_limit < new_minimum) {
  197             new_limit *= 2;
  198             bl = (bl << 1) | 1;
  199         }
  200 
  201         {
  202             batu_t      batu;
  203 
  204             if (dbat) switch (batn) {
  205 
  206             case 0:
  207                 mfdbatu(batu, 0 );
  208                 batu.bits.bl = bl;
  209 
  210                 sync(); isync();
  211                 mtdbatu( 0, batu);
  212                 sync(); isync();
  213 
  214                 break;
  215 
  216             case 1:
  217                 mfdbatu(batu, 1 );
  218                 batu.bits.bl = bl;
  219 
  220                 sync(); isync();
  221                 mtdbatu( 1, batu);
  222                 sync(); isync();
  223 
  224                 break;
  225 
  226             case 2:
  227                 mfdbatu(batu, 2 );
  228                 batu.bits.bl = bl;
  229 
  230                 sync(); isync();
  231                 mtdbatu( 2, batu);
  232                 sync(); isync();
  233 
  234                 break;
  235 
  236             case 3:
  237                 mfdbatu(batu, 3 );
  238                 batu.bits.bl = bl;
  239 
  240                 sync(); isync();
  241                 mtdbatu( 3, batu);
  242                 sync(); isync();
  243 
  244                 break;
  245             }
  246 
  247             if (ibat) switch (batn) {
  248 
  249             case 0:
  250                 mfibatu(batu, 0 );
  251                 batu.bits.bl = bl;
  252 
  253                 sync(); isync();
  254                 mtibatu( 0, batu);
  255                 sync(); isync();
  256 
  257                 break;
  258 
  259             case 1:
  260                 mfibatu(batu, 1 );
  261                 batu.bits.bl = bl;
  262 
  263                 sync(); isync();
  264                 mtibatu( 1, batu);
  265                 sync(); isync();
  266 
  267                 break;
  268 
  269             case 2:
  270                 mfibatu(batu, 2 );
  271                 batu.bits.bl = bl;
  272 
  273                 sync(); isync();
  274                 mtibatu( 2, batu);
  275                 sync(); isync();
  276 
  277                 break;
  278 
  279             case 3:
  280                 mfibatu(batu, 3 );
  281                 batu.bits.bl = bl;
  282 
  283                 sync(); isync();
  284                 mtibatu( 3, batu);
  285                 sync(); isync();
  286 
  287                 break;
  288             }
  289         }
  290     }
  291     else
  292         new_limit = new_minimum;
  293 
  294     return (new_limit);
  295 }

Cache object: 91e533f717c861361a549f03077233b5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.