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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [mmu/] [mmu.c] - Blame information for rev 346

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

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

powered by: WebSVN 2.1.0

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