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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [sw/] [mmu/] [mmu.c] - Blame information for rev 81

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

Line No. Rev Author Line
1 25 julius
/* 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 0x04000000
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 8
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 32
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 32
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_CI   | \
47
                          SPR_DTLBTR_URE  | \
48
                          SPR_DTLBTR_UWE  | \
49
                          SPR_DTLBTR_SRE  | \
50
                          SPR_DTLBTR_SWE  )
51
 
52
#define ITLB_PR_NOLIMIT  ( SPR_ITLBTR_CI   | \
53
                          SPR_ITLBTR_SXE  | \
54
                          SPR_ITLBTR_UXE  )
55
 
56
#if 1
57
#define debug printf
58
#else
59
#define debug
60
#endif
61
 
62
/* fails if x is false */
63
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
64
 
65
//#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
 
68
/* Extern functions */
69
extern void lo_dmmu_en (void);
70
extern void lo_immu_en (void);
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
  report(line);
129
  report (0xeeeeeeee);
130 52 julius
  or32_exit (1);
131 25 julius
}
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 52 julius
  or32_exit (1);
158 25 julius
}
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 52 julius
  or32_exit (1);
167 25 julius
}
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
/* Translation address register test
793
   Set various translation and check the pattern */
794
int itlb_translation_test (void)
795
{
796
  int i, j;
797
  unsigned long ea, ta;
798
 
799
  /* Disable IMMU */
800
  immu_disable();
801
 
802
  /* Invalidate all entries in DTLB */
803
  for (i = 0; i < ITLB_WAYS; i++) {
804
    for (j = 0; j < ITLB_SETS; j++) {
805
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
806
      mtspr (SPR_ITLBTR_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_TEXT_SET_NB; i++) {
812
    ea = FLASH_START + (i*PAGE_SIZE);
813
    ta = FLASH_START + (i*PAGE_SIZE);
814
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
815
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
816
  }
817
 
818
  /* Set dtlb permisions */
819
  itlb_val = ITLB_PR_NOLIMIT;
820
 
821
  /* Write test program */
822
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
823
    copy_jump (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
824
  }
825
 
826
  /* Set one to one translation of the last way of ITLB */
827
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
828
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
829
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
830
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
831
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
832
  }
833
 
834
  /* Enable IMMU */
835
  immu_enable();
836
 
837
  /* Check the pattern */
838
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
839
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
840
  }
841
 
842
  /* Set FLASH_END -> RAM_START + (RAM_SIZE/2) translation */
843
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
844
    ea = FLASH_START + FLASH_SIZE + i*PAGE_SIZE;
845
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
846
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
847
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
848
  }
849
 
850
  /* Check the pattern */
851
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
852
    call (FLASH_START + FLASH_SIZE + (i*PAGE_SIZE) + (i*0x10));
853
  }
854
 
855
  /* Set hi -> lo, lo -> hi translation */
856
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
857
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
858
    ta = RAM_START + (RAM_SIZE/2) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*PAGE_SIZE);
859
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, ea | SPR_ITLBMR_V);
860
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, ta | ITLB_PR_NOLIMIT);
861
  }
862
 
863
  /* Check the pattern */
864
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
865
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + ((ITLB_SETS - i - 1 + TLB_TEXT_SET_NB)*0x10));
866
  }
867
 
868
  /* Disable IMMU */
869
  immu_disable ();
870
 
871
  /* Check the pattern */
872
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
873
    call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
874
  }
875
 
876
  return 0;
877
}
878
 
879
/* EA match register test
880
   Shifting one in ITLBMR and performing accesses to boundaries
881
   of the page, checking the triggering of exceptions */
882
int itlb_match_test (int way, int set)
883
{
884
  int i, j;
885
  unsigned long add, t_add;
886
  unsigned long ea, ta;
887
 
888
  /* Disable IMMU */
889
  immu_disable();
890
 
891
  /* Invalidate all entries in ITLB */
892
  for (i = 0; i < ITLB_WAYS; i++) {
893
    for (j = 0; j < ITLB_SETS; j++) {
894
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
895
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
896
    }
897
  }
898
 
899
  /* Set one to one translation for the use of this program */
900
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
901
    ea = FLASH_START + (i*PAGE_SIZE);
902
    ta = FLASH_START + (i*PAGE_SIZE);
903
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
904
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
905
  }
906
 
907
  /* Set dtlb permisions */
908
  itlb_val = ITLB_PR_NOLIMIT;
909
 
910
  /* Set pattern */
911
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 8);
912
  copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE));
913
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 8);
914
  copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE);
915
 
916
  /* Enable IMMU */
917
  immu_enable();
918
 
919
  /* Shifting one in ITLBMR */
920
  i = 0;
921
  add = (PAGE_SIZE*ITLB_SETS);
922
  t_add = add + (set*PAGE_SIZE);
