OpenCores
URL https://opencores.org/ocsvn/mips_enhanced/mips_enhanced/trunk

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [software/] [leon3/] [mmu.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
#include "leon3.h"
2
#include "testmod.h" 
3
#include "mmu.h" 
4
 
5
#define NODO_CLEAR
6
#define TLBNUM 8
7
 
8
extern unsigned long ctx;
9
extern unsigned long pg0,pm0,pt0,page0,page1,page2,pth_addr,pth_addr1;
10
typedef void (*functype)(void);
11
 
12
 
13
#define fail(err) do { } while(1);
14
#define report(test_case) 
15
 
16
void leon_flush_cache_all (void)
17
{
18
 
19
        __asm__ __volatile__(" flush ");
20
        __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t": :
21
                             "i" (0x11) : "memory");
22
 
23
 
24
}
25
 
26
void leon_flush_tlb_all (void)
27
{
28
        leon_flush_cache_all();
29
        __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
30
                             "r" (0x400),
31
                             "i" (0x18) : "memory");
32
}
33
 
34
 
35
void mmu_func1();
36
mmu_test()
37
{
38
  ctxd_t *c0 = (ctxd_t *)&ctx;
39
  pgd_t *g0 = (pgd_t *)&pg0;
40
  pmd_t *m0 = (pmd_t *)&pm0;
41
  pte_t *p0 = (pte_t *)&pt0;
42
  unsigned long pteval,j,k;
43
  unsigned long paddr, vaddr, val;
44
  unsigned long *pthaddr = &pth_addr1;
45
  functype func = mmu_func1;
46
  int i=0;
47
 
48
  if ((rsysreg(12) & 8) == 0) return(0);
49
  report_subtest(MMU_TEST);
50
 
51
  /*
52
__asm__(
53
  "set 0xf, %g2\n\t"
54
  "sta    %g2,[%g0] 2\n\t"
55
  "set 0x40000000 , %g1\n\t"
56
  "ld [%g1],%g1\n\t"
57
  );*/
58
 
59
__asm__(
60
        ".section .data\n\t"
61
        ".align %0\n\t"
62
        "ctx: .skip %1\n\t"
63
        ".align %1\n\t"
64
        "pg0: .skip %1\n\t"
65
        ".align %2\n\t"
66
        "pm0: .skip %2\n\t"
67
        ".align %3\n\t"
68
        "pt0: .skip %3\n\t"
69
        ".align %0\n\t"
70
        "page0: .skip %0\n\t"
71
        "page1: .skip %0\n\t"
72
        "page2: .skip %4\n\t"
73
        ".text\n"
74
        : : "i" (PAGE_SIZE),
75
        "i"(SRMMU_PGD_TABLE_SIZE) ,
76
        "i"(SRMMU_PMD_TABLE_SIZE) ,
77
        "i"(SRMMU_PTE_TABLE_SIZE) ,
78
      "i"((3)*PAGE_SIZE) );
79
 
80
//      if (!((lr->leonconf >> MMU_CONF_BIT) & 1))
81
//                      return(0);      
82
 
83
 
84
 leon_flush_cache_all ();
85
 leon_flush_tlb_all ();
86
 
87
//while(1);
88
 
89
 
90
 /* Prepare Page Table Hirarchy */
91
 #ifndef NODO_CLEAR
92
 /* use ram vhl model that clear mem at startup to suppress this loop */
93
 for (i = 0;i<SRMMU_PTRS_PER_CTX;i++) {
94
   srmmu_ctxd_set(c0+i,(pgd_t *)0);
95
 }
96
 #endif /*DO_CLEAR*/
97
 
98
 /* one-on-one mapping for context 0 */
99
 paddr = 0;
100
 srmmu_ctxd_set(c0+0,(pgd_t *)g0); //ctx 0
101
 srmmu_ctxd_set(c0+1,(pgd_t *)g0); //ctx 1
102
 pteval = ((0 >> 4) | SRMMU_ET_PTE | SRMMU_EXEC);           /*0 - 1000000: ROM */
103
 srmmu_set_pte(g0+0, pteval);
104
 pteval = ((0x20000000 >> 4) | SRMMU_ET_PTE | SRMMU_EXEC);  /*20000000 - 21000000: IOAREA */
105
 srmmu_set_pte(g0+32, pteval);
106
 pteval = ((0x40000000 >> 4) | SRMMU_ET_PTE | SRMMU_EXEC | SRMMU_WRITE | SRMMU_CACHE);  /*40000000 - 41000000: CRAM */
107
 srmmu_set_pte(g0+64, pteval);
108
 
109
 /* testarea:
110
  *  map 0x40000000  at f0080000 [vaddr:(0) (240)(2)(-)] as pmd
111
  *  map page0       at f0041000 [vaddr:(0) (240)(1)(1)] as page SRMMU_PRIV_RDONLY
112
  *  map mmu_func1() at f0042000 [vaddr:(0) (240)(1)(2)] as page
113
  *  map f0043000 - f007f000 [vaddr:(0) (240)(1)(3)] - [vaddr:(0) (240)(1)(63)] as page
114
  * page fault test:
115
  *  missing pgd at f1000000 [vaddr:(0) (241)(-)(-)]
116
  */
117
 srmmu_pgd_set(g0+240,m0);
118
 pteval = ((((unsigned long)0x40000000) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
119
 srmmu_set_pte(m0+2, pteval);
120
 srmmu_pmd_set(m0+1,p0);
121
 srmmu_set_pte(p0+2, 0);
122
 pteval = ((((unsigned long)&page0) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV_RDONLY);
123
 srmmu_set_pte(p0+1, pteval);
124
 ((unsigned long *)&page0)[0] = 0;
125
 ((unsigned long *)&page0)[1] = 0x12345678;
126
 for (i = 3;i<TLBNUM+3;i++) {
127
       pteval = (((((unsigned long)&page2)+(((i-3)%3)*PAGE_SIZE)) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
128
       srmmu_set_pte(p0+i, pteval);
129
 }
130
 
131
 *((unsigned long **)&pth_addr) =  pthaddr;
132
 /* repair info for fault (0xf1000000)*/
133
 pthaddr[0] = (unsigned long) (g0+241);
134
 pthaddr[1] = ((0x40000000 >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
135
 pthaddr[2] = 0xf1000000;
136
 /* repair info for write protection fault (0xf0041000) */
137
 pthaddr[3] = (unsigned long) (p0+1);
138
 pthaddr[4] = ((((unsigned long)&page0) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
139
 pthaddr[5] = 0xf0041000;
140
 /* repair info for instruction page fault (0xf0042000) */
141
 pthaddr[6] = (unsigned long) (p0+2);
142
 pthaddr[7] = ((((unsigned long)func) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
143
 pthaddr[8] = 0xf0042000;
144
 /* repair info for priviledge protection fault (0xf0041000) */
145
 pthaddr[9] = (unsigned long) (p0+1);
146
 pthaddr[10] = ((((unsigned long)&page0) >> 4) | SRMMU_ET_PTE | SRMMU_EXEC | SRMMU_WRITE);
147
 pthaddr[11] = 0xf0041000;
148
 
149
 srmmu_set_ctable_ptr((unsigned long)c0);
150
 
151
 /* test reg access */
152
 k = srmmu_get_mmureg();
153
 k = srmmu_get_ctable_ptr();
154
 srmmu_set_context(1);
155
 k = srmmu_get_context();
156
 srmmu_set_context(0);
157
 
158
 /* close your eyes and pray ... */
159
 srmmu_set_mmureg(0x00000001);
160
 asm(" flush "); //iflush 
161
 asm(" sta      %g0, [%g0] 0x11 "); //dflush
162
 
163
 
164
 
165
 mmu_double();
166
 
167
 
168
 
169
 /* test reg access */
170
 k = srmmu_get_mmureg();
171
 k = srmmu_get_ctable_ptr();
172
 k = srmmu_get_context();
173
 
174
 /* do tests*/
175
 if ( (*((unsigned long *)0xf0041000)) != 0 ||
176
      (*((unsigned long *)0xf0041004)) != 0x12345678 ) { fail(1); }
177
 if ( (*((unsigned long *)0xf0080000)) != (*((unsigned long *)0x40000000))) { fail(2); }
178
 
179
 /* page faults tests*/
180
 val = * ((volatile unsigned long *)0xf1000000);
181
 /* write protection fault */
182
 * ((volatile unsigned long *)0xf0041004) = 0x87654321;
183
 if ( (*((volatile unsigned long *)0xf0041004)) != 0x87654321 ) { fail(3); }
184
 /* doubleword write */
185
 __asm__ __volatile__("set 0xf0041000,%%g1\n\t"\
186
                      "set 0x12345678,%%g2\n\t"\
187
                      "set 0xabcdef01,%%g3\n\t"\
188
                      "std %%g2, [%%g1]\n\t"\
189
                      "std %%g2, [%%g1]\n\t": : :
190
                      "g1","g2","g3");
191
 if ( (*((volatile unsigned long *)0xf0041000)) != 0x12345678 ||
192
      (*((volatile unsigned long *)0xf0041004)) != 0xabcdef01) { fail(4); }
193
 
194
 for (j=0xf0043000,i = 3;i<TLBNUM+3;i++,j+=0x1000) {
195
       *((unsigned long *)j) = j;
196
       asm(" sta        %g0, [%g0] 0x11 "); //dflush
197
       if ( *((unsigned long*) (((unsigned long)&page2)+(((i-3)%3)*PAGE_SIZE))) != j ) { fail(5); }
198
 }
199
 asm(" sta      %g0, [%g0] 0x11 "); //dflush
200
 for (j=0,i = 3;i<TLBNUM+3;i++) {
201
       pteval = (((((unsigned long)&page2)+(((i-3)%3)*PAGE_SIZE)) >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
202
       if ((*(p0+i)) & (SRMMU_DIRTY | SRMMU_REF)) j++;
203
       if (((*(p0+i)) & ~(SRMMU_DIRTY | SRMMU_REF))  != (pteval& ~(SRMMU_DIRTY | SRMMU_REF))) { fail(6); }
204
 }
205
 //at least one entry has to have been flushed
206
 if (j == 0) { fail(7);}
207
 
208
 
209
 /* instruction page fault */
210
 func = (functype)0xf0042000;
211
 func();
212
 
213
 /* flush */
214
 srmmu_flush_whole_tlb();
215
 asm(" sta      %g0, [%g0] 0x11 "); //dflush
216
 
217
 for (j=0,i = 3;i<TLBNUM+3;i++) {
218
       if ((*(p0+i)) & (SRMMU_DIRTY | SRMMU_REF)) j++;
219
 }
220
 if (j != TLBNUM) { fail(8);}
221
 
222
 /* check modified & ref bit */
223
 if (!srmmu_pte_dirty(p0[1]) || !srmmu_pte_young(p0[1])) { fail(9); };
224
 if (!srmmu_pte_young(m0[2])) { fail(10); };
225
 if (!srmmu_pte_young(p0[2])) { fail(11); };
226
 
227
 /* check priviledge fault */
228
 __asm__ __volatile__("mov      %%psr, %%g1\n\t" \
229
                      "andn     %%g1, 0x0080, %%g2\n\t"  \
230
                      " wr      %%g2, 0x0, %%psr\n\t"\
231
                      "nop\n\t"\
232
                      "nop\n\t"\
233
                      "nop\n\t" \
234
                      : : :
235
                      "g1");
236
 // supervisor = 0 
237
 val = * ((volatile unsigned long *)0xf0041004);
238
 __asm__ __volatile__("set 0x4,%o1\n\t" \
239
                      "ta 0x2\n\t" \
240
                      "nop\n\t" );
241
 
242
 mmu_double();
243
 
244
 // supervisor = 1 
245
 {
246
   //check ctx field
247
   unsigned long a;
248
   srmmu_set_context(0);
249
   a = *(unsigned long *)0x40000000;
250
   srmmu_set_context(1);
251
   a = *(unsigned long *)0x40000000;
252
   srmmu_set_context(0);
253
   a = *(unsigned long *)0x40000000;
254
 }
255
 {
256
   //bypass asi:
257
   unsigned int i;
258
   i = leon_load_bp(0x40000000);
259
   leon_store_bp(0x40000000,i);
260
 }
261
 //mmu off
262
 srmmu_set_mmureg(0x00000000);
263
 
264
 asm("flush");
265
 return(0);
266
 {
267
   int i = 0;
268
   while (1) {
269
     i++;
270
   }
271
 };
272
 
273
 
274
}
275
 
276
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.