Back to home page

LXR

 
 

    


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

0001 /*
0002  *  This file was submitted by Eric Vaitl <vaitl@viasat.com>.
0003  *  The manipulation of the page table has a very positive impact on
0004  *  the performance of the MVME162.
0005  *
0006  *  The following history is included verbatim from the submitter.
0007  *
0008  * Revision 1.8  1995/11/18  00:07:25  vaitl
0009  * Modified asm-statements to get rid of the register hard-codes.
0010  *
0011  * Revision 1.7  1995/10/27  21:00:32  vaitl
0012  * Modified page table routines so application code can map
0013  * VME space.
0014  *
0015  * Revision 1.6  1995/10/26  17:40:01  vaitl
0016  * Two cache changes after reading the mvme162 users manual.
0017  *
0018  * 1) The users manual says that the MPU can act as a source for the
0019  *    VME2 chip, so I made the VME accessable memory copy-back instead
0020  *    of write through.  I have't changed the comments yet. If this
0021  *    causes problems, I'll change it back.
0022  *
0023  * 2) The 162 book also says that IO space should be serialized as well as
0024  *    non-cacheable. I flipped the appropriate dttr0 and ittr0 registers. I
0025  *    don't think this is really necessary because we don't recover from any
0026  *    exceptions. If it slows down IO addresses too much, I'll change it back
0027  *    and see what happens.
0028  *
0029  * Revision 1.5  1995/10/25  19:32:38  vaitl
0030  * Got it. Three problems:
0031  *   1) Must cpusha instead of cinva.
0032  *   2) On page descriptors the PDT field of 1 or 3 is resident. On pointer
0033  *      descriptors resident is 2 or 3. I was using 2 for everything.
0034  *      Changed it to 3 for everything.
0035  *   3) Forgot to do a pflusha.
0036  *
0037  * Revision 1.4  1995/10/25  17:47:11  vaitl
0038  * Still working on it.
0039  *
0040  * Revision 1.3  1995/10/25  17:16:05  vaitl
0041  * Working on page table. Caching partially set up, but can't currently
0042  * set tc register.
0043  *
0044  */
0045 
0046 #include <string.h>
0047 #include <page_table.h>
0048 
0049 /* All page table must fit between BASE_TABLE_ADDR and
0050    MAX_TABLE_ADDR. */
0051 
0052 #define BASE_TABLE_ADDR 0x10000
0053 #define MAX_TABLE_ADDR 0x20000
0054 #define ROOT_TABLE_SIZE 512
0055 #define POINTER_TABLE_SIZE 512
0056 #define PAGE_TABLE_SIZE 256
0057 
0058 static unsigned long *root_table;
0059 static unsigned long *next_avail;
0060 
0061 /* Returns a zeroed out table. */
0062 static unsigned long *table_alloc(int size){
0063     unsigned long *addr=next_avail;
0064     if(((unsigned long)next_avail + size) > MAX_TABLE_ADDR){
0065     return 0;
0066     }
0067     memset((void *)addr,0, size);
0068     next_avail =(unsigned long *)((unsigned long)next_avail + size);
0069     return addr;
0070 }
0071 
0072 /*
0073    void page_table_init();
0074 
0075    This should transparently map the first 4 Meg of ram.  Caching is
0076    turned off from 0x00000000 to 0x00020000 (this region is used by
0077    162Bug and contains the page tables). From 0x00020000 to 0x00400000
0078    we are using copy back caching. DTTR0 and ITTR0 are set up to
0079    directly translate from 0x80000000-0xffffffff with caching turned
0080    off and serialized. Addresses between 0x400000 and 0x80000000 are
0081    illegal.
0082 */
0083 void page_table_init(){
0084 
0085     /* put everything in a known state */
0086     page_table_teardown();
0087 
0088     root_table=table_alloc(ROOT_TABLE_SIZE);
0089 
0090     /* First set up TTR.
0091        base address = 0x80000000
0092        address mask = 0x7f
0093        Ignore FC2 for match.
0094        Noncachable.
0095        Not write protected.*/
0096     __asm__ volatile ("movec %0,%%dtt0\n\
0097                    movec %0,%%itt0"
0098           :: "d" (0x807fc040));
0099 
0100     /* Point urp and srp at root page table. */
0101     __asm__ volatile ("movec %0,%%urp\n\
0102                    movec %0,%%srp"
0103           :: "d" (BASE_TABLE_ADDR));
0104 
0105     page_table_map((void *)0,0x20000, CACHE_NONE);
0106     page_table_map((void *)0x20000,0x400000-0x20000,CACHE_COPYBACK);
0107 
0108     /* Turn on paging with a 4 k page size.*/
0109     __asm__ volatile ("movec %0,%%tc"
0110           :: "d" (0x8000));
0111 
0112     /* Turn on the cache. */
0113     __asm__ volatile ("movec %0,%%cacr"
0114           :: "d" (0x80008000));
0115 }
0116 
0117 void page_table_teardown(){
0118     next_avail=(unsigned long *)BASE_TABLE_ADDR;
0119     /* Turn off paging.  Turn off the cache. Flush the cache. Tear down
0120        the transparent translations. */
0121     __asm__ volatile ("movec %0,%%tc\n\
0122                    movec %0,%%cacr\n\
0123                    cpusha %%bc\n\
0124                    movec %0,%%dtt0\n\
0125                    movec %0,%%itt0\n\
0126                    movec %0,%%dtt1\n\
0127                    movec %0,%%itt1"
0128           :: "d" (0) );
0129 }
0130 
0131 /* Identity maps addr to addr+size with caching cache_type. */
0132 int page_table_map(void *addr, unsigned long size, int cache_type){
0133     unsigned long *pointer_table;
0134     unsigned long *page_table;
0135     unsigned long root_index, pointer_index, page_index;
0136     /* addr must be a multiple of 4k */
0137     if((unsigned long)addr & 0xfff){
0138     return  PTM_BAD_ADDR;
0139     }
0140     /* size must also be a multiple of 4k */
0141     if(size & 0xfff){
0142     return PTM_BAD_SIZE;
0143     }
0144     /* check for valid cache type */
0145     if( (cache_type>CACHE_NONE) || (cache_type<CACHE_WRITE_THROUGH)){
0146     return PTM_BAD_CACHE;
0147     }
0148 
0149     while(size){
0150     root_index=(unsigned long)addr;
0151     root_index >>= 25;
0152     root_index &= 0x7f;
0153 
0154     if(root_table[root_index]){
0155         pointer_table =
0156         (unsigned long *) (root_table[root_index] & 0xfffffe00);
0157     }else{
0158         if(!(pointer_table=table_alloc(POINTER_TABLE_SIZE))){
0159         return  PTM_NO_TABLE_SPACE;
0160         }
0161         root_table[root_index]=((unsigned long)pointer_table) + 0x03;
0162     }
0163 
0164     pointer_index=(unsigned long)addr;
0165     pointer_index >>=18;
0166     pointer_index &= 0x7f;
0167 
0168     if(pointer_table[pointer_index]){
0169         page_table =
0170         (unsigned long *) (pointer_table[pointer_index] &
0171                    0xffffff00);
0172     }else{
0173         if(!(page_table=table_alloc(PAGE_TABLE_SIZE))){
0174         return  PTM_NO_TABLE_SPACE;
0175         }
0176         pointer_table[pointer_index]=
0177         ((unsigned long)page_table) + 0x03;
0178     }
0179 
0180     page_index=(unsigned long)addr;
0181     page_index >>=12;
0182     page_index &= 0x3f;
0183 
0184     page_table[page_index] =
0185         ((unsigned long) addr & 0xfffff000) + 0x03 + (cache_type << 5);
0186 
0187     size -= 4096;
0188     addr = (void *) ((unsigned long)addr + 4096);
0189     }
0190 
0191     /* Flush the ATC. Push and invalidate the cache. */
0192     __asm__ volatile ("pflusha\n\
0193                    cpusha %bc");
0194 
0195     return  PTM_SUCCESS;
0196 }