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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [testbench/] [except_test.c] - Blame information for rev 619

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

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

powered by: WebSVN 2.1.0

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