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 582

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 458 julius
// Tests most functions of the MMUs.
31
// The tests attempt to keep the areas of instruction and data memory working 
32
// as they should, while testing around them, higher in memory. Some linker 
33
// variables are relied upon by the interrupt routines for checking if areas 
34
// are within the expected text areas of memory, but usually we just keep 
35
// above the stack (also set in the linker script) and things go OK.
36
 
37
// The tests for translation setup address translation in the MMU from areas 
38
// in the 512kB - 1024kB region (64 sets in OR1200, 8kByte per set) to halfway
39
// through RAM. Usually the sets taht would encompass the actual program are 
40
// skipped (TLB_TEXT_SET_NB) ie, we say how many sets encompass the program 
41
// text for itlb tests and only do tests above it (so, on sets 8-64, meaning 
42
// when we enable the iMMU and say have the execution bits disabled to force a
43
// page fault the program gets to continue and is translated 1-1 while 
44
// accesses to the areas we are testing will cause a page fault) but it should
45
//  still work to test all sets.
46
 
47
// In essense, the tests are aware that they could be operating out of the 
48
// same memory the tests are being performed in and takes care of this.
49
 
50
// The use of the "match_space" variable is for the addresses we'll access 
51
// when a non-1-1 translation will occur, otherwise usually the 
52
// "translate_space" variable by itself is used (it's first setup to the 
53
// desired address, and either data or the return instructions are placed 
54
// where we expect the MMU to translate to)
55
 
56 90 jeremybenn
#include "spr-defs.h"
57
#include "support.h"
58
 
59 458 julius
// Set this to 1 to enable the DMMU tests
60
#define DO_DMMU_TESTS 1
61
 
62
// Symbols defined in linker script
63
extern unsigned long _ram_end;
64
extern unsigned long _src_beg;
65
 
66
unsigned long text_begin_addr;
67
unsigned long end_data_addr;
68
 
69 90 jeremybenn
/* For shorter simulation run */
70
#define RTL_SIM 1
71
 
72
/* Define RAM physical location and size
73 458 julius
Bottom half will be used for this program, the rest
74
will be used for testing */
75 90 jeremybenn
#define RAM_START   0x00000000
76 458 julius
// Assume only 2MB memory
77 90 jeremybenn
#define RAM_SIZE    0x00200000
78
 
79 458 julius
#define VM_BASE 0xc0000000
80
 
81 90 jeremybenn
/* What is the last address in ram that is used by this program */
82 458 julius
#define TEXT_START_ADD text_begin_addr
83
#define TEXT_END_ADD end_data_addr
84
#define DATA_END_ADD end_data_addr
85 90 jeremybenn
 
86 458 julius
// Uncomment the following to determine the page to test from at run-time
87
unsigned long TLB_TEXT_SET_NB;
88
unsigned long TLB_DATA_SET_NB;
89 90 jeremybenn
 
90
/* MMU page size */
91
#define PAGE_SIZE 8192
92
 
93
/* Number of DTLB sets used (power of 2, max is 256) */
94
#define DTLB_SETS 64
95 458 julius
 
96 90 jeremybenn
/* Number of DTLB ways (1, 2, 3 etc., max is 4). */
97
#define DTLB_WAYS 1
98
 
99
/* Number of ITLB sets used (power of 2, max is 256) */
100
#define ITLB_SETS 64
101
 
102
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
103
#define ITLB_WAYS 1
104
 
105
/* TLB mode codes */
106
#define TLB_CODE_ONE_TO_ONE     0x00000000
107
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
108
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
109
 
110
#define TLB_CODE_MASK   0xfffff000
111
#define TLB_PR_MASK     0x00000fff
112
#define DTLB_PR_NOLIMIT  (SPR_DTLBTR_URE  | \
113
                          SPR_DTLBTR_UWE  | \
114
                          SPR_DTLBTR_SRE  | \
115
                          SPR_DTLBTR_SWE  )
116
 
117
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
118
                          SPR_ITLBTR_UXE  )
119
 
120
 
121 458 julius
 
122 90 jeremybenn
/* fails if x is false */
123
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
124
 
125 458 julius
// iMMU and dMMU enable functions
126 90 jeremybenn
extern void lo_dmmu_en (void);
127
extern void lo_immu_en (void);
128
 
129
/* Local functions prototypes */
130
void dmmu_disable (void);
131
void immu_disable (void);
132
 
133 458 julius
// Machine code for l.jr r9 and then l.nop
134
#define OR32_L_JR_R9 0x44004800
135
#define OR32_L_NOP 0x15000000
136
 
137 90 jeremybenn
/* Global variables */
138
extern unsigned long ram_end;
139
 
140
/* DTLB mode status */
141
volatile unsigned long dtlb_val;
142
 
143
/* ITLB mode status */
144
volatile unsigned long itlb_val;
145
 
146
/* DTLB miss counter */
147
volatile int dtlb_miss_count;
148
 
149
/* Data page fault counter */
150
volatile int dpage_fault_count;
151
 
152
/* ITLB miss counter */
153
volatile int itlb_miss_count;
154
 
155
/* Instruction page fault counter */
156
volatile int ipage_fault_count;
157
 
158
/* EA of last DTLB miss exception */
159
unsigned long dtlb_miss_ea;
160
 
161
/* EA of last data page fault exception */
162
unsigned long dpage_fault_ea;
163
 
164
/* EA of last ITLB miss exception */
165
unsigned long itlb_miss_ea;
166
 
167
/* EA of last insn page fault exception */
168
unsigned long ipage_fault_ea;
169
 
170 458 julius
 
171
#define sys_call() __asm__ __volatile__("l.sys\t0");
172
/*
173 90 jeremybenn
void sys_call (void)
174
{
175
  asm("l.sys\t0");
176
}
177 458 julius
*/
178 90 jeremybenn
void fail (char *func, int line)
179
{
180
#ifndef __FUNCTION__
181
#define __FUNCTION__ "?"
182
#endif
183
 
184
  /* Trigger sys call exception to enable supervisor mode again */
185
  sys_call ();
186
 
187
  immu_disable ();
188
  dmmu_disable ();
189
 
190 458 julius
  report(line);
191 90 jeremybenn
  report (0xeeeeeeee);
192
  exit (1);
193
}
194
 
195
void call(unsigned long add)
196
{
197 458 julius
  asm("l.jalr\t\t%0" : : "r" (add) : "r9", "r11");
198
  asm("l.nop" : :);
199 90 jeremybenn
}
200
 
201
void jump(void)
202
{
203 458 julius
  return;
204
  /*asm("_jr:");
205
  asm("l.jr\t\tr9") ;
206
  asm("l.nop" : :);*/
207 90 jeremybenn
}
208
 
209
void copy_jump(unsigned long phy_add)
210
{
211 458 julius
  memcpy((void *)phy_add, (void *)&jump, (8*4));
212 90 jeremybenn
}
213
 
214
/* Bus error exception handler */
215
void bus_err_handler (void)
216
{
217
  /* This shouldn't happend */
218 458 julius
  printf("Test failed: Bus error\n");
219 90 jeremybenn
  report (0xeeeeeeee);
220
  exit (1);
221
}
222
 
223
/* Illegal insn exception handler */
224
void ill_insn_handler (void)
225
{
226
  /* This shouldn't happend */
227 458 julius
  printf("Test failed: Illegal insn\n");
228 90 jeremybenn
  report (0xeeeeeeee);
229
  exit (1);
230
}
231
 
232
/* Sys call exception handler */
233
void sys_call_handler (void)
234
{
235
  /* Set supervisor mode */
236
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) | SPR_SR_SM);
237
}
238
 
