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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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