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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [or1ksim/] [or1ksim-0.3.0/] [testbench/] [mmu.c] - Blame information for rev 403

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* This is MMU test for OpenRISC 1200 */
2
 
3
#include "spr_defs.h"
4
#include "support.h"
5
 
6
/* For shorter simulation run */
7
#define RTL_SIM 1
8
 
9
/* Define RAM physical location and size
10
   Bottom half will be used for this program, the rest
11
   will be used for testing */
12
#define FLASH_START 0xf0000000
13
#define FLASH_SIZE  0x00200000
14
#define RAM_START   0x00000000
15
#define RAM_SIZE    0x00200000
16
 
17
/* What is the last address in ram that is used by this program */
18
#define TEXT_END_ADD (FLASH_START + (FLASH_SIZE / 2))
19
#define DATA_END_ADD (RAM_START + (RAM_SIZE / 2))
20
 
21
#define TLB_TEXT_SET_NB 8
22
#define TLB_DATA_SET_NB 4
23
 
24
/* MMU page size */
25
#define PAGE_SIZE 8192
26
 
27
/* Number of DTLB sets used (power of 2, max is 256) */
28
#define DTLB_SETS 64
29
 
30
/* Number of DTLB ways (1, 2, 3 etc., max is 4). */
31
#define DTLB_WAYS 1
32
 
33
/* Number of ITLB sets used (power of 2, max is 256) */
34
#define ITLB_SETS 64
35
 
36
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
37
#define ITLB_WAYS 1
38
 
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
#define TLB_CODE_MASK   0xfffff000
45
#define TLB_PR_MASK     0x00000fff
46
#define DTLB_PR_NOLIMIT  (SPR_DTLBTR_URE  | \
47
                          SPR_DTLBTR_UWE  | \
48
                          SPR_DTLBTR_SRE  | \
49
                          SPR_DTLBTR_SWE  )
50
 
51
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
52
                          SPR_ITLBTR_UXE  )
53
 
54
#if 1
55
#define debug printf
56
#else
57
#define debug
58
#endif
59
 
60
/* fails if x is false */
61
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
62
 
63
//#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
 
66
/* Extern functions */
67
extern void lo_dmmu_en (void);
68
extern void lo_immu_en (void);
69
extern int  lo_dtlb_ci_test (unsigned long, unsigned long);
70
extern int  lo_itlb_ci_test(unsigned long, unsigned long);
71
extern void testjump(unsigned long phy_addr, unsigned long virt_addr);
72
extern void (*jr)(void);
73
 
74
/* Local functions prototypes */
75
void dmmu_disable (void);
76
void immu_disable (void);
77
 
78
/* Global variables */
79
extern unsigned long ram_end;
80
 
81
/* DTLB mode status */
82
volatile unsigned long dtlb_val;
83
 
84
/* ITLB mode status */
85
volatile unsigned long itlb_val;
86
 
87
/* DTLB miss counter */
88
volatile int dtlb_miss_count;
89
 
90
/* Data page fault counter */
91
volatile int dpage_fault_count;
92
 
93
/* ITLB miss counter */
94
volatile int itlb_miss_count;
95
 
96
/* Instruction page fault counter */
97
volatile int ipage_fault_count;
98
 
99
/* EA of last DTLB miss exception */
100
unsigned long dtlb_miss_ea;
101
 
102
/* EA of last data page fault exception */
103
unsigned long dpage_fault_ea;
104
 
105
/* EA of last ITLB miss exception */
106
unsigned long itlb_miss_ea;
107
 
108
/* EA of last insn page fault exception */
109
unsigned long ipage_fault_ea;
110
 
111
void sys_call (void)
112
{
113
  asm("l.sys\t0");
114
}
115
 
116
void fail (char *func, int line)
117
{
118
#ifndef __FUNCTION__
119
#define __FUNCTION__ "?"
120
#endif
121
 
122
  /* Trigger sys call exception to enable supervisor mode again */
123
  sys_call ();
124
 
125
  immu_disable ();
126
  dmmu_disable ();
127
 
128
  debug("Test failed in %s:%i\n", func, line);
129
  report (0xeeeeeeee);
130
  exit (1);
131
}
132
 
133
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
/* Bus error exception handler */
152
void bus_err_handler (void)
153
{
154
  /* This shouldn't happend */
155
  debug("Test failed: Bus error\n");
156
  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
  debug("Test failed: Illegal insn\n");
165
  report (0xeeeeeeee);
166
  exit (1);
167
}
168
 