239
/* DTLB miss exception handler */
240
void dtlb_miss_handler (void)
241
{
242
  unsigned long ea, ta, tlbtr;
243
  int set, way = 0;
244
  int i;
245
 
246
  /* Get EA that cause the exception */
247
  ea = mfspr (SPR_EEAR_BASE);
248
 
249
  /* Find TLB set and LRU way */
250
  set = (ea / PAGE_SIZE) % DTLB_SETS;
251
  for (i = 0; i < DTLB_WAYS; i++) {
252
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
253
      way = i;
254
      break;
255
    }
256
  }
257
 
258 458 julius
  printf("dtlb miss ea = %.8lx set = %d way = %d\n", ea, set, way);
259 90 jeremybenn
 
260 458 julius
  // Anything under the stack belongs to the program, direct tranlsate it
261
  if (ea < (unsigned long)&_ram_end){
262 90 jeremybenn
    /* If this is acces to data of this program set one to one translation */
263
    mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
264
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
265
    return;
266
  }
267
 
268
  /* Update DTLB miss counter and EA */
269
  dtlb_miss_count++;
270
  dtlb_miss_ea = ea;
271
 
272 458 julius
  // Everything gets translated back to the space halfway through RAM
273
  ta = (set*PAGE_SIZE) + RAM_START + (RAM_SIZE/2);
274 90 jeremybenn
  tlbtr = (ta & SPR_DTLBTR_PPN) | (dtlb_val & TLB_PR_MASK);
275 458 julius
  printf("ta = %.8lx tlbtr = %.8lx dtlb_val = %.8lx\n",ta, tlbtr, dtlb_val);
276 90 jeremybenn
 
277
  /* Set DTLB entry */
278
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
279
  mtspr (SPR_DTLBTR_BASE(way) + set, tlbtr);
280
}
281
 
282
/* Data page fault exception handler */
283
void dpage_fault_handler (void)
284
{
285
  unsigned long ea;
286
  int set, way = 0;
287
  int i;
288
 
289
  /* Get EA that cause the exception */
290
  ea = mfspr (SPR_EEAR_BASE);
291
 
292
  /* Find TLB set and way */
293
  set = (ea / PAGE_SIZE) % DTLB_SETS;
294
  for (i = 0; i < DTLB_WAYS; i++) {
295 458 julius
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) ==
296
        (ea & SPR_DTLBMR_VPN)) {
297 90 jeremybenn
      way = i;
298
      break;
299
    }
300
  }
301
 
302 458 julius
  printf("ea = %.8lx set = %d way = %d\n", ea, set, way);
303 90 jeremybenn
 
304 458 julius
  if (((RAM_START <= ea) & (ea < DATA_END_ADD) ) |
305
      ((TEXT_START_ADD <= ea) & (ea < TEXT_END_ADD))) {
306 90 jeremybenn
    /* If this is acces to data of this program set one to one translation */
307
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | DTLB_PR_NOLIMIT);
308
    return;
309
  }
310
 
311
  /* Update data page fault counter and EA */
312
  dpage_fault_count++;
313
  dpage_fault_ea = ea;
314
 
315
  /* Give permission */
316 458 julius
  mtspr (SPR_DTLBTR_BASE(way) + set,
317
         (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
318 90 jeremybenn
}
319
 
320
 
321
/* ITLB miss exception handler */
322
void itlb_miss_handler (void)
323
{
324
  unsigned long ea, ta, tlbtr;
325
  int set, way = 0;
326
  int i;
327
 
328
  /* Get EA that cause the exception */
329
  ea = mfspr (SPR_EEAR_BASE);
330
 
331
  /* Find TLB set and LRU way */
332
  set = (ea / PAGE_SIZE) % ITLB_SETS;
333
  for (i = 0; i < ITLB_WAYS; i++) {
334
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
335
      way = i;
336
      break;
337
    }
338
  }
339
 
340 458 julius
  printf("itlb miss ea = %.8lx set = %d way = %d\n", ea, set, way);
341 90 jeremybenn
 
342 458 julius
  if ((TEXT_START_ADD <= ea) && (ea < TEXT_END_ADD)) {
343 90 jeremybenn
    /* If this is acces to data of this program set one to one translation */
344
    mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
345
    mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | ITLB_PR_NOLIMIT);
346
    return;
347
  }
348
 
349
  /* Update ITLB miss counter and EA */
350
  itlb_miss_count++;
351
  itlb_miss_ea = ea;
352
 
353 458 julius
  /* Whatever access is in progress, translated address have to point to
354
     physical RAM */
355
 
356
  ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
357 90 jeremybenn
  tlbtr = (ta & SPR_ITLBTR_PPN) | (itlb_val & TLB_PR_MASK);
358
 
359 458 julius
  printf("ta = %.8lx\n", ta);
360 90 jeremybenn
 
361
  /* Set ITLB entry */
362
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
363
  mtspr (SPR_ITLBTR_BASE(way) + set, tlbtr);
364
}
365
 
366
/* Intstruction page fault exception handler */
367
void ipage_fault_handler (void)
368
{
369
  unsigned long ea;
370
  int set, way = 0;
371
  int i;
372
 
373
  /* Get EA that cause the exception */
374
  ea = mfspr (SPR_EEAR_BASE);
375
 
376
  /* Find TLB set and way */
377
  set = (ea / PAGE_SIZE) % ITLB_SETS;
378
  for (i = 0; i < ITLB_WAYS; i++) {
379
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_VPN) == (ea & SPR_ITLBMR_VPN)) {
380
      way = i;
381
      break;
382
    }
383
  }
384
 
385 458 julius
  printf("ipage fault: ea = %.8lx set = %d way = %d\n", ea, set, way);
386 90 jeremybenn
 
387 458 julius
  if ((TEXT_START_ADD <= ea) && (ea < TEXT_END_ADD)) {
388 90 jeremybenn
    /* If this is acces to data of this program set one to one translation */
389
    mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | ITLB_PR_NOLIMIT);
390
    return;
391
  }
392 458 julius
 
393
  printf("ipage fault was outside of code area\n");
394
 
395 90 jeremybenn
  /* Update instruction page fault counter and EA */
396
  ipage_fault_count++;
397
  ipage_fault_ea = ea;
398
 
399
  /* Give permission */
400
  mtspr (SPR_ITLBTR_BASE(way) + set, (mfspr (SPR_ITLBTR_BASE(way) + set) & ~ITLB_PR_NOLIMIT) | itlb_val);
401
}
402
 
403
/* Invalidate all entries in DTLB and enable DMMU */
404
void dmmu_enable (void)
405
{
406
  /* Register DTLB miss handler */
407 458 julius
        //add_handler(0x9, dtlb_miss_handler);
408
   excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
409 90 jeremybenn
 
410
  /* Register data page fault handler */
411 458 julius
  //add_handler(0x3, dpage_fault_handler);
412 90 jeremybenn
  excpt_dpfault = (unsigned long)dpage_fault_handler;
413
 
414
  /* Enable DMMU */
415
  lo_dmmu_en ();
416 458 julius
 
417 90 jeremybenn
}
418
 
419
/* Disable DMMU */
420
void dmmu_disable (void)
421
{
422
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
423
}
424
 
425
/* Invalidate all entries in ITLB and enable IMMU */
426
void immu_enable (void)
427
{
428
  /* Register ITLB miss handler */
429 458 julius
  //add_handler(0xa, itlb_miss_handler);
430 90 jeremybenn
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
431 458 julius
 
432 90 jeremybenn
  /* Register instruction page fault handler */
433 458 julius
  //add_handler(0x4, ipage_fault_handler);
434 90 jeremybenn
  excpt_ipfault = (unsigned long)ipage_fault_handler;
435
 
436
  /* Enable IMMU */
437
  lo_immu_en ();
438 458 julius
 
439 90 jeremybenn
}
440
 
