1 | /* page_table.c |
---|
2 | * |
---|
3 | * The code submitted by Eric Vaitl <vaitl@viasat.com> for the MVME162 appears |
---|
4 | * to be for a uniprocessor implementation. The function that sets up the |
---|
5 | * page tables, page_table_init(), is not data driven. For all processors, it |
---|
6 | * sets up page tables to map virtual addresses from 0x20000 to 0x3FFFFF to |
---|
7 | * physical addresses 0x20000 to 0x3FFFFF. This presumably maps a subset of |
---|
8 | * a local 4 MB space, which is probably the amount of RAM on Eric Vailt's |
---|
9 | * MVME162. |
---|
10 | * |
---|
11 | * It is possible to set up the various bus bridges in the MVME167s to create |
---|
12 | * a flat physical address space across multiple boards, i.e., it is possible |
---|
13 | * for each MVME167 in a multiprocessor system to access a given memory |
---|
14 | * location using the same physical address, whether that location is in local |
---|
15 | * or VME space. Addres translation can be set up so that each virtual address |
---|
16 | * maps to its corresponding physical address, e.g. virtual address 0x12345678 |
---|
17 | * is mapped to physical address 0x12345678. With this mapping, the MMU is |
---|
18 | * only used to control the caching modes for the various regions of memory. |
---|
19 | * Mapping the virtual addresses to their corresponding physical address makes |
---|
20 | * it unnecessary to map addresses under software control during the |
---|
21 | * initialization of RTEMS, before address translation is turned on. |
---|
22 | * |
---|
23 | * With the above approach, address translation may be set up either with the |
---|
24 | * transparent address translation registers, or with page tables. If page |
---|
25 | * tables are used, a more efficient use of page table space can be achieved |
---|
26 | * by sharing the page tables between processors. The entire page table tree |
---|
27 | * can be shared, or each processor can hold a private copy of the top nodes |
---|
28 | * which point to leaf nodes stored on individual processors. |
---|
29 | * |
---|
30 | * In this port, only the transparent address translation registers are used. |
---|
31 | * We map the entire virtual range from 0x0 to 0x7FFFFFFF to the identical |
---|
32 | * physical range 0x0 to 0x7FFFFFFF. We rely on the hardware to signal bus |
---|
33 | * errors if we address non-existent memory within this range. Our two |
---|
34 | * MVME167s are configured to exist at physical addresses 0x00800000 to |
---|
35 | * 0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. If jumper J1-4 is |
---|
36 | * installed, memory and cache control can be done by providing parameters |
---|
37 | * in NVRAM and jumpers J1-[5-7] are ignored. See the README for details. |
---|
38 | * If J1-4 is removed, behaviour defaults to the following. We map the space |
---|
39 | * from 0x0 to 0x7FFFFFFF as copyback, unless jumper J1-5 is removed, in which |
---|
40 | * case we map as writethrough. If jumper J1-7 is removed, the data cache is |
---|
41 | * NOT enabled. If jumper J1-6 is removed, the instruction cache is not enabled. |
---|
42 | * |
---|
43 | * Copyright (c) 1998, National Research Council of Canada |
---|
44 | */ |
---|
45 | |
---|
46 | #include <bsp.h> |
---|
47 | #include <page_table.h> /* Nothing in here for us */ |
---|
48 | |
---|
49 | /* |
---|
50 | * page_table_init |
---|
51 | * |
---|
52 | * Map the virtual range 0x00000000--0x7FFFFFFF to the physical range |
---|
53 | * 0x00000000--0x7FFFFFFF. Rely on the hardware to raise exceptions when |
---|
54 | * addressing non-existent memory. Use only the transparent translation |
---|
55 | * registers (for now). |
---|
56 | * |
---|
57 | * On all processors, the local virtual address range 0xFF000000--0xFFFFFFFF |
---|
58 | * is mapped to the physical address range 0xFF000000--0xFFFFFFFF as |
---|
59 | * caching disabled, serialized access. |
---|
60 | * |
---|
61 | * Output parameters: NONE |
---|
62 | * |
---|
63 | * Return values: NONE |
---|
64 | */ |
---|
65 | void page_table_init( void ) |
---|
66 | { |
---|
67 | unsigned char j1; /* State of J1 jumpers */ |
---|
68 | register unsigned long dtt0; /* Content of dtt0 */ |
---|
69 | register unsigned long cacr; /* Content of cacr */ |
---|
70 | |
---|
71 | /* |
---|
72 | * Logical base addr = 0x00 map starting at 0x00000000 |
---|
73 | * Logical address mask = 0x7F map up to 0x7FFFFFFF |
---|
74 | * E = 0b1 enable address translation |
---|
75 | * S-Field = 0b1X ignore FC2 when matching |
---|
76 | * U1, U0 = 0b00 user page attributes not used |
---|
77 | * CM = 0b01 cachable, copyback |
---|
78 | * W = 0b0 read/write access allowed |
---|
79 | */ |
---|
80 | dtt0 = 0x007FC020; |
---|
81 | |
---|
82 | cacr = 0x00000000; /* Data and instruction cache off */ |
---|
83 | |
---|
84 | /* Read the J1 header */ |
---|
85 | j1 = (unsigned char)(lcsr->vector_base & 0xFF); |
---|
86 | |
---|
87 | if ( !(j1 & 0x10) ) { |
---|
88 | /* Jumper J1-4 is on, configure from NVRAM */ |
---|
89 | |
---|
90 | if ( nvram->cache_mode & 0x01 ) |
---|
91 | cacr |= 0x80000000; |
---|
92 | |
---|
93 | if ( nvram->cache_mode & 0x02 ) |
---|
94 | cacr |= 0x00008000; |
---|
95 | |
---|
96 | if ( nvram->cache_mode ) |
---|
97 | dtt0 = ((nvram->cache_mode & 0x0C) << 3) | (dtt0 & 0xFFFFFF9F); |
---|
98 | } |
---|
99 | else { |
---|
100 | /* Configure according to other jumper settings */ |
---|
101 | |
---|
102 | if ( !(j1 & 0x80) ) |
---|
103 | /* Jumper J1-7 if on, enable data caching */ |
---|
104 | cacr |= 0x80000000; |
---|
105 | |
---|
106 | if ( !(j1 & 0x40) ) |
---|
107 | /* Jumper J1-6 if on, enable instruction caching */ |
---|
108 | cacr |= 0x00008000; |
---|
109 | |
---|
110 | if ( j1 & 0x20 ) |
---|
111 | /* Jumper J1-5 is off, enable writethrough caching */ |
---|
112 | dtt0 &= 0xFFFFFF9F; |
---|
113 | } |
---|
114 | |
---|
115 | /* do it ! */ |
---|
116 | __asm__ volatile("movec %0, %%tc\n\t" /* turn off paged address translation */ |
---|
117 | "movec %0, %%cacr\n\t" /* disable both caches */ |
---|
118 | "cinva %%bc\n\t" /* clear both caches */ |
---|
119 | "movec %1,%%dtt0\n\t" /* block address translation on */ |
---|
120 | "movec %1,%%itt0\n\t" |
---|
121 | "movec %2,%%dtt1\n\t" |
---|
122 | "movec %2,%%itt1\n\t" |
---|
123 | "movec %3,%%cacr" /* data cache on */ |
---|
124 | :: "d" (0), "d" (dtt0), "d" (0xFF00C040), "d" (cacr)); |
---|
125 | } |
---|
126 | |
---|
127 | /* |
---|
128 | * page_table_teardown |
---|
129 | * |
---|
130 | * Turn off paging. Turn off the cache. Flush the cache. Tear down |
---|
131 | * the transparent translations. |
---|
132 | * |
---|
133 | * Input parameters: NONE |
---|
134 | * |
---|
135 | * Output parameters: NONE |
---|
136 | * |
---|
137 | * Return values: NONE |
---|
138 | */ |
---|
139 | void page_table_teardown( void ) |
---|
140 | { |
---|
141 | __asm__ volatile ("movec %0,%%tc\n\t" |
---|
142 | "movec %0,%%cacr\n\t" |
---|
143 | "cpusha %%bc\n\t" |
---|
144 | "movec %0,%%dtt0\n\t" |
---|
145 | "movec %0,%%itt0\n\t" |
---|
146 | "movec %0,%%dtt1\n\t" |
---|
147 | "movec %0,%%itt1" |
---|
148 | :: "d" (0) ); |
---|
149 | } |
---|