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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [testbench/] [mmu.c] - Blame information for rev 466

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

powered by: WebSVN 2.1.0

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