923
  while (add != 0x00000000) {
924
    mtspr (SPR_ITLBMR_BASE(way) + set, t_add | SPR_ITLBMR_V);
925
    mtspr (SPR_ITLBTR_BASE(way) + set, (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE)) | ITLB_PR_NOLIMIT);
926
 
927
    /* Reset ITLB miss counter and EA */
928
    itlb_miss_count = 0;
929
    itlb_miss_ea = 0;
930
 
931
    if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < FLASH_START) || (t_add >= TEXT_END_ADD))) {
932
 
933
      /* Jump on last address of previous page */
934
      call (t_add - 8);
935
      ASSERT(itlb_miss_count == 1);
936
 
937
      /* Jump on first address of the page */
938
      call (t_add);
939
      ASSERT(itlb_miss_count == 1);
940
 
941
      /* Jump on last address of the page */
942
      call (t_add + PAGE_SIZE - 8);
943
      ASSERT(itlb_miss_count == 1);
944
 
945
      /* Jump on first address of next page */
946
      call (t_add + PAGE_SIZE);
947
      ASSERT(itlb_miss_count == 2);
948
    }
949
 
950
    i++;
951
    add = (PAGE_SIZE*ITLB_SETS) << i;
952
    t_add = add + (set*PAGE_SIZE);
953
 
954
    for (j = 0; j < ITLB_WAYS; j++) {
955
      mtspr (SPR_ITLBMR_BASE(j) + ((set - 1) & (ITLB_SETS - 1)), 0);
956
      mtspr (SPR_ITLBMR_BASE(j) + ((set + 1) & (ITLB_SETS - 1)), 0);
957
    }
958
  }
959
 
960
  /* Disable IMMU */
961
  immu_disable();
962
 
963
  return 0;
964
}
965
 
966
/* Valid bit test
967
   Set all ways of one set to be invalid, perform
968
   access so miss handler will set them to valid,
969
   try access again - there should be no miss exceptions */
970
int itlb_valid_bit_test (int set)
971
{
972
  int i, j;
973
  unsigned long ea, ta;
974
 
975
  /* Disable IMMU */
976
  immu_disable();
977
 
978
  /* Invalidate all entries in ITLB */
979
  for (i = 0; i < ITLB_WAYS; i++) {
980
    for (j = 0; j < ITLB_SETS; j++) {
981
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
982
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
983
    }
984
  }
985
 
986
  /* Set one to one translation for the use of this program */
987
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
988
    ea = FLASH_START + (i*PAGE_SIZE);
989
    ta = FLASH_START + (i*PAGE_SIZE);
990
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
991
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
992
  }
993
 
994
  /* Reset ITLB miss counter and EA */
995
  itlb_miss_count = 0;
996
  itlb_miss_ea = 0;
997
 
998
  /* Set itlb permisions */
999
  itlb_val = ITLB_PR_NOLIMIT;
1000
 
1001
  /* Resetv ITLBMR for every way */
1002
  for (i = 0; i < ITLB_WAYS; i++) {
1003
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
1004
  }
1005
 
1006
  /* Enable IMMU */
1007
  immu_enable();
1008
 
1009
  /* Perform jumps to address, that is not in ITLB */
1010
  for (i = 0; i < ITLB_WAYS; i++) {
1011
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1012
 
1013
    /* Check if there was ITLB miss */
1014
    ASSERT(itlb_miss_count == (i + 1));
1015
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1016
  }
1017
 
1018
  /* Reset ITLB miss counter and EA */
1019
  itlb_miss_count = 0;
1020
  itlb_miss_ea = 0;
1021
 
1022
  /* Perform jumps to address, that is now in ITLB */
1023
  for (i = 0; i < ITLB_WAYS; i++) {
1024
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1025
 
1026
    /* Check if there was ITLB miss */
1027
    ASSERT(itlb_miss_count == 0);
1028
  }
1029
 
1030
  /* Reset valid bits */
1031
  for (i = 0; i < ITLB_WAYS; i++) {
1032
    mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V);
1033
  }
1034
 
1035
  /* Perform jumps to address, that is now in ITLB but is invalid */
1036
  for (i = 0; i < ITLB_WAYS; i++) {
1037
    TEST_JUMP(RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE));
1038
 
1039
    /* Check if there was ITLB miss */
1040
    ASSERT(itlb_miss_count == (i + 1));