169
/* Sys call exception handler */
170
void sys_call_handler (void)
171
{
172
  /* Set supervisor mode */
173
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) | SPR_SR_SM);
174
}
175
 
176
/* 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
 
186
  /* 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
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
196
 
197
  if (((RAM_START <= ea) && (ea < DATA_END_ADD) ) || ((FLASH_START <= ea) && (ea < TEXT_END_ADD))) {
198
    /* 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
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
201
    return;
202
  }
203
 
204
  /* Update DTLB miss counter and EA */
205
  dtlb_miss_count++;
206
  dtlb_miss_ea = ea;
207
 
208
  /* Whatever access is in progress, translated address have to point to physical RAM */
209
  ta = (ea & ((RAM_SIZE/2) - 1)) + RAM_START + (RAM_SIZE/2);
210
  tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
211
  debug("tlbtr = %.8lx dtlb_val = %.8lx\n", tlbtr, dtlb_val);
212
 
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
/* 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
 
225
  /* 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
/* ITLB miss exception handler */
255
void itlb_miss_handler (void)
256
{
257
  unsigned long ea, ta, tlbtr;
258
  int set, way = 0;
259
  int i;
260
 
261
  /* Get EA that cause the exception */
262
  ea = mfspr (SPR_EEAR_BASE);
263
 
264
  /* 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
  debug("ea = %.8lx set = %d way = %d\n", ea, set, way);
274
 
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
    mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | ITLB_PR_NOLIMIT);
279
    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
  ta = (ea & ((RAM_SIZE/2) - 1)) + DATA_END_ADD;
288
  tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
289
 
290
  debug("ta = %.8lx\n", ta);
291
 
292
  /* 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
}
296
 
297
/* 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
  ea = mfspr (SPR_EEAR_BASE);
306
 
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
/* 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
  /* Register data page fault handler */
339
  excpt_dpfault = (unsigned long)dpage_fault_handler;
340
 
341
  /* Enable DMMU */
342
  lo_dmmu_en ();
343
}
344
 
345
/* Disable DMMU */
346
void dmmu_disable (void)
347
{
348
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
349
}
350
 
351
/* 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
  /* Register instruction page fault handler */
358
  excpt_ipfault = (unsigned long)ipage_fault_handler;
359
 
360
  /* Enable IMMU */
361
  lo_immu_en ();
362
}
363
 
364
/* Disable IMMU */
365
void immu_disable (void)
366
{
367
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
368
}
369
 
370
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
/* 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
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
402
    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
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
406
  }
407
 
408
  /* Set dtlb permisions */
409
  dtlb_val = DTLB_PR_NOLIMIT;
410
 
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
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
419
    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
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
423
  }
424
 
425
  /* Enable DMMU */
426
  dmmu_enable();
427
 
428
  /* Check the pattern */
429
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
430
    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
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
438
    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
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
444
    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
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
448
  }
449
 
450
  /* Check the pattern */
451
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
452
    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
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
460
    REG32(i*PAGE_SIZE) = i;
461
    REG32(((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
462
  }
463
 
464
  /* Set hi -> lo, lo -> hi translation */
465
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
466
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
467
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1 + TLB_DATA_SET_NB)*PAGE_SIZE);
468
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
469
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
470
  }
471
 
472
  /* Check the pattern */
473
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
474
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
475
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
476
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
477
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
478
  }
479
 
480
  /* Write new pattern */
481
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
482
    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
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
491
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
492
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
493
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
494
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
495
  }
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
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
522
    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
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
526
  }
527
 
528
  /* Set dtlb permisions */
529
  dtlb_val = DTLB_PR_NOLIMIT;
530
 
531
  /* Set pattern */
532
  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
 
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
    mtspr (SPR_DTLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | DTLB_PR_NOLIMIT);
547
 
548
    /* Reset DTLB miss counter and EA */
549
    dtlb_miss_count = 0;
550
    dtlb_miss_ea = 0;
551
 
552
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
553
 
554
      /* Read last address of previous page */
555
      tmp = REG32(t_add - 4);
556
      ASSERT(tmp == 0x00112233);
557
      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
      ASSERT(tmp == 0xccddeeff);
572
      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
/* 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
  int i, j;
598
  unsigned long ea, ta;
599
 
600
  /* 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
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
613
    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
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
617
  }
618
 
619
  /* Reset DTLB miss counter and EA */
620
  dtlb_miss_count = 0;
621
  dtlb_miss_ea = 0;
622
 
623
  /* Set dtlb permisions */
624
  dtlb_val = DTLB_PR_NOLIMIT;