441
/* Disable IMMU */
442
void immu_disable (void)
443
{
444
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
445
}
446
 
447
void write_pattern(unsigned long start, unsigned long end)
448
{
449
  unsigned long add;
450
 
451
  add = start;
452
  while (add < end) {
453
    REG32(add) = add;
454
    add += PAGE_SIZE;
455
  }
456
 
457
}
458
 
459
/* Translation address register test
460 458 julius
Set various translation and check the pattern */
461 90 jeremybenn
int dtlb_translation_test (void)
462
{
463
  int i, j;
464
  unsigned long ea, ta;
465
 
466
  /* Disable DMMU */
467
  dmmu_disable();
468
 
469 458 julius
  printf("dtlb translation test set\n");
470
 
471 90 jeremybenn
  /* Invalidate all entries in DTLB */
472
  for (i = 0; i < DTLB_WAYS; i++) {
473
    for (j = 0; j < DTLB_SETS; j++) {
474
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
475
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
476
    }
477
  }
478
 
479 458 julius
  /* Set one to one translation for program's data space */
480 90 jeremybenn
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
481
    ea = RAM_START + (i*PAGE_SIZE);
482
    ta = RAM_START + (i*PAGE_SIZE);
483
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
484 458 julius
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | (DTLB_PR_NOLIMIT));
485 90 jeremybenn
  }
486
 
487
  /* Set dtlb permisions */
488
  dtlb_val = DTLB_PR_NOLIMIT;
489
 
490
  /* Write test pattern */
491
  for (i = 0; i < DTLB_SETS; i++) {
492 458 julius
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
493
    REG32(ea) = i;
494
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
495
    REG32(ea) = 0xffffffff - i;
496 90 jeremybenn
  }
497
 
498 458 julius
  /* Set one to one translation */
499 90 jeremybenn
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
500
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
501
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
502
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
503
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
504
  }
505
 
506
  /* Enable DMMU */
507
  dmmu_enable();
508
 
509
  /* Check the pattern */
510
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
511
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
512
    ASSERT(REG32(ea) == i);
513
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
514
    ASSERT(REG32(ea) == (0xffffffff - i));
515
  }
516
 
517
  /* Write new pattern */
518
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
519 458 julius
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
520
    REG32(ea) = 0xffffffff - i;
521
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
522
    REG32(ea) = i;
523 90 jeremybenn
  }
524
 
525
  /* Set 0 -> RAM_START + (RAM_SIZE/2) translation */
526
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
527
    ea = i*PAGE_SIZE;
528
    ta = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
529
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
530
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
531
  }
532
 
533
  /* Check the pattern */
534
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
535
    ea = i*PAGE_SIZE;
536
    ASSERT(REG32(ea) == (0xffffffff - i));
537
    ea = ((i + 1)*PAGE_SIZE) - 4;
538
    ASSERT(REG32(ea) == i);
539
  }
540
 
541
  /* Write new pattern */
542
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
543
    REG32(i*PAGE_SIZE) = i;
544 458 julius
    REG32(((i + 1)*PAGE_SIZE) - 4) = 0xffffffff - i;
545 90 jeremybenn
  }
546
 
547
  /* Set hi -> lo, lo -> hi translation */
548
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
549
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
550 458 julius
    ta = RAM_START + (RAM_SIZE/2) + ((DTLB_SETS - i - 1 + TLB_DATA_SET_NB)*
551
                                     PAGE_SIZE);
552 90 jeremybenn
    mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + i, ea | SPR_DTLBMR_V);
553
    mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + i, ta | DTLB_PR_NOLIMIT);
554
  }
555
 
556
  /* Check the pattern */
557
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
558
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
559
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
560
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
561
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
562
  }
563
 
564
  /* Write new pattern */
565
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
566
    REG32(RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE)) = 0xffffffff - i;
567
    REG32(RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4) = i;
568
  }
569
 
570
  /* Disable DMMU */
571
  dmmu_disable();
572
 
573
  /* Check the pattern */
574
  for (i = TLB_DATA_SET_NB; i < DTLB_SETS; i++) {
575
    ea = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
576
    ASSERT(REG32(ea) == (0xffffffff - DTLB_SETS + i + 1 - TLB_DATA_SET_NB));
577
    ea = RAM_START + (RAM_SIZE/2) + ((i + 1)*PAGE_SIZE) - 4;
578
    ASSERT(REG32(ea) == (DTLB_SETS - i - 1 + TLB_DATA_SET_NB));
579
  }
580 458 julius
 
581
  printf("OK\n");
582
  printf("-------------------------------------------\n");
583 90 jeremybenn
 
584
  return 0;
585
}
586
 
587
/* EA match register test
588 458 julius
Shifting one in DTLBMR and performing accesses to boundaries
589
of the page, checking the triggering of exceptions */
590 90 jeremybenn
int dtlb_match_test (int way, int set)
591
{
592
  int i, j, tmp;
593 458 julius
  unsigned long large_offset_addr;
594 90 jeremybenn
  unsigned long ea, ta;
595 458 julius
  unsigned long match_space;
596
  unsigned long translate_space;
597
  unsigned long program_space_offset;
598 90 jeremybenn
 
599
  /* Disable DMMU */
600
  dmmu_disable();
601
 
602 458 julius
  printf("dtlb_match_test - way %d set %d\n",way, set);
603
 
604 90 jeremybenn
  /* Invalidate all entries in DTLB */
605
  for (i = 0; i < DTLB_WAYS; i++) {
606
    for (j = 0; j < DTLB_SETS; j++) {
607
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
608
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
609
    }
610
  }
611
 
612 458 julius
  // Program text/data pages should be 1-1 translation
613 90 jeremybenn
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
614
    ea = RAM_START + (i*PAGE_SIZE);
615
    ta = RAM_START + (i*PAGE_SIZE);
616
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
617
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
618
  }
619
 
620
  /* Set dtlb permisions */
621
  dtlb_val = DTLB_PR_NOLIMIT;
622
 
623 458 julius
  // Determine offset required to skip past area in use by program
624
  program_space_offset = 0;
625
  while (program_space_offset <= DATA_END_ADD)
626
          program_space_offset += (PAGE_SIZE*DTLB_SETS);
627
 
628
  // Setup match area address - based at halfway through RAM, 
629
  // and then offset by the area encompassed by the set we wish to test.
630
  // TODO: Ensure this is on a page boundary
631
  translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
632
 
633 90 jeremybenn
  /* Set pattern */
634 458 julius
  // Last word of page before the one covered by this set
635
  REG32(translate_space - 4) = 0x00112233;
636
 
637
  // First word of page covered by this set
638
  REG32(translate_space) = 0x44556677;
639
 
640
  // Last word of page covered by this set
641
  REG32(translate_space + PAGE_SIZE - 4) = 0x8899aabb;
642
 
643
  // First word of page covered by next set
644
  REG32(translate_space + PAGE_SIZE) = 0xccddeeff;
645 90 jeremybenn
 
646
  /* Enable DMMU */
647
  dmmu_enable();
648
 
649
  /* Shifting one in DTLBMR */
650
  i = 0;
651
 
652 458 julius
  // Setup match space - place we will do accesses to, and have them
653
  // tranlsated into the translate space addresses. Ensure it is above the end
654
  // of the program's space.
