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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc3/] [or1ksim/] [testbench/] [mmu.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 410 simons
/* This is MMU test for OpenRISC 1200 */
2
 
3
#include "spr_defs.h"
4
#include "support.h"
5
 
6 480 simons
/* For shorter simulation run */
7
#define RTL_SIM 1
8
 
9 410 simons
/* Define RAM physical location and size
10
   Bottom half will be used for this program, the rest
11
   will be used for testing */
12 970 simons
#define FLASH_START 0xf0000000
13 413 markom
#define FLASH_SIZE  0x00200000
14 957 simons
#define RAM_START   0x00000000
15 413 markom
#define RAM_SIZE    0x00200000
16 410 simons
 
17
/* What is the last address in ram that is used by this program */
18 413 markom
#define TEXT_END_ADD (FLASH_START + (FLASH_SIZE / 2))
19
#define DATA_END_ADD (RAM_START + (RAM_SIZE / 2))
20 410 simons
 
21 639 simons
#define TLB_TEXT_SET_NB 8
22
#define TLB_DATA_SET_NB 4
23 448 simons
 
24 410 simons
/* MMU page size */
25 457 simons
#define PAGE_SIZE 8192
26 410 simons
 
27
/* Number of DTLB sets used (power of 2, max is 256) */
28 639 simons
#define DTLB_SETS 64
29 410 simons
 
30
/* Number of DTLB ways (1, 2, 3 etc., max is 4). */
31 448 simons
#define DTLB_WAYS 1
32 410 simons
 
33
/* Number of ITLB sets used (power of 2, max is 256) */
34 639 simons
#define ITLB_SETS 64
35 410 simons
 
36
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
37 448 simons
#define ITLB_WAYS 1
38 410 simons
 
39
/* TLB mode codes */
40
#define TLB_CODE_ONE_TO_ONE     0x00000000
41
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
42
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
43
 
44 412 simons
#define TLB_CODE_MASK   0xfffff000
45
#define TLB_PR_MASK     0x00000fff
46 1614 phoenix
#define DTLB_PR_NOLIMIT  (SPR_DTLBTR_URE  | \
47 412 simons
                          SPR_DTLBTR_UWE  | \
48
                          SPR_DTLBTR_SRE  | \
49
                          SPR_DTLBTR_SWE  )
50 410 simons
 
51 1614 phoenix
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
52 448 simons
                          SPR_ITLBTR_UXE  )
53
 
54
#if 1
55 1024 simons
#define debug printf
56 448 simons
#else
57
#define debug
58
#endif
59
 
60 412 simons
/* fails if x is false */
61
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
62
 
63 448 simons
//#define TEST_JUMP(x) testjump( ((x) & (RAM_SIZE/2 - 1)) + DATA_END_ADD, (x))
64
#define TEST_JUMP(x) copy_jump (((x) & (RAM_SIZE/2 - 1)) + DATA_END_ADD); call (x)
65 413 markom
 
66 410 simons
/* Extern functions */
67
extern void lo_dmmu_en (void);
68
extern void lo_immu_en (void);
69 639 simons
extern int  lo_dtlb_ci_test (unsigned long, unsigned long);
70
extern int  lo_itlb_ci_test(unsigned long, unsigned long);
71 415 simons
extern void testjump(unsigned long phy_addr, unsigned long virt_addr);
72 448 simons
extern void (*jr)(void);
73 410 simons
 
74 415 simons
/* Local functions prototypes */
75
void dmmu_disable (void);
76
void immu_disable (void);
77
 
78 410 simons
/* Global variables */
79
extern unsigned long ram_end;
80
 
81
/* DTLB mode status */
82 448 simons
volatile unsigned long dtlb_val;
83 410 simons
 
84
/* ITLB mode status */
85 448 simons
volatile unsigned long itlb_val;
86 410 simons
 
87 412 simons
/* DTLB miss counter */
88 415 simons
volatile int dtlb_miss_count;
89 412 simons
 
90 448 simons
/* Data page fault counter */
91
volatile int dpage_fault_count;
92
 
93 412 simons
/* ITLB miss counter */
94 415 simons
volatile int itlb_miss_count;
95 412 simons
 
96 448 simons
/* Instruction page fault counter */
97
volatile int ipage_fault_count;
98
 
99 412 simons
/* EA of last DTLB miss exception */
100
unsigned long dtlb_miss_ea;
101
 
102 448 simons
/* EA of last data page fault exception */
103
unsigned long dpage_fault_ea;
104
 
105 412 simons
/* EA of last ITLB miss exception */
106
unsigned long itlb_miss_ea;
107
 
108 448 simons
/* EA of last insn page fault exception */
109
unsigned long ipage_fault_ea;
110
 
111 457 simons
void sys_call (void)
112
{
113
  asm("l.sys\t0");
114
}
115
 
116 412 simons
void fail (char *func, int line)
117
{
118
#ifndef __FUNCTION__
119
#define __FUNCTION__ "?"
120
#endif
121 448 simons
 
122
  /* Trigger sys call exception to enable supervisor mode again */
123
  sys_call ();
124
 
125 415 simons
  immu_disable ();
126
  dmmu_disable ();
127 448 simons
 
128
  debug("Test failed in %s:%i\n", func, line);
129 415 simons
  report (0xeeeeeeee);
130 412 simons
  exit (1);
131
}
132
 
133 448 simons
void call(unsigned long add)
134
{
135
        asm("l.jalr\t\t%0" : : "r" (add) : "r9", "r11");
136
        asm("l.nop" : :);
137
}
138
 