1041
    ASSERT(itlb_miss_ea == (RAM_START + RAM_SIZE + (i*ITLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
1042
  }
1043
 
1044
  /* Disable IMMU */
1045
  immu_disable ();
1046
 
1047
  return 0;
1048
}
1049
 
1050
/* Permission test
1051
   Set various permissions, perform r/w access
1052
   in user and supervisor mode and chack triggering
1053
   of page fault exceptions */
1054
int itlb_premission_test (int set)
1055
{
1056
  int i, j;
1057
  unsigned long ea, ta;
1058
 
1059
  /* Disable IMMU */
1060
  immu_disable();
1061
 
1062
  /* Invalidate all entries in ITLB */
1063
  for (i = 0; i < ITLB_WAYS; i++) {
1064
    for (j = 0; j < ITLB_SETS; j++) {
1065
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1066
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1067
    }
1068
  }
1069
 
1070
  /* Set one to one translation for the use of this program */
1071
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1072
    ea = FLASH_START + (i*PAGE_SIZE);
1073
    ta = FLASH_START + (i*PAGE_SIZE);
1074
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1075
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1076
  }
1077
 
1078
  /* Testing page */
1079
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
1080
 
1081
  /* Set match register */
1082
  mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + set, ea | SPR_ITLBMR_V);
1083
 
1084
  /* Reset page fault counter and EA */
1085
  ipage_fault_count = 0;
1086
  ipage_fault_ea = 0;
1087
 
1088
  /* Copy the code */
1089
  copy_jump (ea);
1090
  copy_jump (ea + 8);
1091
 
1092
  /* Enable IMMU */
1093
  immu_enable ();
1094
 
1095
  /* Execute supervisor */
1096
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
1097
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_SXE));
1098
 
1099
  call (ea);
1100
  ASSERT(ipage_fault_count == 1);
1101
  call (ea + 8);
1102
  ASSERT(ipage_fault_count == 1);
1103
 
1104
  /* Execute user */
1105
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_UXE;
1106
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, ea | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_UXE));
1107
 
1108
  /* Set user mode */
1109
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
1110
 
1111
  call (ea);
1112
  ASSERT(ipage_fault_count == 2);
1113
  call (ea + 8);
1114
  ASSERT(ipage_fault_count == 2);
1115
 
1116
  /* Trigger sys call exception to enable supervisor mode again */
1117
  sys_call ();
1118
 
1119
  /* Disable IMMU */
1120
  immu_disable ();
1121
 
1122
  return 0;
1123
}
1124
 
1125
int main (void)
1126
{
1127
  int i, j;
1128
 
1129
  i = j = 0; /* Get rid of warnings */
1130
 
1131
  /* Register bus error handler */
1132
  excpt_buserr = (unsigned long)bus_err_handler;
1133
 
1134
  /* Register illegal insn handler */
1135
  excpt_illinsn = (unsigned long)ill_insn_handler;
1136
 
1137
  /* Register illegal insn handler */
1138
  excpt_syscall = (unsigned long)sys_call_handler;
1139
 
1140
#if 0
1141
#if 0  /* Fails on or1ksim when IC/DC enabled */
1142
  /* Translation test */
1143
  dtlb_translation_test ();
1144
 
1145
  /* Virtual address match test */
1146
#ifndef RTL_SIM
1147
  for (j = 0; j < DTLB_WAYS; j++) {
1148
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1149
      dtlb_match_test (j, i);
1150
  }
1151
#else
1152
  dtlb_match_test (0, DTLB_SETS - 2);
1153
#endif
1154
 
1155
  /* Valid bit testing */
1156
#ifndef RTL_SIM
1157
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1158
    dtlb_valid_bit_test (i);
1159
#else
1160
  dtlb_valid_bit_test (DTLB_SETS - 2);
1161
#endif
1162
 
1163
  /* Permission test */
1164
#ifndef RTL_SIM
1165
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1166
    dtlb_premission_test (i);
1167
#else
1168
  dtlb_premission_test (DTLB_SETS - 2);
1169
#endif
1170
 
1171
#endif
1172
 
1173
#if 1 /* OK */
1174
  /* Translation test */
1175
  itlb_translation_test ();
1176
 
1177
  /* Virtual address match test */
1178
#ifndef RTL_SIM
1179
  for (j = 0; j < DTLB_WAYS; j++) {
1180
    for (i = TLB_TEXT_SET_NB + 1; i < (DTLB_SETS - 1); i++)
1181
      itlb_match_test (j, i);
1182
  }
1183
#else
1184
  itlb_match_test (0, DTLB_SETS - 2);
1185
#endif
1186
 
1187
  /* Valid bit testing */
1188
#ifndef RTL_SIM
1189
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS); i++)
1190
    itlb_valid_bit_test (i);
1191
#else
1192
  itlb_valid_bit_test (ITLB_SETS-1);
1193
#endif
1194
 
1195
  /* Permission test */
1196
#ifndef RTL_SIM
1197
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
1198
    itlb_premission_test (i);
1199
#else
1200
  itlb_premission_test (ITLB_SETS - 2);
1201
#endif
1202
 
1203
#endif
1204
#endif
1205
 
1206
  report (0xdeaddead);
1207 52 julius
  or32_exit (0);
1208 25 julius
  return 0;
1209
}
1210
 

powered by: WebSVN 2.1.0

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