655
  match_space = program_space_offset + (set*PAGE_SIZE);
656
 
657
  // This is used to provide a large match offset (ie. virtual address)
658
  // We will offset the match address by this each time. This value is 
659
  // shifted left after each test, ensuring the high bits of address are 
660
  // tested.
661
  large_offset_addr = (PAGE_SIZE*DTLB_SETS); // 8kB * 64, 512KB
662
 
663
  while (large_offset_addr != 0x00000000) {
664
    // Set MATCH register for the areas we will access explicitly, and 
665
    // validate them.
666
    mtspr (SPR_DTLBMR_BASE(way) + set, match_space | SPR_DTLBMR_V);
667
 
668
    // Set TRANSLATE register to the areas where we have set our data
669
    mtspr (SPR_DTLBTR_BASE(way) + set, translate_space | DTLB_PR_NOLIMIT);
670
 
671 90 jeremybenn
    /* Reset DTLB miss counter and EA */
672
    dtlb_miss_count = 0;
673
    dtlb_miss_ea = 0;
674 458 julius
    printf("testing match space %8lx translate space %8lx\n",match_space,
675
           translate_space);
676
    // Only do the test if we won't tread on any memory being used for data
677
    // and stack. It is unlikely this would occur.
678
    if (match_space > DATA_END_ADD){
679
 
680 90 jeremybenn
      /* Read last address of previous page */
681 458 julius
      tmp = REG32(match_space - 4);
682 90 jeremybenn
      ASSERT(tmp == 0x00112233);
683
      ASSERT(dtlb_miss_count == 1);
684
 
685
      /* Read first address of the page */
686 458 julius
      tmp = REG32(match_space);
687 90 jeremybenn
      ASSERT(tmp == 0x44556677);
688
      ASSERT(dtlb_miss_count == 1);
689
 
690
      /* Read last address of the page */
691 458 julius
      tmp = REG32(match_space + PAGE_SIZE - 4);
692 90 jeremybenn
      ASSERT(tmp == 0x8899aabb);
693
      ASSERT(dtlb_miss_count == 1);
694
 
695
      /* Read first address of next page */
696 458 julius
      tmp = REG32(match_space + PAGE_SIZE);
697 90 jeremybenn
      ASSERT(tmp == 0xccddeeff);
698
      ASSERT(dtlb_miss_count == 2);
699
    }
700
 
701
    i++;
702 458 julius
    large_offset_addr = (PAGE_SIZE*DTLB_SETS) << i;
703
    match_space = large_offset_addr + program_space_offset + (set*PAGE_SIZE);
704 90 jeremybenn
 
705 458 julius
    // Clear MR/T for space we just tested
706 90 jeremybenn
    for (j = 0; j < DTLB_WAYS; j++) {
707
      mtspr (SPR_DTLBMR_BASE(j) + ((set - 1) & (DTLB_SETS - 1)), 0);
708
      mtspr (SPR_DTLBMR_BASE(j) + ((set + 1) & (DTLB_SETS - 1)), 0);
709
    }
710
  }
711
 
712
  /* Disable DMMU */
713
  dmmu_disable();
714
 
715 458 julius
  printf("OK\n");
716
  printf("-------------------------------------------\n");
717
 
718 90 jeremybenn
  return 0;
719
}
720
 
721
/* Valid bit test
722 458 julius
Set all ways of one set to be invalid, perform
723
access so miss handler will set them to valid,
724
try access again - there should be no miss exceptions */
725 90 jeremybenn
int dtlb_valid_bit_test (int set)
726
{
727
  int i, j;
728
  unsigned long ea, ta;
729
 
730
  /* Disable DMMU */
731
  dmmu_disable();
732
 
733 458 julius
  printf("dtlb_valid_bit_test, set %d\n", set);
734
 
735 90 jeremybenn
  /* Invalidate all entries in DTLB */
736
  for (i = 0; i < DTLB_WAYS; i++) {
737
    for (j = 0; j < DTLB_SETS; j++) {
738
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
739
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
740
    }
741
  }
742
 
743
  /* Set one to one translation for the use of this program */
744
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
745
    ea = RAM_START + (i*PAGE_SIZE);
746
    ta = RAM_START + (i*PAGE_SIZE);
747
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
748
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
749
  }
750
 
751
  /* Reset DTLB miss counter and EA */
752
  dtlb_miss_count = 0;
753
  dtlb_miss_ea = 0;
754
 
755
  /* Set dtlb permisions */
756
  dtlb_val = DTLB_PR_NOLIMIT;
757
 
758
  /* Resetv DTLBMR for every way */
759
  for (i = 0; i < DTLB_WAYS; i++) {
760
    mtspr (SPR_DTLBMR_BASE(i) + set, 0);
761
  }
762
 
763
  /* Enable DMMU */
764
  dmmu_enable();
765
 
766
  /* Perform writes to address, that is not in DTLB */
767
  for (i = 0; i < DTLB_WAYS; i++) {
768
    REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) = i;
769
 
770
    /* Check if there was DTLB miss */
771
    ASSERT(dtlb_miss_count == (i + 1));
772
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
773
  }
774
 
775
  /* Reset DTLB miss counter and EA */
776
  dtlb_miss_count = 0;
777
  dtlb_miss_ea = 0;
778
 
779
  /* Perform reads to address, that is now in DTLB */
780
  for (i = 0; i < DTLB_WAYS; i++) {
781
    ASSERT(REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) == i);
782
 
783
    /* Check if there was DTLB miss */
784
    ASSERT(dtlb_miss_count == 0);
785
  }
786
 
787
  /* Reset valid bits */
788
  for (i = 0; i < DTLB_WAYS; i++) {
789
    mtspr (SPR_DTLBMR_BASE(i) + set, mfspr (SPR_DTLBMR_BASE(i) + set) & ~SPR_DTLBMR_V);
790
  }
791
 
792
  /* Perform reads to address, that is now in DTLB but is invalid */
793
  for (i = 0; i < DTLB_WAYS; i++) {
794
    ASSERT(REG32(RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)) == i);
795
 
796
    /* Check if there was DTLB miss */
797
    ASSERT(dtlb_miss_count == (i + 1));
798
    ASSERT(dtlb_miss_ea == (RAM_START + RAM_SIZE + (i*DTLB_SETS*PAGE_SIZE) + (set*PAGE_SIZE)));
799
  }
800
 
801
  /* Disable DMMU */
802
  dmmu_disable();
803
 
804 458 julius
  printf("OK\n");
805
  printf("-------------------------------------------\n");
806
 
807 90 jeremybenn
  return 0;
808
}
809
 
810
/* Permission test
811 458 julius
Set various permissions, perform r/w access
812
in user and supervisor mode and chack triggering
813
of page fault exceptions */
814
int dtlb_permission_test (int set)
815 90 jeremybenn
{
816
  int i, j;
817
  unsigned long ea, ta, tmp;
818
 
819 458 julius
  printf("dtlb_permission_test, set %d\n", set);
820
 
821 90 jeremybenn
  /* Disable DMMU */
822
  dmmu_disable();
823
 
824
  /* Invalidate all entries in DTLB */
825
  for (i = 0; i < DTLB_WAYS; i++) {
826
    for (j = 0; j < DTLB_SETS; j++) {
827
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
828
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
829
    }
830
  }
831
 
832
  /* Set one to one translation for the use of this program */
833
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
834
    ea = RAM_START + (i*PAGE_SIZE);
835
    ta = RAM_START + (i*PAGE_SIZE);
836
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
837
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
838
  }
839
 
840
  /* Testing page */
841
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
842
 
843
  /* Set match register */