139
void jump(void)
140
{
141
        asm("_jr:");
142
        asm("l.jr\t\tr9") ;
143
        asm("l.nop" : :);
144
}
145
 
146
void copy_jump(unsigned long phy_add)
147
{
148
        memcpy((void *)phy_add, (void *)&jr, 8);
149
}
150
 
151 415 simons
/* Bus error exception handler */
152
void bus_err_handler (void)
153
{
154
  /* This shouldn't happend */
155 448 simons
  debug("Test failed: Bus error\n");
156 415 simons
  report (0xeeeeeeee);
157
  exit (1);
158
}
159
 
160
/* Illegal insn exception handler */
161
void ill_insn_handler (void)
162
{
163
  /* This shouldn't happend */
164 448 simons
  debug("Test failed: Illegal insn\n");
165 415 simons
  report (0xeeeeeeee);
166
  exit (1);
167
}
168
 
169 448 simons
/* Sys call exception handler */
170
void sys_call_handler (void)
171
{
172
  /* Set supervisor mode */
173 600 simons
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) | SPR_SR_SM);
174 448 simons
}
175
 
176 410 simons
/* DTLB miss exception handler */
177
void dtlb_miss_handler (void)
178
{
179
  unsigned long ea, ta, tlbtr;
180
  int set, way = 0;
181
  int i;
182
 
183
  /* Get EA that cause the exception */
184
  ea = mfspr (SPR_EEAR_BASE);
185 412 simons
 
186 410 simons
  /* Find TLB set and LRU way */
187
  set = (ea / PAGE_SIZE) % DTLB_SETS;
188
  for (i = 0; i < DTLB_WAYS; i++) {
189
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
190
      way = i;
191
      break;
192
    }
193
  }
194
 
195 448 simons
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
196 410 simons
 
197 415 simons
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= ea) && (ea < TEXT_END_ADD))) {
198 410 simons
    /* If this is acces to data of this program set one to one translation */
199
    mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
200 448 simons
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
201 410 simons
    return;
202
  }
203
 
204 412 simons
  /* Update DTLB miss counter and EA */
205
  dtlb_miss_count++;
206
  dtlb_miss_ea = ea;
207
 
208 410 simons
  /* Whatever access is in progress, translated address have to point to physical RAM */
209 415 simons
  ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2);
210
  tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
211 448 simons
  debug("tlbtr = %.8lx dtlb_val = %.8lx\n", tlbtr, dtlb_val);
212 410 simons
 
213
  /* Set DTLB entry */
214
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
215
  mtspr (SPR_DTLBTR_BASE(way) + set, tlbtr);
216
}
217
 
218 448 simons
/* Data page fault exception handler */
219
void dpage_fault_handler (void)
220
{
221
  unsigned long ea;
222
  int set, way = 0;
223
  int i;
224 410 simons
 
225 448 simons
  /* Get EA that cause the exception */
226
  ea = mfspr (SPR_EEAR_BASE);
227
 
228
  /* Find TLB set and way */
229
  set = (ea / PAGE_SIZE) % DTLB_SETS;
230
  for (i = 0; i < DTLB_WAYS; i++) {
231
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) == (ea & SPR_DTLBMR_VPN)) {
232
      way = i;
233
      break;
234
    }
235
  }
236
 
237
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
238
 
239
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= ea) && (ea < TEXT_END_ADD))) {
240
    /* If this is acces to data of this program set one to one translation */
241
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
242
    return;
243
  }
244
 
245
  /* Update data page fault counter and EA */
246
  dpage_fault_count++;
247
  dpage_fault_ea = ea;
248
 
249
  /* Give permission */
250
  mtspr (SPR_DTLBTR_BASE(way) + set, (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
251
}
252
 
253
 
254 410 simons
/* ITLB miss exception handler */
255
void itlb_miss_handler (void)
256
{
257 413 markom
  unsigned long ea, ta, tlbtr;
258
  int set, way = 0;
259
  int i;
260 410 simons
 
261 413 markom
  /* Get EA that cause the exception */
262 466 simons
  ea = mfspr (SPR_EEAR_BASE);
263 410 simons
 
264 413 markom
  /* Find TLB set and LRU way */
265
  set = (ea / PAGE_SIZE) % ITLB_SETS;
266
  for (i = 0; i < ITLB_WAYS; i++) {
267
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
268
      way = i;
269
      break;
270
    }
271
  }
272
 
273 448 simons
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
274 413 markom
 
275
  if ((FLASH_START <= ea) && (ea < TEXT_END_ADD)) {
276
    /* If this is acces to data of this program set one to one translation */
277
    mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
278 448 simons
    mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | ITLB_PR_NOLIMIT);
279 413 markom
    return;
280
  }
281
 
282
  /* Update ITLB miss counter and EA */
283
  itlb_miss_count++;
284
  itlb_miss_ea = ea;
285
 
286
  /* Whatever access is in progress, translated address have to point to physical RAM */
287 417 simons
  ta = (ea & ((RAM_SIZE/2) - 1)) + DATA_END_ADD;
288 415 simons
  tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
289 413 markom
 
290 448 simons
  debug("ta = %.8lx\n", ta);
291
 
292 413 markom
  /* Set ITLB entry */
293
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
294
  mtspr (SPR_ITLBTR_BASE(way) + set, tlbtr);
295 410 simons
}
296
 
