Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:56

0001 /*
0002  * mmu.c
0003  *
0004  * This file contains routines for initializing
0005  * and manipulating the MMU on the MPC8xx.
0006  *
0007  * Copyright (c) 1999, National Research Council of Canada
0008  *
0009  * Trivially modified for mpc8260 21.3.2001
0010  * Andy Dachs <a.dachs@sstl.co.uk>
0011  *
0012  * The license and distribution terms for this file may be
0013  * found in the file LICENSE in this distribution or at
0014  * http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #include <rtems.h>
0018 #include <mpc8260.h>
0019 #include <mpc8260/mmu.h>
0020 
0021 /*
0022  * mmu_init
0023  *
0024  * This routine sets up the virtual memory maps on an MPC8xx.
0025  * The MPC8xx does not support block address translation (BATs)
0026  * and does not have segment registers. Thus, we must set up page
0027  * translation. However, its MMU supports variable size pages
0028  * (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
0029  *
0030  * The MPC8xx has separate data and instruction 32-entry translation
0031  * lookaside buffers (TLB). By mapping all of DRAM as one huge page,
0032  * we can preload the TLBs and not have to be concerned with taking
0033  * TLB miss exceptions.
0034  *
0035  * We set up the virtual memory map so that virtual address of a
0036  * location is equal to its real address.
0037  */
0038 void mmu_init( void )
0039 {
0040 #if 0
0041 /* so far we leave mmu uninitialised */
0042 
0043   register uint32_t   reg1, i;
0044 
0045   /*
0046    * Initialize the TLBs
0047    *
0048    * Instruction address translation and data address translation
0049    * must be disabled during initialization (IR=0, DR=0 in MSR).
0050    * We can assume the MSR has already been set this way.
0051    */
0052 
0053   /*
0054    * Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
0055    *    GPM [0]         0b0 = PowerPC mode
0056    *    PPM [1]         0b0 = Page resolution of protection
0057    *    CIDEF [2]       0b0/0b1 = Default cache-inhibit attribute =
0058    *                            NO for IMMU, YES for DMMU!
0059    *    reserved/WTDEF [3]  0b0 = Default write-through attribute = not
0060    *    RSV4x [4]       0b0 = 4 entries not reserved
0061    *    reserved/TWAM [5]   0b0/0b1 = 4-Kbyte page hardware assist
0062    *    PPCS [6]        0b0 = Ignore user/supervisor state
0063    *    reserved [7-18]     0x00
0064    *    xTLB_INDX [19-23]   31 = 0x1F
0065    *    reserved [24-31]    0x00
0066    *
0067    * Note: It is important that cache-inhibit be set as the default for the
0068    * data cache when the DMMU is disabled in order to prevent internal memory
0069    * mapped registers from being cached accidentally when address translation
0070    * is turned off at the start of exception processing.
0071    */
0072   reg1 = M8xx_MI_CTR_ITLB_INDX(31);
0073   _mtspr( M8xx_MI_CTR, reg1 );
0074   reg1 = M8xx_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
0075   _mtspr( M8xx_MD_CTR, reg1 );
0076   _isync;
0077 
0078   /*
0079    * Invalidate all TLB entries in both TLBs.
0080    * Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
0081    *       all 32 entries are invalidated.
0082    */
0083   __asm__ volatile ("tlbia\n"::);
0084   _isync;
0085 
0086   /*
0087    * Set Current Address Space ID Register (M_CASID).
0088    * Supervisor: CASID = 0
0089    */
0090   reg1 = 0;
0091   _mtspr( M8xx_M_CASID, reg1 );
0092 
0093   /*
0094    * Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
0095    * We ignore the Access Protection Group (APG) mechanism globally
0096    * by setting all of the Mx_AP fields to 0b01 : client access
0097    * permission is defined by page protection bits.
0098    */
0099   reg1 = 0x55555555;
0100   _mtspr( M8xx_MI_AP, reg1 );
0101   _mtspr( M8xx_MD_AP, reg1 );
0102 
0103   /*
0104    * Load both 32-entry TLBs with values from the MMU_TLB_table
0105    * which is defined in the BSP.
0106    * Note the _TLB_Table must have at most 32 entries. This code
0107    * makes no effort to enforce this restriction.
0108    */
0109   for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
0110     reg1 = MMU_TLB_table[i].mmu_epn;
0111     _mtspr( M8xx_MI_EPN, reg1 );
0112     _mtspr( M8xx_MD_EPN, reg1 );
0113     reg1 = MMU_TLB_table[i].mmu_twc;
0114     _mtspr( M8xx_MI_TWC, reg1 );
0115     _mtspr( M8xx_MD_TWC, reg1 );
0116     reg1 = MMU_TLB_table[i].mmu_rpn;    /* RPN must be written last! */
0117     _mtspr( M8xx_MI_RPN, reg1 );
0118     _mtspr( M8xx_MD_RPN, reg1 );
0119   }
0120 
0121   /*
0122    * Turn on address translation by setting MSR[IR] and MSR[DR].
0123    */
0124   _CPU_MSR_GET( reg1 );
0125   reg1 |= PPC_MSR_IR | PPC_MSR_DR;
0126   _CPU_MSR_SET( reg1 );
0127 
0128 #endif
0129 
0130 }