844
  mtspr (SPR_DTLBMR_BASE(DTLB_WAYS - 1) + set, ea | SPR_DTLBMR_V);
845
 
846
  /* Reset page fault counter and EA */
847
  dpage_fault_count = 0;
848
  dpage_fault_ea = 0;
849
 
850
  /* Enable DMMU */
851
  dmmu_enable();
852
 
853
  /* Write supervisor */
854
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_SWE;
855
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_SWE));
856
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0) = 0x00112233;
857
  ASSERT(dpage_fault_count == 1);
858
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4) = 0x44556677;
859
  ASSERT(dpage_fault_count == 1);
860
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8) = 0x8899aabb;
861
  ASSERT(dpage_fault_count == 1);
862
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12) = 0xccddeeff;
863
  ASSERT(dpage_fault_count == 1);
864
 
865
  /* Read supervisor */
866
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_SRE;
867
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_SRE));
868
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0);
869
  ASSERT(dpage_fault_count == 2);
870
  ASSERT(tmp == 0x00112233);
871
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4);
872
  ASSERT(dpage_fault_count == 2);
873
  ASSERT(tmp == 0x44556677);
874
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8);
875
  ASSERT(dpage_fault_count == 2);
876
  ASSERT(tmp == 0x8899aabb);
877
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12);
878
  ASSERT(dpage_fault_count == 2);
879
  ASSERT(tmp == 0xccddeeff);
880
 
881
  /* Write user */
882
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_UWE;
883
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_UWE));
884
 
885
  /* Set user mode */
886
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
887
 
888
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0) = 0xffeeddcc;
889
  ASSERT(dpage_fault_count == 3);
890
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4) = 0xbbaa9988;
891
  ASSERT(dpage_fault_count == 3);
892
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8) = 0x77665544;
893
  ASSERT(dpage_fault_count == 3);
894
  REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12) = 0x33221100;
895
  ASSERT(dpage_fault_count == 3);
896
 
897
  /* Trigger sys call exception to enable supervisor mode again */
898
  sys_call ();
899
 
900
  /* Read user mode */
901
  dtlb_val = DTLB_PR_NOLIMIT | SPR_DTLBTR_URE;
902
  mtspr (SPR_DTLBTR_BASE(DTLB_WAYS - 1) + set, ea | (DTLB_PR_NOLIMIT & ~SPR_DTLBTR_URE));
903
 
904
  /* Set user mode */
905
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
906
 
907
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 0);
908
  ASSERT(dpage_fault_count == 4);
909
  ASSERT(tmp == 0xffeeddcc);
910
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 4);
911
  ASSERT(dpage_fault_count == 4);
912
  ASSERT(tmp == 0xbbaa9988);
913
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 8);
914
  ASSERT(dpage_fault_count == 4);
915
  ASSERT(tmp == 0x77665544);
916
  tmp = REG32(RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) + 12);
917
  ASSERT(dpage_fault_count == 4);
918
  ASSERT(tmp == 0x33221100);
919
 
920
  /* Trigger sys call exception to enable supervisor mode again */
921
  sys_call ();
922
 
923
  /* Disable DMMU */
924
  dmmu_disable();
925
 
926 458 julius
  printf("OK\n");
927
  printf("-------------------------------------------\n");
928
 
929 90 jeremybenn
  return 0;
930
}
931
 
932 458 julius
 
933
/* Dcache test - check inhibit
934
Write data with cache inhibit on and off, check for coherency
935
 */
936
int dtlb_dcache_test (int set)
937
{
938 90 jeremybenn
  int i, j;
939 458 julius
  unsigned long ea, ta, vmea;
940
 
941
  // Check data cache is present and enabled
942
  if (!(mfspr(SPR_UPR)& SPR_UPR_DCP))
943
    return 0;
944
 
945
  if (!(mfspr(SPR_SR) & SPR_SR_DCE))
946
    return 0;
947
 
948
  printf("dtlb_dcache_test, set %d\n", set);
949
 
950 90 jeremybenn
  /* Disable DMMU */
951
  dmmu_disable();
952 458 julius
 
953 90 jeremybenn
  /* Invalidate all entries in DTLB */
954
  for (i = 0; i < DTLB_WAYS; i++) {
955
    for (j = 0; j < DTLB_SETS; j++) {
956
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
957
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
958
    }
959
  }
960 458 julius
 
961 90 jeremybenn
  /* Set one to one translation for the use of this program */
962
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
963
    ea = RAM_START + (i*PAGE_SIZE);
964
    ta = RAM_START + (i*PAGE_SIZE);
965
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
966 458 julius
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
967
  }
968
 
969 90 jeremybenn
  /* Testing page */
970 458 julius
  ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
971
 
972
  ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
973
 
974
  vmea = VM_BASE + RAM_START + (RAM_SIZE/2) + ((DTLB_SETS-1)*PAGE_SIZE);
975
 
976
  // Set a 1-1 translation for this page without cache inhibited
977
 
978
  /* Set match register */
979
  mtspr (SPR_DTLBMR_BASE(0) + set, ea | SPR_DTLBMR_V);
980
  /* Set translate register */
981
  mtspr (SPR_DTLBTR_BASE(0) + set, ta | DTLB_PR_NOLIMIT);
982
 
983
  // Now set a far-off translation, VM_BASE, for this page with cache inhibited
984
  // Use the last set
985
 
986
  /* Set match register */
987
  mtspr (SPR_DTLBMR_BASE(0) + (DTLB_SETS-1),
988
         vmea | SPR_DTLBMR_V);
989
  /* Set translate register */
990
  mtspr (SPR_DTLBTR_BASE(0) + (DTLB_SETS-1),
991
         ta | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
992
 
993
  /* Enable DMMU */
994
  dmmu_enable();
995
 
996
  // First do a write with the cache inhibited mapping
997
  unsigned long int testwrite_to_be_cached = 0xfeca1d0d ^ set;
998
  REG32((vmea)) = testwrite_to_be_cached;
999
  // Read it back to check that it's the same, this read should get cached
1000
  ASSERT(REG32(ea) == testwrite_to_be_cached);
1001
  // Now write again to the cache inhibited location
1002
  unsigned long int testwrite_not_to_be_cached = 0xbaadbeef ^ set;
1003
  REG32((vmea)) = testwrite_not_to_be_cached;
1004
  // Now check that the cached mapping doesn't read this value back
1005
  ASSERT(REG32(ea) == testwrite_to_be_cached);
1006
 
1007
  // Now disable cache inhibition on the 1-1 mapping
1008
  /* Set translate register */
1009
  mtspr (SPR_DTLBTR_BASE(0) + set,
1010
         ea | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
1011
 
1012
  // Check that we now get the second value we wrote
1013
  testwrite_to_be_cached = testwrite_not_to_be_cached;
1014
  ASSERT(REG32(ea) == testwrite_to_be_cached);
1015
 
1016
  /* Disable DMMU */
1017
  dmmu_disable();
1018
 
1019
  printf("OK\n");
1020
  printf("-------------------------------------------\n");
1021
 
1022 90 jeremybenn
  return 0;
1023 458 julius
 
1024 90 jeremybenn
}
1025
 
1026
/* Translation address register test
1027 458 julius
Set various translation and check the pattern */
1028 90 jeremybenn
int itlb_translation_test (void)
1029
{
1030
  int i, j;
1031 458 julius
  //unsigned long ea, ta;
1032
  unsigned long translate_space;
1033
  unsigned long match_space;
1034
  printf("itlb_translation_test\n");
1035 90 jeremybenn
 
1036
  /* Disable IMMU */
1037
  immu_disable();
1038
 
1039 458 julius
  /* Invalidate all entries in DTLB */
1040 90 jeremybenn
  for (i = 0; i < ITLB_WAYS; i++) {
1041
    for (j = 0; j < ITLB_SETS; j++) {
1042
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1043
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1044
    }
1045
  }
1046
 
1047
  /* Set one to one translation for the use of this program */
1048
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1049 458 julius
          match_space = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1050
          translate_space = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1051
    mtspr (SPR_ITLBMR_BASE(0) + i, match_space | SPR_ITLBMR_V);
1052
    mtspr (SPR_ITLBTR_BASE(0) + i, translate_space | ITLB_PR_NOLIMIT);
1053 90 jeremybenn
  }
1054
 
1055
  /* Set itlb permisions */
1056
  itlb_val = ITLB_PR_NOLIMIT;
1057 458 julius
 
1058 90 jeremybenn
  /* Write test program */
1059
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1060 458 julius
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
1061
    //printf("writing app to 0x%8lx to be translated in set %d\n",translate_space, i);
1062
    REG32(translate_space) = OR32_L_JR_R9;
1063
    REG32(translate_space + 4) = OR32_L_NOP;
1064
    // Now flush this in case DC isn't on write-through
1065
    mtspr(SPR_DCBFR, translate_space);
1066
    mtspr(SPR_DCBFR, translate_space+4);
1067 90 jeremybenn
  }