297 448 simons
/* Intstruction page fault exception handler */
298
void ipage_fault_handler (void)
299
{
300
  unsigned long ea;
301
  int set, way = 0;
302
  int i;
303
 
304
  /* Get EA that cause the exception */
305 466 simons
  ea = mfspr (SPR_EEAR_BASE);
306 448 simons
 
307
  /* Find TLB set and way */
308
  set = (ea / PAGE_SIZE) % ITLB_SETS;
309
  for (i = 0; i < ITLB_WAYS; i++) {
310
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_VPN) == (ea & SPR_ITLBMR_VPN)) {
311
      way = i;
312
      break;
313
    }
314
  }
315
 
316
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
317
 
318
  if ((FLASH_START <= ea) && (ea < TEXT_END_ADD)) {
319
    /* If this is acces to data of this program set one to one translation */
320
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | ITLB_PR_NOLIMIT);
321
    return;
322
  }
323
 
324
  /* Update instruction page fault counter and EA */
325
  ipage_fault_count++;
326
  ipage_fault_ea = ea;
327
 
328
  /* Give permission */
329
  mtspr (SPR_ITLBTR_BASE(way) + set, (mfspr (SPR_ITLBTR_BASE(way) + set) & ~ITLB_PR_NOLIMIT) | itlb_val);
330
}
331
 
332 410 simons
/* Invalidate all entries in DTLB and enable DMMU */
333
void dmmu_enable (void)
334
{
335
  /* Register DTLB miss handler */
336
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
337
 
338 448 simons
  /* Register data page fault handler */
339
  excpt_dpfault = (unsigned long)dpage_fault_handler;
340
 
341 410 simons
  /* Enable DMMU */
342
  lo_dmmu_en ();
343
}
344
 
345 415 simons
/* Disable DMMU */
346
void dmmu_disable (void)
347
{
348
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
349
}
350
 
351 410 simons
/* Invalidate all entries in ITLB and enable IMMU */
352
void immu_enable (void)
353
{
354
  /* Register ITLB miss handler */
355
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
356
 
357 448 simons
  /* Register instruction page fault handler */
358
  excpt_ipfault = (unsigned long)ipage_fault_handler;
359
 
360 410 simons
  /* Enable IMMU */
361
  lo_immu_en ();
362
}
363
 
364 415 simons
/* Disable IMMU */
365
void immu_disable (void)
366
{
367
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
368
}
369
 
370 410 simons
void write_pattern(unsigned long start, unsigned long end)
371
{
372
  unsigned long add;
373
 
374
  add = start;
375
  while (add < end) {
376
    REG32(add) = add;
377
    add += PAGE_SIZE;
378
  }
379
 
380
}
381
 
382 415 simons
/* Translation address register test
383
   Set various translation and check the pattern */
384
int dtlb_translation_test (void)
385
{
386
  int i, j;
387
  unsigned long ea, ta;
388
 
389
  /* Disable DMMU */
390
  dmmu_disable();
391
 
392
  /* Invalidate all entries in DTLB */
393
  for (i = 0; i < DTLB_WAYS; i++) {
394
    for (j = 0; j < DTLB_SETS; j++) {
395
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
396
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
397
    }
398
  }
399
 
400
  /* Set one to one translation for the use of this program */
401 448 simons
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
402 415 simons
    ea = RAM_START + (i*PAGE_SIZE);
403
    ta = RAM_START + (i*PAGE_SIZE);
404
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
405 448 simons
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
406 415 simons
  }
407
 
408 448 simons
  /* Set dtlb permisions */
409
  dtlb_val = DTLB_PR_NOLIMIT;
410 415 simons
 
411
  /* Write test pattern */
412
  for (i = 0; i < DTLB_SETS; i++) {
413
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = i;
414
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
415
  }
416
 
417
  /* Set one to one translation of the last way of DTLB */
418 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
419 415 simons
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
420
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
421
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
422 448 simons
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
423 415 simons
  }
424
 
425
  /* Enable DMMU */
426
  dmmu_enable();
427
 
428
  /* Check the pattern */
429 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
430 415 simons
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
431
    ASSERT(REG32(ea) == i);
432
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
433
    ASSERT(REG32(ea) == (0xffffffff - i));
434
  }
435
 
436
  /* Write new pattern */
437 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
438 415 simons
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
439
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
440
  }
441
 
442
  /* Set 0 -> RAM_START + (RAM_SIZE/2) translation */
443 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
444 415 simons
    ea = i*PAGE_SIZE;
445
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
446
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
447 448 simons
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
448 415 simons
  }
449
 
450
  /* Check the pattern */
451 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
452 415 simons
    ea = i*PAGE_SIZE;
453
    ASSERT(REG32(ea) == (0xffffffff - i));
454
    ea = ((i + 1)*PAGE_SIZE) - 4;
455
    ASSERT(REG32(ea) == i);
456
  }
457
 
458
  /* Write new pattern */
459 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
460 415 simons
    REG32(i*PAGE_SIZE) = i;
461
    REG32(((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
462
  }
463
 
464
  /* Set hi -> lo, lo -> hi translation */
465 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
466 415 simons
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
467 448 simons
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1 + TLB_DATA_SET_NB)*PAGE_SIZE);
468 415 simons
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
469 448 simons
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
470 415 simons
  }
471
 
472
  /* Check the pattern */
473 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
474 415 simons
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
475 448 simons
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
476 415 simons
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
477 448 simons
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
478 415 simons
  }
479
 
480
  /* Write new pattern */
481 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
482 415 simons
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
483
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
484
  }
485
 
486
  /* Disable DMMU */