625
 
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
  /* Enable DMMU */
632
  dmmu_enable();
633
 
634
  /* 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
  /* Disable DMMU */
670
  dmmu_disable();
671
 
672
  return 0;
673
}
674
 
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
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
750
 
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
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
769
 
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
/* 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
/* 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
  /* Invalidate all entries in ITLB */
847
  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
  /* Set itlb permisions */
863
  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
 
985
      /* 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
/* 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
  int i, j;
1017
  unsigned long ea, ta;
1018
 
1019
  /* 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
  /* Reset ITLB miss counter and EA */
1039
  itlb_miss_count = 0;
1040
  itlb_miss_ea = 0;
1041
 
1042
  /* Set itlb permisions */
1043
  itlb_val = ITLB_PR_NOLIMIT;
1044
 
1045
  /* Resetv ITLBMR for every way */
1046
  for (i = 0; i < ITLB_WAYS; i++) {
1047
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
1048
  }
1049
 
1050
  /* Enable IMMU */
1051
  immu_enable();
1052
 
1053
  /* Perform jumps to address, that is not in ITLB */
1054
  for (i = 0; i < ITLB_WAYS; i++) {
1055
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1056
 
1057
    /* Check if there was ITLB miss */
1058
    ASSERT(itlb_miss_count == (i + 1));
1059
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1060
  }
1061
 
1062
  /* 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
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1069
 
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
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1082
 
1083
    /* Check if there was ITLB miss */
1084
    ASSERT(itlb_miss_count == (i + 1));
1085
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1086
  }
1087
 
1088
  /* Disable IMMU */
1089
  immu_disable ();
1090
 
1091
  return 0;
1092
}
1093
 
1094
/* Permission test
1095
   Set various permissions, perform r/w access
1096
   in user and supervisor mode and check triggering
1097
   of page fault exceptions */
1098
int itlb_premission_test (int set)
1099
{
1100
  int i, j;
1101
  unsigned long ea, ta;
1102
 
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
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
1154
 
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
/* 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
int main (void)
1205
{
1206
  int i, j;
1207
 
1208
  i = j = 0; /* Get rid of warnings */
1209
 
1210
  /* Register bus error handler */
1211
  excpt_buserr = (unsigned long)bus_err_handler;
1212
 
1213
  /* Register illegal insn handler */
1214
  excpt_illinsn = (unsigned long)ill_insn_handler;
1215
 
1216
  /* Register illegal insn handler */
1217
  excpt_syscall = (unsigned long)sys_call_handler;
1218
 
1219
#if 1
1220
  /* Translation test */
1221
  dtlb_translation_test ();
1222
 
1223
  /* Virtual address match test */
1224
#ifndef RTL_SIM
1225
  for (j = 0; j < DTLB_WAYS; j++) {
1226
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1227
      dtlb_match_test (j, i);
1228
  }
1229
#else
1230
  dtlb_match_test (0, DTLB_SETS - 2);
1231
#endif
1232
 
1233
  /* Valid bit testing */
1234
#ifndef RTL_SIM
1235
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1236
    dtlb_valid_bit_test (i);
1237
#else
1238
  dtlb_valid_bit_test (DTLB_SETS - 2);
1239
#endif
1240
 
1241
  /* Permission test */
1242
#ifndef RTL_SIM
1243
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1244
    dtlb_premission_test (i);
1245
#else
1246
  dtlb_premission_test (DTLB_SETS - 2);
1247
#endif
1248
 
1249
  dtlb_ci_test();
1250
#endif
1251
 
1252
#if 1
1253
  /* Translation test */
1254
  itlb_translation_test ();
1255
 
1256
  /* Virtual address match test */
1257
#ifndef RTL_SIM
1258
  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
#else
1263
  itlb_match_test (0, DTLB_SETS - 2);
1264
#endif
1265
 
1266
  /* Valid bit testing */
1267
#ifndef RTL_SIM
1268
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS); i++)
1269
    itlb_valid_bit_test (i);
1270
#else
1271
  itlb_valid_bit_test (ITLB_SETS-1);
1272
#endif
1273
 
1274
  /* Permission test */
1275
#ifndef RTL_SIM
1276
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
1277
    itlb_premission_test (i);
1278
#else
1279
  itlb_premission_test (ITLB_SETS - 2);
1280
#endif
1281
 
1282
  itlb_ci_test();
1283
#endif
1284
 
1285
  report (0xdeaddead);
1286
  exit (0);
1287
  return 0;
1288
}
1289
 

powered by: WebSVN 2.1.0

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