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

Cache object: a35b6821c3574a40e260f268f8b3e179


[ 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.