487
  dmmu_disable();
488
 
489
  /* Check the pattern */
490 448 simons
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
491 415 simons
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
492 448 simons
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
493 415 simons
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
494 448 simons
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
495 415 simons
  }
496
 
497
  return 0;
498
}
499
 
500
/* EA match register test
501
   Shifting one in DTLBMR and performing accesses to boundaries
502
   of the page, checking the triggering of exceptions */
503
int dtlb_match_test (int way, int set)
504
{
505
  int i, j, tmp;
506
  unsigned long add, t_add;
507
  unsigned long ea, ta;
508
 
509
  /* Disable DMMU */
510
  dmmu_disable();
511
 
512
  /* Invalidate all entries in DTLB */
513
  for (i = 0; i < DTLB_WAYS; i++) {
514
    for (j = 0; j < DTLB_SETS; j++) {
515
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
516
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
517
    }
518
  }
519
 
520
  /* Set one to one translation for the use of this program */
521 448 simons
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
522 415 simons
    ea = RAM_START + (i*PAGE_SIZE);
523
    ta = RAM_START + (i*PAGE_SIZE);
524
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
525 448 simons
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
526 415 simons
  }
527
 
528
  /* Set dtlb permisions */
529 448 simons
  dtlb_val = DTLB_PR_NOLIMIT;
530 415 simons
 
531
  /* Set pattern */
532 448 simons
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 4) = 0x00112233;
533
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) = 0x44556677;
534
  REG32(RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 4) = 0x8899aabb;
535
  REG32(RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE) = 0xccddeeff;
536 415 simons
 
537
  /* Enable DMMU */
538
  dmmu_enable();
539
 
540
  /* Shifting one in DTLBMR */
541
  i = 0;
542
  add = (PAGE_SIZE*DTLB_SETS);
543
  t_add = add + (set*PAGE_SIZE);
544
  while (add != 0x00000000) {
545
    mtspr (SPR_DTLBMR_BASE(way) + set, t_add | SPR_DTLBMR_V);
546 448 simons
    mtspr (SPR_DTLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | DTLB_PR_NOLIMIT);
547 415 simons
 
548
    /* Reset DTLB miss counter and EA */
549
    dtlb_miss_count = 0;
550
    dtlb_miss_ea = 0;
551
 
552 448 simons
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
553 415 simons
 
554
      /* Read last address of previous page */
555
      tmp = REG32(t_add - 4);
556 448 simons
      ASSERT(tmp == 0x00112233);
557 415 simons
      ASSERT(dtlb_miss_count == 1);
558
 
559
      /* Read first address of the page */
560
      tmp = REG32(t_add);
561
      ASSERT(tmp == 0x44556677);
562
      ASSERT(dtlb_miss_count == 1);
563
 
564
      /* Read last address of the page */
565
      tmp = REG32(t_add + PAGE_SIZE - 4);
566
      ASSERT(tmp == 0x8899aabb);
567
      ASSERT(dtlb_miss_count == 1);
568
 
569
      /* Read first address of next page */
570
      tmp = REG32(t_add + PAGE_SIZE);
571 448 simons
      ASSERT(tmp == 0xccddeeff);
572 415 simons
      ASSERT(dtlb_miss_count == 2);
573
    }
574
 
575
    i++;
576
    add = (PAGE_SIZE*DTLB_SETS) << i;
577
    t_add = add + (set*PAGE_SIZE);
578
 
579
    for (j = 0; j < DTLB_WAYS; j++) {
580
      mtspr (SPR_DTLBMR_BASE(j) + ((set - 1) & (DTLB_SETS - 1)), 0);
581
      mtspr (SPR_DTLBMR_BASE(j) + ((set + 1) & (DTLB_SETS - 1)), 0);
582
    }
583
  }
584
 
585
  /* Disable DMMU */
586
  dmmu_disable();
587
 
588
  return 0;
589
}
590
 
591 412 simons
/* Valid bit test
592
   Set all ways of one set to be invalid, perform
593
   access so miss handler will set them to valid,
594
   try access again - there should be no miss exceptions */
595
int dtlb_valid_bit_test (int set)
596
{
597 415 simons
  int i, j;
598
  unsigned long ea, ta;
599 412 simons
 
600 415 simons
  /* Disable DMMU */
601
  dmmu_disable();
602
 
603
  /* Invalidate all entries in DTLB */
604
  for (i = 0; i < DTLB_WAYS; i++) {
605
    for (j = 0; j < DTLB_SETS; j++) {
606
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
607
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
608
    }
609
  }
610
 
611
  /* Set one to one translation for the use of this program */
612 448 simons
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
613 415 simons
    ea = RAM_START + (i*PAGE_SIZE);
614
    ta = RAM_START + (i*PAGE_SIZE);
615
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
616 448 simons
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
617 415 simons
  }
618
 
619 412 simons
  /* Reset DTLB miss counter and EA */
620
  dtlb_miss_count = 0;
621
  dtlb_miss_ea = 0;
622
 
623
  /* Set dtlb permisions */
624 448 simons
  dtlb_val = DTLB_PR_NOLIMIT;
625 412 simons
 
626
  /* Resetv DTLBMR for every way */
627
  for (i = 0; i < DTLB_WAYS; i++) {
628
    mtspr (SPR_DTLBMR_BASE(i) + set, 0);
629
  }
630
 
631 415 simons
  /* Enable DMMU */
632
  dmmu_enable();
633
 
634 412 simons
  /* Perform writes to address, that is not in DTLB */