1068
 
1069 458 julius
  /* Set one to one translation of the last ways of ITLB */
1070 90 jeremybenn
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1071 458 julius
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
1072
    //printf("translate_space: 0x%8lx set %d\n",translate_space, i);
1073
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, translate_space | SPR_ITLBMR_V);
1074
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i,
1075
           translate_space | ITLB_PR_NOLIMIT);
1076 90 jeremybenn
  }
1077
 
1078
  /* Enable IMMU */
1079
  immu_enable();
1080
 
1081 458 julius
  /* Check the tranlsation works by jumping there */
1082 90 jeremybenn
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1083 458 julius
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
1084
    //printf("calling 0x%.8lx - should use set %d\n",translate_space, i);
1085
    call (translate_space);
1086 90 jeremybenn
  }
1087
 
1088
  /* Set hi -> lo, lo -> hi translation */
1089
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1090 458 julius
    match_space = RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE);
1091
    translate_space = RAM_START + (RAM_SIZE/2) +
1092
      (((ITLB_SETS-1)+TLB_TEXT_SET_NB - i)*PAGE_SIZE);
1093
    printf("setting itlb set %d match -> trans = 0x%.8lx -> 0x%.8lx\n",
1094
           i, match_space, translate_space);
1095
    mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + i, match_space | SPR_ITLBMR_V);
1096
    mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + i, translate_space|ITLB_PR_NOLIMIT);
1097 90 jeremybenn
  }
1098
 
1099
  /* Check the pattern */
1100
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1101 458 julius
    match_space = RAM_START + (RAM_SIZE/2) + (((ITLB_SETS-1)+TLB_TEXT_SET_NB - i)*PAGE_SIZE) + (i*0x10);
1102
    printf("immu hi->lo check - calling 0x%.8lx\n",match_space);
1103
    call(match_space);
1104 90 jeremybenn
  }
1105
 
1106
  /* Disable IMMU */
1107
  immu_disable ();
1108
 
1109
  /* Check the pattern */
1110
  for (i = TLB_TEXT_SET_NB; i < ITLB_SETS; i++) {
1111 458 julius
    translate_space = (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
1112
    //call (RAM_START + (RAM_SIZE/2) + (i*PAGE_SIZE) + (i*0x10));
1113
    //printf("immu disabled check of set %d - calling 0x%.8lx\n",i, translate_space);
1114
    call (translate_space);
1115 90 jeremybenn
  }
1116 458 julius
 
1117
  printf("OK\n");
1118
  printf("-------------------------------------------\n");
1119 90 jeremybenn
 
1120
  return 0;
1121
}
1122
 
1123
/* EA match register test
1124 458 julius
Shifting one in ITLBMR and performing accesses to boundaries
1125
of the page, checking the triggering of exceptions */
1126 90 jeremybenn
int itlb_match_test (int way, int set)
1127
{
1128
  int i, j;
1129 458 julius
  unsigned long add;
1130 90 jeremybenn
  unsigned long ea, ta;
1131 458 julius
 
1132
  printf("itlb_match_test\n");
1133 90 jeremybenn
 
1134
  /* Disable IMMU */
1135
  immu_disable();
1136
 
1137
  /* Invalidate all entries in ITLB */
1138
  for (i = 0; i < ITLB_WAYS; i++) {
1139
    for (j = 0; j < ITLB_SETS; j++) {
1140
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1141
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1142
    }
1143
  }
1144
 
1145
  /* Set one to one translation for the use of this program */
1146
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1147 458 julius
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1148
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1149 90 jeremybenn
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1150
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1151
  }
1152
 
1153
  /* Set dtlb permisions */
1154
  itlb_val = ITLB_PR_NOLIMIT;
1155
 
1156
 
1157 458 julius
  // Write program which will just return into these places
1158
  unsigned long translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
1159
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE) - 8);
1160
  REG32(translate_space-8) = OR32_L_JR_R9;
1161
  REG32(translate_space-4) = OR32_L_NOP;
1162
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE));
1163
  REG32(translate_space) = OR32_L_JR_R9;
1164
  REG32(translate_space+4) = OR32_L_NOP;
1165
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE - 8);
1166
  REG32(translate_space + PAGE_SIZE - 8) = OR32_L_JR_R9;
1167
  REG32(translate_space + PAGE_SIZE - 4) = OR32_L_NOP;
1168
  //copy_jump (RAM_START + (RAM_SIZE/2) + (set + 1)*PAGE_SIZE);
1169
  REG32(translate_space + PAGE_SIZE) = OR32_L_JR_R9;
1170
  REG32(translate_space + PAGE_SIZE + 4) = OR32_L_NOP;
1171
  // Flush these areas incase cache doesn't write them through immediately
1172
  mtspr(SPR_DCBFR, translate_space-8);
1173
  mtspr(SPR_DCBFR, translate_space);
1174
  mtspr(SPR_DCBFR, translate_space+4);
1175
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE - 8);
1176
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE - 4);
1177
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE);
1178
  mtspr(SPR_DCBFR, translate_space + PAGE_SIZE + 4);
1179
 
1180 90 jeremybenn
  /* Enable IMMU */
1181
  immu_enable();
1182
 
1183
  /* Shifting one in ITLBMR */
1184
  i = 0;
1185
  add = (PAGE_SIZE*ITLB_SETS);
1186 458 julius
  //t_add = add + (set*PAGE_SIZE);
1187
  // Space we'll access and expect the MMU to translate our requests
1188
  unsigned long match_space = (PAGE_SIZE*DTLB_SETS) + (set*PAGE_SIZE);