635
  for (i = 0; i < DTLB_WAYS; i++) {
636
    REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) = i;
637
 
638
    /* Check if there was DTLB miss */
639
    ASSERT(dtlb_miss_count == (i + 1));
640
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
641
  }
642
 
643
  /* Reset DTLB miss counter and EA */
644
  dtlb_miss_count = 0;
645
  dtlb_miss_ea = 0;
646
 
647
  /* Perform reads to address, that is now in DTLB */
648
  for (i = 0; i < DTLB_WAYS; i++) {
649
    ASSERT(REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) == i);
650
 
651
    /* Check if there was DTLB miss */
652
    ASSERT(dtlb_miss_count == 0);
653
  }
654
 
655
  /* Reset valid bits */
656
  for (i = 0; i < DTLB_WAYS; i++) {
657
    mtspr (SPR_DTLBMR_BASE(i) + set, mfspr (SPR_DTLBMR_BASE(i) + set) & ~SPR_DTLBMR_V);
658
  }
659
 
660
  /* Perform reads to address, that is now in DTLB but is invalid */
661
  for (i = 0; i < DTLB_WAYS; i++) {
662
    ASSERT(REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) == i);
663
 
664
    /* Check if there was DTLB miss */
665
    ASSERT(dtlb_miss_count == (i + 1));
666
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
667
  }
668
 
669 415 simons
  /* Disable DMMU */
670
  dmmu_disable();
671
 
672 412 simons
  return 0;
673
}
674 448 simons
 
675
/* Permission test
676
   Set various permissions, perform r/w access
677
   in user and supervisor mode and chack triggering
678
   of page fault exceptions */
679
int dtlb_premission_test (int set)
680
{
681
  int i, j;
682
  unsigned long ea, ta, tmp;
683
 
684
  /* Disable DMMU */
685
  dmmu_disable();
686
 
687
  /* Invalidate all entries in DTLB */
688
  for (i = 0; i < DTLB_WAYS; i++) {
689
    for (j = 0; j < DTLB_SETS; j++) {
690
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
691
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
692
    }
693
  }
694
 
695
  /* Set one to one translation for the use of this program */
696
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
697
    ea = RAM_START + (i*PAGE_SIZE);
698
    ta = RAM_START + (i*PAGE_SIZE);
699
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
700
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
701
  }
702
 
703
  /* Testing page */
704
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
705
 
706
  /* Set match register */
707
  mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + set, ea | SPR_DTLBMR_V);
708
 
709
  /* Reset page fault counter and EA */
710
  dpage_fault_count = 0;
711
  dpage_fault_ea = 0;
712
 
713
  /* Enable DMMU */
714
  dmmu_enable();
715
 
716
  /* Write supervisor */
717
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_SWE;
718
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_SWE));
719
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0) = 0x00112233;
720
  ASSERT(dpage_fault_count == 1);
721
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4) = 0x44556677;
722
  ASSERT(dpage_fault_count == 1);
723
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8) = 0x8899aabb;
724
  ASSERT(dpage_fault_count == 1);
725
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12) = 0xccddeeff;
726
  ASSERT(dpage_fault_count == 1);
727
 
728
  /* Read supervisor */
729
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_SRE;
730
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_SRE));
731
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0);
732
  ASSERT(dpage_fault_count == 2);
733
  ASSERT(tmp == 0x00112233);
734
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4);
735
  ASSERT(dpage_fault_count == 2);
736
  ASSERT(tmp == 0x44556677);
737
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8);
738
  ASSERT(dpage_fault_count == 2);
739
  ASSERT(tmp == 0x8899aabb);
740
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12);
741
  ASSERT(dpage_fault_count == 2);
742
  ASSERT(tmp == 0xccddeeff);
743
 
744
  /* Write user */
745
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_UWE;
746
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_UWE));
747
 
748
  /* Set user mode */
749 600 simons
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
750 448 simons
 
751
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0) = 0xffeeddcc;
752
  ASSERT(dpage_fault_count == 3);
753
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4) = 0xbbaa9988;
754
  ASSERT(dpage_fault_count == 3);
755
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8) = 0x77665544;
756
  ASSERT(dpage_fault_count == 3);
757
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12) = 0x33221100;
758
  ASSERT(dpage_fault_count == 3);
759
 
760
  /* Trigger sys call exception to enable supervisor mode again */
761
  sys_call ();
762
 
763
  /* Read user mode */
764
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_URE;
765
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_URE));
766
 
767
  /* Set user mode */
768 600 simons
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
769 448 simons
 
770
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0);
771
  ASSERT(dpage_fault_count == 4);
772
  ASSERT(tmp == 0xffeeddcc);
773
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4);
774
  ASSERT(dpage_fault_count == 4);
775
  ASSERT(tmp == 0xbbaa9988);
776
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8);
777
  ASSERT(dpage_fault_count == 4);
778
  ASSERT(tmp == 0x77665544);
779
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12);
780
  ASSERT(dpage_fault_count == 4);
781
  ASSERT(tmp == 0x33221100);
782
 
783
  /* Trigger sys call exception to enable supervisor mode again */
784
  sys_call ();
785
 
786
  /* Disable DMMU */
787
  dmmu_disable();
788
 
789
  return 0;
790
}
791
 
792 639 simons
/* Data cache inhibit bit test
793
   Set and clear CI bit and check the pattern. */
794
int dtlb_ci_test (void)
795
{
796
  int i, j;
797
  unsigned long ea, ta, ret;
798
 
799
  /* Disable DMMU */
800
  dmmu_disable();
801
 
802
  /* Invalidate all entries in DTLB */
803
  for (i = 0; i < DTLB_WAYS; i++) {
804
    for (j = 0; j < DTLB_SETS; j++) {
805
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
806
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
807
    }
808
  }
809
 
810
  /* Set one to one translation for the use of this program */
811
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
812
    ea = RAM_START + (i*PAGE_SIZE);
813
    ta = RAM_START + (i*PAGE_SIZE);
814
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
815
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT  | SPR_DTLBTR_CI);
816
  }
817
 
818
  /* Testing page */
819
  ea = RAM_START + (RAM_SIZE/2) + (TLB_DATA_SET_NB*PAGE_SIZE);
820
  ta = RAM_START + (RAM_SIZE/2) + (TLB_DATA_SET_NB*PAGE_SIZE);
821
 
822
  /* Write test pattern */
823
  REG32(ea) = 0x01234567;
824
  REG32(ea + PAGE_SIZE - 4) = 0x9abcdef;
825
 
826
  /* Set one to one translation with CI bit for testing area */
827
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, ea | SPR_DTLBMR_V);
828
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, ta | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
829
 
830
  ret = lo_dtlb_ci_test(ea, TLB_DATA_SET_NB);
831
  ASSERT(ret == 0);
832
 
833
  return 0;
834
}
835
 
836 448 simons
/* Translation address register test
837
   Set various translation and check the pattern */
838
int itlb_translation_test (void)
839
{
840
  int i, j;
841
  unsigned long ea, ta;
842
 
843
  /* Disable IMMU */
844
  immu_disable();
845
 
846 1446 nogj
  /* Invalidate all entries in ITLB */
847 448 simons
  for (i = 0; i < ITLB_WAYS; i++) {
848
    for (j = 0; j < ITLB_SETS; j++) {
849
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
850
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
851
    }
852
  }
853
 
854
  /* Set one to one translation for the use of this program */
855
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
856
    ea = FLASH_START + (i*PAGE_SIZE);
857
    ta = FLASH_START + (i*PAGE_SIZE);
858
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
859
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
860
  }
861
 
862 1446 nogj
  /* Set itlb permisions */
863 448 simons
  itlb_val = ITLB_PR_NOLIMIT;
864
 
865
  /* Write test program */
866
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
867
    copy_jump (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
868
  }
869
 
870
  /* Set one to one translation of the last way of ITLB */
871
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
872
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
873
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
874
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
875
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
876
  }
877
 
878
  /* Enable IMMU */
879
  immu_enable();
880
 
881
  /* Check the pattern */
882
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
883
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
884
  }
885
 
886
  /* Set FLASH_END -> RAM_START + (RAM_SIZE/2) translation */
887
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
888
    ea = FLASH_START + FLASH_SIZE + i*PAGE_SIZE;
889
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
890
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
891
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
892
  }
893
 
894
  /* Check the pattern */
895
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
896
    call (FLASH_START + FLASH_SIZE + (i*PAGE_SIZE) + (i*0x10));
897
  }
898
 
899
  /* Set hi -> lo, lo -> hi translation */
900
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
901
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
902
    ta = RAM_START + (RAM_SIZE/2) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*PAGE_SIZE);
903
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
904
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
905
  }
906
 
907
  /* Check the pattern */
908
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
909
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*0x10));
910
  }
911
 
912
  /* Disable IMMU */
913
  immu_disable ();
914
 
915
  /* Check the pattern */
916
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
917
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
918
  }
919
 
920
  return 0;
921
}
922
 
923
/* EA match register test
924
   Shifting one in ITLBMR and performing accesses to boundaries
925
   of the page, checking the triggering of exceptions */
926
int itlb_match_test (int way, int set)
927
{
928
  int i, j;
929
  unsigned long add, t_add;
930
  unsigned long ea, ta;
931
 
932
  /* Disable IMMU */
933
  immu_disable();
934
 
935
  /* Invalidate all entries in ITLB */
936
  for (i = 0; i < ITLB_WAYS; i++) {
937
    for (j = 0; j < ITLB_SETS; j++) {
938
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
939
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
940
    }
941
  }
942
 
943
  /* Set one to one translation for the use of this program */
944
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
945
    ea = FLASH_START + (i*PAGE_SIZE);
946
    ta = FLASH_START + (i*PAGE_SIZE);
947
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
948
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
949
  }
950
 
951
  /* Set dtlb permisions */
952
  itlb_val = ITLB_PR_NOLIMIT;
953
 
954
  /* Set pattern */
955
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 8);
956
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE));
957
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 8);
958
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE);
959
 
960
  /* Enable IMMU */
961
  immu_enable();
962
 
963
  /* Shifting one in ITLBMR */
964
  i = 0;
965
  add = (PAGE_SIZE*ITLB_SETS);
966
  t_add = add + (set*PAGE_SIZE);
967
  while (add != 0x00000000) {
968
    mtspr (SPR_ITLBMR_BASE(way) + set, t_add | SPR_ITLBMR_V);
969
    mtspr (SPR_ITLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | ITLB_PR_NOLIMIT);
970
 
971
    /* Reset ITLB miss counter and EA */
972
    itlb_miss_count = 0;
973
    itlb_miss_ea = 0;
974
 
975
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
976
 
977
      /* Jump on last address of previous page */
978
      call (t_add - 8);
979
      ASSERT(itlb_miss_count == 1);
980
 
981
      /* Jump on first address of the page */
982
      call (t_add);
983
      ASSERT(itlb_miss_count == 1);
984 415 simons
 
985 448 simons
      /* Jump on last address of the page */
986
      call (t_add + PAGE_SIZE - 8);
987
      ASSERT(itlb_miss_count == 1);
988
 
989
      /* Jump on first address of next page */
990
      call (t_add + PAGE_SIZE);
991
      ASSERT(itlb_miss_count == 2);
992
    }