1189 90 jeremybenn
  while (add != 0x00000000) {
1190 458 julius
    mtspr (SPR_ITLBMR_BASE(way) + set,  match_space | SPR_ITLBMR_V);
1191
    mtspr (SPR_ITLBTR_BASE(way) + set,  translate_space | ITLB_PR_NOLIMIT);
1192 90 jeremybenn
 
1193
    /* Reset ITLB miss counter and EA */
1194
    itlb_miss_count = 0;
1195
    itlb_miss_ea = 0;
1196
 
1197 458 julius
    //if (((t_add < RAM_START) || (t_add >= DATA_END_ADD)) && ((t_add < TEXT_START_ADD) || (t_add >= TEXT_END_ADD))) {
1198 90 jeremybenn
 
1199
      /* Jump on last address of previous page */
1200 458 julius
      call (match_space - 8);
1201 90 jeremybenn
      ASSERT(itlb_miss_count == 1);
1202
 
1203
      /* Jump on first address of the page */
1204 458 julius
      call (match_space);
1205 90 jeremybenn
      ASSERT(itlb_miss_count == 1);
1206
 
1207
      /* Jump on last address of the page */
1208 458 julius
      call (match_space + PAGE_SIZE - 8);
1209 90 jeremybenn
      ASSERT(itlb_miss_count == 1);
1210
 
1211
      /* Jump on first address of next page */
1212 458 julius
      call (match_space + PAGE_SIZE);
1213 90 jeremybenn
      ASSERT(itlb_miss_count == 2);
1214 458 julius
      //}
1215 90 jeremybenn
 
1216
    i++;
1217
    add = (PAGE_SIZE*ITLB_SETS) << i;
1218 458 julius
    match_space = add + (set*PAGE_SIZE);
1219 90 jeremybenn
 
1220
    for (j = 0; j < ITLB_WAYS; j++) {
1221
      mtspr (SPR_ITLBMR_BASE(j) + ((set - 1) & (ITLB_SETS - 1)), 0);
1222
      mtspr (SPR_ITLBMR_BASE(j) + ((set + 1) & (ITLB_SETS - 1)), 0);
1223
    }
1224
  }
1225
 
1226 458 julius
  printf("OK\n");
1227
  printf("-------------------------------------------\n");
1228
 
1229 90 jeremybenn
  /* Disable IMMU */
1230
  immu_disable();
1231
 
1232
  return 0;
1233
}
1234
 
1235
/* Valid bit test
1236 458 julius
Set all ways of one set to be invalid, perform
1237
access so miss handler will set them to valid,
1238
try access again - there should be no miss exceptions */
1239 90 jeremybenn
int itlb_valid_bit_test (int set)
1240
{
1241
  int i, j;
1242
  unsigned long ea, ta;
1243
 
1244 458 julius
  printf("itlb_valid_bit_test set = %d\n", set);
1245
 
1246 90 jeremybenn
  /* Disable IMMU */
1247
  immu_disable();
1248
 
1249
  /* Invalidate all entries in ITLB */
1250
  for (i = 0; i < ITLB_WAYS; i++) {
1251
    for (j = 0; j < ITLB_SETS; j++) {
1252
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1253
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1254
    }
1255
  }
1256
 
1257
  /* Set one to one translation for the use of this program */
1258
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1259 458 julius
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1260
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1261 90 jeremybenn
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1262
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1263
  }
1264
 
1265
  /* Reset ITLB miss counter and EA */
1266
  itlb_miss_count = 0;
1267
  itlb_miss_ea = 0;
1268
 
1269
  /* Set itlb permisions */
1270
  itlb_val = ITLB_PR_NOLIMIT;
1271
 
1272 458 julius
  /* Resetv ITLBMR for every way after the program code */
1273
  for (i = TLB_TEXT_SET_NB; i < ITLB_WAYS; i++) {
1274 90 jeremybenn
    mtspr (SPR_ITLBMR_BASE(i) + set, 0);
1275
  }
1276
 
1277
  /* Enable IMMU */
1278
  immu_enable();
1279 458 julius
  // Address we'll jump to and expect it to be translated
1280
  unsigned long match_space = (PAGE_SIZE*ITLB_SETS) + (set*PAGE_SIZE);
1281
  // Address that we will actually access
1282
  unsigned long translate_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
1283 90 jeremybenn
  /* Perform jumps to address, that is not in ITLB */
1284 458 julius
  printf("writing program to 0x%.8lx\n", translate_space);
1285
  REG32(translate_space) = OR32_L_JR_R9;
1286
  REG32(translate_space+4) = OR32_L_NOP;
1287
  mtspr(SPR_DCBFR, translate_space);
1288
  mtspr(SPR_DCBFR, translate_space+4);
1289
  printf("jumping to 0x%.8lx, should be itlb miss\n",match_space);
1290
  call (match_space);
1291
 
1292
  /* Check if there was ITLB miss */
1293
  ASSERT(itlb_miss_count == 1);
1294
  ASSERT(itlb_miss_ea == match_space);
1295 90 jeremybenn
 
1296
  /* Reset ITLB miss counter and EA */
1297
  itlb_miss_count = 0;
1298
  itlb_miss_ea = 0;
1299 458 julius
  printf("jumping to 0x%.8lx again - should not be a miss\n", match_space);
1300 90 jeremybenn
  /* Perform jumps to address, that is now in ITLB */
1301 458 julius
  call (match_space);
1302 90 jeremybenn
 
1303 458 julius
  /* Check if there was ITLB miss */
1304
  ASSERT(itlb_miss_count == 0);
1305 90 jeremybenn
 
1306
  /* Reset valid bits */
1307
  for (i = 0; i < ITLB_WAYS; i++) {
1308
    mtspr (SPR_ITLBMR_BASE(i) + set, mfspr (SPR_ITLBMR_BASE(i) + set) & ~SPR_ITLBMR_V);
1309
  }
1310 458 julius
  printf("jumping to 0x%.8lx again - mmu entries invalidated, so should be a miss\n", match_space);
1311 90 jeremybenn
  /* Perform jumps to address, that is now in ITLB but is invalid */
1312 458 julius
  call (match_space);
1313
 
1314
  /* Check if there was ITLB miss */
1315
  ASSERT(itlb_miss_count == 1);
1316
  ASSERT(itlb_miss_ea == match_space);
1317 90 jeremybenn
 
1318
  /* Disable IMMU */
1319
  immu_disable ();
1320
 
1321 458 julius
  printf("OK\n");
1322
  printf("-------------------------------------------\n");
1323
 
1324 90 jeremybenn
  return 0;
1325
}
1326
 
1327
/* Permission test
1328 458 julius
Set various permissions, perform r/w access
1329
in user and supervisor mode and chack triggering
1330
of page fault exceptions */
1331
int itlb_permission_test (int set)
1332 90 jeremybenn
{
1333
  int i, j;
1334
  unsigned long ea, ta;
1335
 
1336 458 julius
  printf("itlb_permission_test set = %d\n", set);
1337
 
1338 90 jeremybenn
  /* Disable IMMU */
1339
  immu_disable();
1340
 
1341
  /* Invalidate all entries in ITLB */
1342
  for (i = 0; i < ITLB_WAYS; i++) {
1343
    for (j = 0; j < ITLB_SETS; j++) {
1344
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
1345
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
1346
    }
1347
  }
1348
 
1349
  /* Set one to one translation for the use of this program */
1350
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
1351 458 julius
          ea = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1352
          ta = /*TEXT_START_ADD +*/ (i*PAGE_SIZE);
1353 90 jeremybenn
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
1354
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
1355
  }
1356
 
1357 458 julius
  // Address that we will actually access
1358
  unsigned long match_space = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
1359
 
1360 90 jeremybenn
  /* Set match register */
1361 458 julius
  mtspr (SPR_ITLBMR_BASE(ITLB_WAYS - 1) + set, match_space | SPR_ITLBMR_V);
1362 90 jeremybenn
 
1363
  /* Reset page fault counter and EA */
1364
  ipage_fault_count = 0;
1365
  ipage_fault_ea = 0;
1366
 
1367
  /* Copy the code */
1368 458 julius
  REG32(match_space+0x0) = OR32_L_JR_R9;
1369
  REG32(match_space+0x4) = OR32_L_NOP;