993
 
994
    i++;
995
    add = (PAGE_SIZE*ITLB_SETS) << i;
996
    t_add = add + (set*PAGE_SIZE);
997
 
998
    for (j = 0; j < ITLB_WAYS; j++) {
999
      mtspr (SPR_ITLBMR_BASE(j) + ((set - 1) & (ITLB_SETS - 1)), 0);
1000
      mtspr (SPR_ITLBMR_BASE(j) + ((set + 1) & (ITLB_SETS - 1)), 0);
1001
    }
1002
  }
1003
 
1004
  /* Disable IMMU */
1005
  immu_disable();
1006
 
1007
  return 0;
1008
}
1009
 
1010 413 markom
/* Valid bit test
1011
   Set all ways of one set to be invalid, perform
1012
   access so miss handler will set them to valid,
1013
   try access again - there should be no miss exceptions */
1014
int itlb_valid_bit_test (int set)
1015
{
1016 448 simons
  int i, j;
1017
  unsigned long ea, ta;
1018 412 simons
 
1019 448 simons
  /* Disable IMMU */
1020
  immu_disable();
1021
 
1022
  /* Invalidate all entries in ITLB */
1023
  for (i = 0; i < ITLB_WAYS; i++) {
1024
    for (j = 0; j < ITLB_SETS; j++) {
1025
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1026
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1027
    }
1028
  }
1029
 
1030
  /* Set one to one translation for the use of this program */
1031
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1032
    ea = FLASH_START + (i*PAGE_SIZE);
1033
    ta = FLASH_START + (i*PAGE_SIZE);
1034
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1035
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1036
  }
1037
 
1038 413 markom
  /* Reset ITLB miss counter and EA */
1039
  itlb_miss_count = 0;
1040
  itlb_miss_ea = 0;
1041
 
1042
  /* Set itlb permisions */
1043 448 simons
  itlb_val = ITLB_PR_NOLIMIT;
1044 412 simons
 
1045 413 markom
  /* Resetv ITLBMR for every way */
1046
  for (i = 0; i < ITLB_WAYS; i++) {
1047
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
1048
  }
1049 412 simons
 
1050 448 simons
  /* Enable IMMU */
1051
  immu_enable();
1052
 
1053 413 markom
  /* Perform jumps to address, that is not in ITLB */
1054
  for (i = 0; i < ITLB_WAYS; i++) {
1055 417 simons
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1056 413 markom
 
1057
    /* Check if there was ITLB miss */
1058
    ASSERT(itlb_miss_count == (i + 1));
1059 417 simons
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1060 413 markom
  }
1061 412 simons
 
1062 413 markom
  /* Reset ITLB miss counter and EA */
1063
  itlb_miss_count = 0;
1064
  itlb_miss_ea = 0;
1065
 
1066
  /* Perform jumps to address, that is now in ITLB */
1067
  for (i = 0; i < ITLB_WAYS; i++) {
1068 417 simons
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1069 413 markom
 
1070
    /* Check if there was ITLB miss */
1071
    ASSERT(itlb_miss_count == 0);
1072
  }
1073
 
1074
  /* Reset valid bits */
1075
  for (i = 0; i < ITLB_WAYS; i++) {
1076
    mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V);
1077
  }
1078
 
1079
  /* Perform jumps to address, that is now in ITLB but is invalid */
1080
  for (i = 0; i < ITLB_WAYS; i++) {
1081 417 simons
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1082 413 markom
 
1083
    /* Check if there was ITLB miss */
1084
    ASSERT(itlb_miss_count == (i + 1));
1085 417 simons
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1086 413 markom
  }
1087
 
1088 448 simons
  /* Disable IMMU */
1089
  immu_disable ();
1090
 
1091 413 markom
  return 0;
1092
}
1093
 
1094 448 simons
/* Permission test
1095
   Set various permissions, perform r/w access
1096 1446 nogj
   in user and supervisor mode and check triggering
1097 448 simons
   of page fault exceptions */
1098
int itlb_premission_test (int set)
1099
{
1100
  int i, j;
1101 457 simons
  unsigned long ea, ta;
1102 448 simons
 
1103
  /* Disable IMMU */
1104
  immu_disable();
1105
 
1106
  /* Invalidate all entries in ITLB */
1107
  for (i = 0; i < ITLB_WAYS; i++) {
1108
    for (j = 0; j < ITLB_SETS; j++) {
1109
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1110
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1111
    }
1112
  }
1113
 
1114
  /* Set one to one translation for the use of this program */
1115
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1116
    ea = FLASH_START + (i*PAGE_SIZE);
1117
    ta = FLASH_START + (i*PAGE_SIZE);
1118
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1119
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1120
  }
1121
 
1122
  /* Testing page */
1123
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
1124
 
1125
  /* Set match register */
1126
  mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + set, ea | SPR_ITLBMR_V);
1127
 
1128
  /* Reset page fault counter and EA */
1129
  ipage_fault_count = 0;
1130
  ipage_fault_ea = 0;
1131
 
1132
  /* Copy the code */
1133
  copy_jump (ea);
1134
  copy_jump (ea + 8);
1135
 
1136
  /* Enable IMMU */
1137
  immu_enable ();
1138
 
1139
  /* Execute supervisor */
1140
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
1141
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_SXE));
1142
 
1143
  call (ea);
1144
  ASSERT(ipage_fault_count == 1);
1145
  call (ea + 8);
1146
  ASSERT(ipage_fault_count == 1);
1147
 
1148
  /* Execute user */
1149
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_UXE;
1150
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_UXE));
1151
 
1152
  /* Set user mode */
1153 600 simons
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
1154 448 simons
 
1155
  call (ea);
1156
  ASSERT(ipage_fault_count == 2);
1157
  call (ea + 8);
1158
  ASSERT(ipage_fault_count == 2);
1159
 
1160
  /* Trigger sys call exception to enable supervisor mode again */
1161
  sys_call ();
1162
 
1163
  /* Disable IMMU */
1164
  immu_disable ();
1165
 
1166
  return 0;
1167
}
1168
 
1169 639 simons
/* Instruction cache inhibit bit test
1170
   Set and clear CI bit and check the pattern. */
1171
int itlb_ci_test(void)
1172
{
1173
  int i, j;
1174
  unsigned long ea, ta, ret;
1175
 
1176
  /* Disable IMMU */
1177
  immu_disable();
1178
 
1179
  /* Invalidate all entries in DTLB */
1180
  for (i = 0; i < ITLB_WAYS; i++) {
1181
    for (j = 0; j < ITLB_SETS; j++) {
1182
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1183
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1184
    }
1185
  }
1186
 
1187
  /* Set one to one translation for the use of this program */
1188
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1189
    ea = FLASH_START + (i*PAGE_SIZE);
1190
    ta = FLASH_START + (i*PAGE_SIZE);
1191
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1192
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1193
  }
1194
 
1195
  /* Testing page */
1196
  ea = RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE);
1197
 
1198
  ret = lo_itlb_ci_test (ea, TLB_TEXT_SET_NB);
1199
  ASSERT(ret == 0);
1200
 
1201
  return 0;
1202
}
1203
 
1204 410 simons
int main (void)
1205
{
1206 415 simons
  int i, j;
1207 410 simons
 
1208 509 markom
  i = j = 0; /* Get rid of warnings */
1209
 
1210 415 simons
  /* Register bus error handler */
1211
  excpt_buserr = (unsigned long)bus_err_handler;
1212 410 simons
 
1213 415 simons
  /* Register illegal insn handler */
1214
  excpt_illinsn = (unsigned long)ill_insn_handler;
1215
 
1216 448 simons
  /* Register illegal insn handler */
1217
  excpt_syscall = (unsigned long)sys_call_handler;
1218
 
1219 417 simons
#if 1
1220 415 simons
  /* Translation test */
1221
  dtlb_translation_test ();
1222
 
1223
  /* Virtual address match test */
1224 480 simons
#ifndef RTL_SIM
1225 415 simons
  for (j = 0; j < DTLB_WAYS; j++) {
1226 448 simons
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1227
      dtlb_match_test (j, i);
1228 415 simons
  }
1229 480 simons
#else
1230
  dtlb_match_test (0, DTLB_SETS - 2);
1231
#endif
1232 415 simons
 
1233 412 simons
  /* Valid bit testing */
1234 480 simons
#ifndef RTL_SIM
1235 448 simons
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1236
    dtlb_valid_bit_test (i);
1237 480 simons
#else
1238
  dtlb_valid_bit_test (DTLB_SETS - 2);
1239
#endif
1240 448 simons
 
1241
  /* Permission test */
1242 480 simons
#ifndef RTL_SIM
1243 448 simons
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1244
    dtlb_premission_test (i);
1245 480 simons
#else
1246
  dtlb_premission_test (DTLB_SETS - 2);
1247
#endif
1248 448 simons
 
1249 639 simons
  dtlb_ci_test();
1250 415 simons
#endif
1251 412 simons
 
1252 417 simons
#if 1
1253 415 simons
  /* Translation test */
1254 448 simons
  itlb_translation_test ();
1255
 
1256
  /* Virtual address match test */
1257 480 simons
#ifndef RTL_SIM
1258 448 simons
  for (j = 0; j < DTLB_WAYS; j++) {
1259
    for (i = TLB_TEXT_SET_NB + 1; i < (DTLB_SETS - 1); i++)
1260
      itlb_match_test (j, i);
1261
  }
1262 480 simons
#else
1263
  itlb_match_test (0, DTLB_SETS - 2);
1264
#endif
1265 448 simons
 
1266
  /* Valid bit testing */
1267 480 simons
#ifndef RTL_SIM
1268 448 simons
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS); i++)
1269
    itlb_valid_bit_test (i);
1270 480 simons
#else
1271
  itlb_valid_bit_test (ITLB_SETS-1);
1272
#endif
1273 448 simons
 
1274
  /* Permission test */
1275 480 simons
#ifndef RTL_SIM
1276 448 simons
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
1277
    itlb_premission_test (i);
1278 480 simons
#else
1279
  itlb_premission_test (ITLB_SETS - 2);
1280
#endif
1281 448 simons
 
1282 639 simons
  itlb_ci_test();
1283 417 simons
#endif
1284 415 simons
 
1285
  report (0xdeaddead);
1286
  exit (0);
1287 410 simons
  return 0;
1288
}
1289 448 simons
 

powered by: WebSVN 2.1.0

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