1370
  REG32(match_space+0x8) = OR32_L_JR_R9;
1371
  REG32(match_space+0xc) = OR32_L_NOP;
1372
  mtspr(SPR_DCBFR, match_space);
1373
  mtspr(SPR_DCBFR, match_space+4);
1374
  mtspr(SPR_DCBFR, match_space+8);
1375
  mtspr(SPR_DCBFR, match_space+12);
1376 90 jeremybenn
 
1377
  /* Enable IMMU */
1378
  immu_enable ();
1379
 
1380
  /* Execute supervisor */
1381 458 julius
  printf("execute disable for supervisor - should cause ipage fault\n");
1382 90 jeremybenn
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
1383 458 julius
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, match_space | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_SXE));
1384
  printf("calling address 0x%.8lx\n", match_space);
1385
  call (match_space);
1386 90 jeremybenn
  ASSERT(ipage_fault_count == 1);
1387 458 julius
  call (match_space + 8);
1388 90 jeremybenn
  ASSERT(ipage_fault_count == 1);
1389
 
1390
  /* Execute user */
1391 458 julius
  printf("execute disable for user - should cause ipage fault\n");
1392 90 jeremybenn
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_UXE;
1393 458 julius
  mtspr (SPR_ITLBTR_BASE(ITLB_WAYS - 1) + set, match_space | (ITLB_PR_NOLIMIT & ~SPR_ITLBTR_UXE));
1394 90 jeremybenn
 
1395
  /* Set user mode */
1396 458 julius
  printf("disabling supervisor mode\n");
1397 90 jeremybenn
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_SM);
1398 458 julius
  printf("calling address 0x%.8lx\n", match_space);
1399
  printf("instruction at jump space: 0x%.8lx\n",REG32(match_space));
1400
  call (match_space);
1401 90 jeremybenn
  ASSERT(ipage_fault_count == 2);
1402 458 julius
  call (match_space + 8);
1403 90 jeremybenn
  ASSERT(ipage_fault_count == 2);
1404
 
1405
  /* Trigger sys call exception to enable supervisor mode again */
1406
  sys_call ();
1407
 
1408
  /* Disable IMMU */
1409
  immu_disable ();
1410
 
1411 458 julius
  printf("OK\n");
1412
  printf("-------------------------------------------\n");
1413 90 jeremybenn
 
1414
  return 0;
1415
}
1416
 
1417
int main (void)
1418
{
1419
  int i, j;
1420
 
1421 458 julius
  text_begin_addr = (unsigned long)&_src_beg;
1422
  end_data_addr = (unsigned long)&_ram_end;
1423
 
1424
  TLB_TEXT_SET_NB =  TLB_DATA_SET_NB = (end_data_addr+PAGE_SIZE) / PAGE_SIZE;
1425
 
1426
  // Some tests check page below, and if this page corresponds with set being
1427
  // used by program's data section, then could mean an incorrect mapping ends
1428
  // up in the TLB cache, which causes the program to do bad things, so to be
1429
  // safe incrementing the number of pages being used by the program.
1430
  TLB_TEXT_SET_NB++;
1431
  TLB_DATA_SET_NB++;
1432
 
1433 90 jeremybenn
  i = j = 0; /* Get rid of warnings */
1434 458 julius
 
1435 90 jeremybenn
  /* Register bus error handler */
1436
  excpt_buserr = (unsigned long)bus_err_handler;
1437
 
1438
  /* Register illegal insn handler */
1439
  excpt_illinsn = (unsigned long)ill_insn_handler;
1440
 
1441
  /* Register illegal insn handler */
1442
  excpt_syscall = (unsigned long)sys_call_handler;
1443
 
1444 458 julius
#if DO_DMMU_TESTS==1
1445
 
1446 90 jeremybenn
  /* Translation test */
1447
  dtlb_translation_test ();
1448 458 julius
 
1449
  printf("DTLB translation tests OK\n");
1450
 
1451 90 jeremybenn
  /* Virtual address match test */
1452
  for (j = 0; j < DTLB_WAYS; j++) {
1453 458 julius
#ifdef SHORT_TEST
1454
    for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
1455
#else
1456 90 jeremybenn
    for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1457 458 julius
#endif
1458 90 jeremybenn
      dtlb_match_test (j, i);
1459
  }
1460 458 julius
  printf("DTLB match tests OK\n");
1461 90 jeremybenn
 
1462
  /* Valid bit testing */
1463 458 julius
 
1464
#ifdef SHORT_TEST
1465
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
1466
#else
1467 90 jeremybenn
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1468
#endif
1469 458 julius
      dtlb_valid_bit_test (i);
1470 90 jeremybenn
 
1471 458 julius
  printf("DTLB valid bit tests OK\n");
1472
 
1473 90 jeremybenn
  /* Permission test */
1474 458 julius
#ifdef SHORT_TEST
1475
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
1476
#else
1477 90 jeremybenn
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
1478
#endif
1479 458 julius
    dtlb_permission_test (i);
1480 90 jeremybenn
 
1481 458 julius
  printf("DTLB permission bit tests OK\n");
1482
 
1483
  /* Data cache test - Disabled for now */
1484
 
1485
#if 0 
1486
#ifdef SHORT_TEST
1487
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
1488
#else
1489
  for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 2); i++)
1490 90 jeremybenn
#endif
1491 458 julius
    dtlb_dcache_test (i);
1492
#endif
1493 90 jeremybenn
 
1494 458 julius
#endif /* end of no DTLB tests */
1495
 
1496
 
1497 90 jeremybenn
  /* Translation test */
1498
  itlb_translation_test ();
1499 458 julius
 
1500
  printf("ITLB translation tests OK\n");
1501 90 jeremybenn
 
1502
  /* Virtual address match test */
1503 458 julius
 
1504 90 jeremybenn
  for (j = 0; j < DTLB_WAYS; j++) {
1505 458 julius
#ifdef SHORT_TEST
1506
  for (i = TLB_DATA_SET_NB + 1; i < (TLB_DATA_SET_NB+4 - 1); i++)
1507
#else
1508
  for (i = TLB_DATA_SET_NB + 1; i < (ITLB_SETS - 1); i++)
1509
#endif
1510 90 jeremybenn
      itlb_match_test (j, i);
1511
  }
1512
 
1513 458 julius
  printf("ITLB match tests OK\n");
1514
 
1515 90 jeremybenn
  /* Valid bit testing */
1516 458 julius
#ifdef SHORT_TEST
1517
  for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
1518 90 jeremybenn
#else
1519 458 julius
  for (i = TLB_DATA_SET_NB; i < (ITLB_SETS - 1); i++)
1520 90 jeremybenn
#endif
1521 458 julius
    itlb_valid_bit_test (i);
1522 90 jeremybenn
 
1523 458 julius
  printf("ITLB valid bit tests OK\n");
1524
 
1525
 
1526 90 jeremybenn
  /* Permission test */
1527 458 julius
#ifdef SHORT_TEST
1528
  for (i = TLB_TEXT_SET_NB; i < (TLB_TEXT_SET_NB + 4); i++)
1529
#else
1530 90 jeremybenn
  for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
1531
#endif
1532 458 julius
    itlb_permission_test (i);
1533 90 jeremybenn
 
1534 458 julius
  printf("ITLB permission tests OK\n");
1535 90 jeremybenn
 
1536 458 julius
  printf("Tests completed\n");
1537 90 jeremybenn
  report (0xdeaddead);
1538 458 julius
  report (0x8000000d);
1539 90 jeremybenn
  exit (0);
1540
}

powered by: WebSVN 2.1.0

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