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

Subversion Repositories or1k

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

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
#define RAM_START   0x40000000
13
#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
#define V_LPINT       5
59
#define V_ALIGN       6
60
#define V_ILLINSN     7
61
#define V_HPINT       8
62
#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
void lp_int_handler (void)
160
{
161
 
162
  /* Disable interrupt recognition */
163
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_EIR);
164
 
165
  except_mask |= 1 << V_LPINT;
166
  except_count++;
167
}
168
 
169
/* High priority interrupt handler */
170
void hp_int_handler (void)
171
{
172
 
173
  /* Disable interrupt recognition */
174
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_EIR);
175
 
176
  except_mask |= 1 << V_HPINT;
177
  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
  /* Disable interrupt recognition */
339
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_EIR);
340
 
341
  /* Set period of one cycle, restartable mode */
342
  mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (period & SPR_TTMR_PERIOD));
343
 
344
  /* Set tick priority */
345
  if (hp_int)
346
    mtspr(SPR_PICPR, mfspr(SPR_PICPR) | (0x00000001L << V_TICK));
347
  else
348
    mtspr(SPR_PICPR, mfspr(SPR_PICPR) & ~(0x00000001L << V_TICK));
349
 
350
  /* Reset counter */
351
  mtspr(SPR_TTCR, 0);
352
 
353
  /* Unmask tick interrupt in PIC */
354
  mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << V_TICK));
355
}
356
 
357
/* Interrupt test */
358
int interrupt_test (void)
359
{
360
  unsigned long ret;
361
  int i;
362
 
363
  /* Init tick timer */
364
  tick_init (1, 1);
365
 
366
  /* Reset except counter */
367
  except_count = 0;
368
  except_mask = 0;
369
  except_pc = 0;
370
  except_ea = 0;
371
 
372
  /* Test normal high priority interrupt trigger */
373
  ret = call ((unsigned long)&int_trigger, 0);
374
  ASSERT(except_count == 1);
375
  ASSERT(except_mask == (1 << V_HPINT));
376
  ASSERT(ret == 0);
377
  ASSERT(except_pc == (unsigned long)int_trigger + 16);
378
 
379 520 simons
#if 0
380 516 markom
  /* Reset except counter */
381
  except_count = 0;
382
  except_mask = 0;
383
  except_pc = 0;
384
  except_ea = 0;
385
 
386
  /* Init tick timer */
387
  tick_init (1, 0);
388
 
389
  /* Test normal low priority interrupt trigger */
390
  ret = call ((unsigned long)&int_trigger, 0);
391
  ASSERT(except_count == 1);
392
  ASSERT(except_mask == (1 << V_LPINT));
393
  ASSERT(ret == 0);
394
  ASSERT(except_pc == (unsigned long)int_trigger + 16);
395
  ASSERT(except_ea == 0);
396 520 simons
#endif
397 516 markom
 
398
  /* Reset except counter */
399
  except_count = 0;
400
  except_mask = 0;
401
  except_pc = 0;
402
  except_ea = 0;
403
 
404
  /* Test inetrrupt in delay slot */
405
  tick_init (10, 1);
406
 
407
  /* Hopefully we will have interrupt recognition between branch insn and delay slot */
408
  except_pc = (unsigned long)&int_loop;
409
  for (i = 0; i < 10; i++) {
410
    call_with_int (except_pc, RAM_START);
411
    ASSERT(except_pc == (unsigned long)&int_loop);
412
  }
413
 
414
  return 0;
415
}
416
 
417
/* ITLB miss test */
418
int itlb_test (void)
419
{
420
  int i, j, ret;
421
  unsigned long ea, ta;
422
 
423
  /* Invalidate all entries in ITLB */
424
  for (i = 0; i < ITLB_WAYS; i++) {
425
    for (j = 0; j < ITLB_SETS; j++) {
426
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
427
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
428
    }
429
  }
430
 
431
  /* Set one to one translation for the use of this program */
432
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
433
    ea = FLASH_START + (i*PAGE_SIZE);
434
    ta = FLASH_START + (i*PAGE_SIZE);
435
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
436
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
437
  }
438
 
439
  /* Set dtlb no permisions */
440
  itlb_val = SPR_ITLBTR_CI;
441
 
442
  /* Reset except counter */
443
  except_count = 0;
444
  except_mask = 0;
445
  except_pc = 0;
446
  except_ea = 0;
447
 
448
  /* Enable IMMU */
449
  immu_enable ();
450
 
451
  /* Copy jump instruction to last location of a page */
452
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_TEXT_SET_NB + 1)*PAGE_SIZE) - 8;
453
  memcpy((void *)ea, (void *)&jump_back, 12);
454
 
455
  /* Check if there was ITLB miss exception */
456
  ret = call (ea, 0);
457
  ASSERT(except_count == 1);
458
  ASSERT(except_mask == (1 << V_ITLB_MISS));
459
  ASSERT(except_pc == ea);
460
  ASSERT(ret == 0);
461
 
462
  /* Set dtlb no permisions */
463
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
464
 
465
  /* Reset except counter */
466
  except_count = 0;
467
  except_mask = 0;
468
  except_pc = 0;
469
  except_ea = 0;
470
 
471
  /* Check if there was IPF miss exception */
472
  ret = call (ea, 0);
473
  ASSERT(except_count == 1);
474
  ASSERT(except_mask == (1 << V_IPF));
475
  ASSERT(except_pc == ea);
476
  ASSERT(ret == 0);
477
 
478
  /* Set dtlb no permisions */
479
  itlb_val = SPR_ITLBTR_CI;
480
 
481
  /* Reset except counter */
482
  except_count = 0;
483
  except_mask = 0;
484
  except_pc = 0;
485
  except_ea = 0;
486
 
487
  /* Check if there was ITLB miss exception */
488
  ret = call (ea, 0);
489
  ASSERT(except_count == 1);
490
  ASSERT(except_mask == (1 << V_ITLB_MISS));
491
  ASSERT(except_pc == ea + 4);
492
  ASSERT(ret == 0);
493
 
494
  /* Set dtlb no permisions */
495
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
496
 
497
  /* Reset except counter */
498
  except_count = 0;
499
  except_mask = 0;
500
  except_pc = 0;
501
  except_ea = 0;
502
 
503
  /* Check if there was IPF exception */
504
  ret = call (ea, 0);
505
  ASSERT(except_count == 1);
506
  ASSERT(except_mask == (1 << V_IPF));
507
  ASSERT(except_pc == ea + 4);
508
  ASSERT(ret == 0);
509
 
510
  /* Reset except counter */
511
  except_count = 0;
512
  except_mask = 0;
513
  except_pc = 0;
514
  except_ea = 0;
515
 
516
  ret = call (ea, 0);
517
  ASSERT(except_count == 0);
518
  ASSERT(ret == 1);
519
 
520
  /* Disable IMMU */
521
  immu_disable ();
522
 
523
  return 0;
524
}
525
 
526
/* DTLB miss test */
527
int dtlb_test (void)
528
{
529
  int i, j, ret;
530
  unsigned long ea, ta;
531
 
532
  /* Invalidate all entries in DTLB */
533
  for (i = 0; i < DTLB_WAYS; i++) {
534
    for (j = 0; j < DTLB_SETS; j++) {
535
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
536
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
537
    }
538
  }
539
 
540
  /* Set one to one translation for the use of this program */
541
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
542
    ea = RAM_START + (i*PAGE_SIZE);
543
    ta = RAM_START + (i*PAGE_SIZE);
544
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
545
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
546
  }
547
 
548
  /* Set dtlb no permisions */
549
  dtlb_val = SPR_DTLBTR_CI;
550
 
551
  /* Reset except counter */
552
  except_count = 0;
553
  except_mask = 0;
554
  except_pc = 0;
555
  except_ea = 0;
556
 
557
  /* Set pattern */
558
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
559
  REG32(ea) = 0x87654321;
560
 
561
  /* Enable DMMU */
562
  dmmu_enable ();
563
 
564
  /* Check if there was DTLB miss exception */
565
  ret = call ((unsigned long)&load_b_acc_32, ea);
566
  ASSERT(except_count == 1);
567
  ASSERT(except_mask == (1 << V_DTLB_MISS));
568
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
569
  ASSERT(except_ea == ea);
570
  ASSERT(ret == 0x12345678);
571
 
572
  /* Set dtlb no permisions */
573
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
574
 
575
  /* Reset except counter */
576
  except_count = 0;
577
  except_mask = 0;
578
  except_pc = 0;
579
  except_ea = 0;
580
 
581
  /* Check if there was DPF miss exception */
582
  ret = call ((unsigned long)&load_b_acc_32, ea);
583
  ASSERT(except_count == 1);
584
  ASSERT(except_mask == (1 << V_DPF));
585
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
586
  ASSERT(except_ea == ea);
587
  ASSERT(ret == 0x12345678);
588
 
589
  /* Reset except counter */
590
  except_count = 0;
591
  except_mask = 0;
592
  except_pc = 0;
593
  except_ea = 0;
594
 
595
  ret = call ((unsigned long)&load_b_acc_32, ea);
596
  ASSERT(except_count == 0);
597
  ASSERT(ret == 0x87654321);
598
 
599
  /* Disable DMMU */
600
  dmmu_disable ();
601
 
602
  return 0;
603
}
604
 
605
/* Bus error test */
606
int buserr_test (void)
607
{
608
  int i, j, ret;
609
  unsigned long ea, ta;
610
 
611
  /* Invalidate all entries in ITLB */
612
  for (i = 0; i < ITLB_WAYS; i++) {
613
    for (j = 0; j < ITLB_SETS; j++) {
614
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
615
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
616
    }
617
  }
618
 
619
  /* Set one to one translation for the use of this program */
620
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
621
    ea = FLASH_START + (i*PAGE_SIZE);
622
    ta = FLASH_START + (i*PAGE_SIZE);
623
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
624
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
625
  }
626
 
627
  /* Invalidate all entries in DTLB */
628
  for (i = 0; i < DTLB_WAYS; i++) {
629
    for (j = 0; j < DTLB_SETS; j++) {
630
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
631
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
632
    }
633
  }
634
 
635
  /* Set one to one translation for the use of this program */
636
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
637
    ea = RAM_START + (i*PAGE_SIZE);
638
    ta = RAM_START + (i*PAGE_SIZE);
639
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
640
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
641
  }
642
 
643
  /* Reset except counter */
644
  except_count = 0;
645
  except_mask = 0;
646
  except_pc = 0;
647
  except_ea = 0;
648
 
649
  /* Set IMMU translation */
650
  ea = RAM_START + (RAM_SIZE) + ((TLB_TEXT_SET_NB)*PAGE_SIZE);
651
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
652
  mtspr (SPR_ITLBMR_BASE(0) + TLB_TEXT_SET_NB, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
653
  mtspr (SPR_ITLBTR_BASE(0) + TLB_TEXT_SET_NB, ((ea + PAGE_SIZE) & SPR_ITLBTR_PPN) | itlb_val);
654
 
655
  /* Enable IMMU */
656
  immu_enable ();
657
 
658
  /* Check if there was bus error exception */
659
  ret = call (ea, 0);
660
  ASSERT(except_count == 1);
661
  ASSERT(except_mask == (1 << V_BERR));
662
  ASSERT(except_pc == ea);
663 525 simons
  ASSERT(except_ea == ea);
664 516 markom
 
665
  /* Disable IMMU */
666
  immu_disable ();
667
 
668
  /* Reset except counter */
669
  except_count = 0;
670
  except_mask = 0;
671
  except_pc = 0;
672
  except_ea = 0;
673
 
674
  /* Copy jump instruction to last location of RAM */
675
  ea = RAM_START + RAM_SIZE - 8;
676
  memcpy((void *)ea, (void *)&jump_back, 8);
677
 
678
  /* Check if there was bus error exception */
679
  ret = call (ea, 0);
680
  ASSERT(except_count == 1);
681
  ASSERT(except_mask == (1 << V_BERR));
682
  ASSERT(except_pc == ea + 4);
683
  ASSERT(except_ea == ea + 8);
684
 
685
  /* Reset except counter */
686
  except_count = 0;
687
  except_mask = 0;
688
  except_pc = 0;
689
  except_ea = 0;
690
 
691
  /* Set DMMU translation */
692
  ea = RAM_START + (RAM_SIZE) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
693
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
694
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
695
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, ((ea + PAGE_SIZE) & SPR_DTLBTR_PPN) | dtlb_val);
696
 
697
  /* Enable DMMU */
698
  dmmu_enable ();
699
 
700
  /* Check if there was bus error exception */
701
  ret = call ((unsigned long)&load_acc_32, ea );
702
  ASSERT(except_count == 1);
703
  ASSERT(except_mask == (1 << V_BERR));
704
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
705 525 simons
  ASSERT(except_ea == ea);
706 516 markom
  ASSERT(ret == 0x12345678);
707
 
708
  /* Disable DMMU */
709
  dmmu_disable ();
710
 
711
  /* Reset except counter */
712
  except_count = 0;
713
  except_mask = 0;
714
  except_pc = 0;
715
  except_ea = 0;
716
 
717
  /* Check if there was bus error exception */
718
  ret = call ((unsigned long)&load_b_acc_32, ea );
719
  ASSERT(except_count == 1);
720
  ASSERT(except_mask == (1 << V_BERR));
721
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
722
  ASSERT(except_ea == ea);
723
  ASSERT(ret == 0x12345678);
724
 
725
  return 0;
726
}
727
 
728
/* Illegal instruction test */
729
int illegal_insn_test (void)
730
{
731
  int ret;
732
 
733
  /* Reset except counter */
734
  except_count = 0;
735
  except_mask = 0;
736
  except_pc = 0;
737
  except_ea = 0;
738
 
739
  /* Set illegal insn */
740
  REG32(RAM_START + 0) = REG32((unsigned long)jump_back + 4);
741
  REG32(RAM_START + 4) = 0xffffffff;
742
 
743
  /* Check if there was illegal insn exception */
744
  ret = call (RAM_START + 4, 0 );
745
  ASSERT(except_count == 1);
746
  ASSERT(except_mask == (1 << V_ILLINSN));
747
  ASSERT(except_pc == RAM_START + 4);
748
 
749
  /* Reset except counter */
750
  except_count = 0;
751
  except_mask = 0;
752
  except_pc = 0;
753
  except_ea = 0;
754
 
755
  /* Check if there was illegal insn exception */
756
  ret = call (RAM_START, 0 );
757
  ASSERT(except_count == 1);
758
  ASSERT(except_mask == (1 << V_ILLINSN));
759
  ASSERT(except_pc == RAM_START);
760
 
761
  return 0;
762
}
763
 
764
/* Align test */
765
int align_test (void)
766
{
767
  int ret;
768
 
769
  /* Reset except counter */
770
  except_count = 0;
771
  except_mask = 0;
772
  except_pc = 0;
773
  except_ea = 0;
774
 
775
  /* Check if there was alignment exception on read insn */
776
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
777
  ASSERT(except_count == 1);
778
  ASSERT(except_mask == (1 << V_ALIGN));
779
  ASSERT(ret == 0x12345678);
780
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
781
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
782
 
783
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
784
  ASSERT(except_count == 2);
785
  ASSERT(except_mask == (1 << V_ALIGN));
786
  ASSERT(ret == 0x12345678);
787
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
788
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
789
 
790
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
791
  ASSERT(except_count == 3);
792
  ASSERT(except_mask == (1 << V_ALIGN));
793
  ASSERT(ret == 0x12345678);
794
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
795
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
796
 
797
  ret = call ((unsigned long)&load_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
798
  ASSERT(except_count == 4);
799
  ASSERT(except_mask == (1 << V_ALIGN));
800
  ASSERT(ret == 0x12345678);
801
  ASSERT(except_pc == ((unsigned long)(load_acc_16) + 8));
802
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
803
 
804
  /* Check alignment exception on write  insn */
805
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
806
  ASSERT(except_count == 5);
807
  ASSERT(except_mask == (1 << V_ALIGN));
808
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
809
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
810
 
811
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
812
  ASSERT(except_count == 6);
813
  ASSERT(except_mask == (1 << V_ALIGN));
814
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
815
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
816
 
817
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
818
  ASSERT(except_count == 7);
819
  ASSERT(except_mask == (1 << V_ALIGN));
820
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
821
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
822
 
823
  call ((unsigned long)&store_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
824
  ASSERT(except_count == 8);
825
  ASSERT(except_mask == (1 << V_ALIGN));
826
  ASSERT(except_pc == ((unsigned long)(store_acc_16) + 8));
827
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
828
 
829
 
830
  ret = call ((unsigned long)&load_b_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
831
  ASSERT(except_count == 9);
832
  ASSERT(except_mask == (1 << V_ALIGN));
833
  ASSERT(ret == 0x12345678);
834
  ASSERT(except_pc == ((unsigned long)(load_b_acc_32) + 8));
835
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
836
 
837
 
838
  return 0;
839
}
840
 
841
/* Trap test */
842
int trap_test (void)
843
{
844
  /* Reset except counter */
845
  except_count = 0;
846
  except_mask = 0;
847
  except_pc = 0;
848
  except_ea = 0;
849
 
850
  /* Check if there was trap exception */
851
  call ((unsigned long)&trap, 0);
852
  ASSERT(except_count == 1);
853
  ASSERT(except_mask == (1 << V_TRAP));
854
  ASSERT(except_pc == (unsigned long)(trap));
855
  ASSERT(except_ea == 0);
856
 
857
  /* Check if there was trap exception */
858
  call ((unsigned long)&b_trap, 0);
859
  ASSERT(except_count == 2);
860
  ASSERT(except_mask == (1 << V_TRAP));
861
  ASSERT(except_pc == (unsigned long)(b_trap));
862
  ASSERT(except_ea == 0);
863
 
864
  return 0;
865
}
866
 
867
/* Range test */
868
int range_test (void)
869
{
870
  /* Reset except counter */
871
  except_count = 0;
872
  except_mask = 0;
873
  except_pc = 0;
874
  except_ea = 0;
875
 
876
  /* Check if there was range exception */
877
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
878
  call ((unsigned long)&range, 0);
879
  ASSERT(except_count == 1);
880
  ASSERT(except_mask == (1 << V_RANGE));
881
  ASSERT(except_pc == (unsigned long)(range));
882
  ASSERT(except_ea == 0);
883
 
884
  /* Check if there was range exception */
885
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
886
  call ((unsigned long)&b_range, 0);
887
  ASSERT(except_count == 2);
888
  ASSERT(except_mask == (1 << V_RANGE));
889
  ASSERT(except_pc == (unsigned long)(b_range));
890
  ASSERT(except_ea == 0);
891
 
892
  return 0;
893
}
894
 
895
/* Exception priority test */
896
void except_priority_test (void)
897
{
898
  int i, j;
899
  unsigned long ea, ta, ret;
900
 
901
  /* Invalidate all entries in ITLB */
902
  for (i = 0; i < ITLB_WAYS; i++) {
903
    for (j = 0; j < ITLB_SETS; j++) {
904
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
905
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
906
    }
907
  }
908
 
909
  /* Set one to one translation for the use of this program */
910
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
911
    ea = FLASH_START + (i*PAGE_SIZE);
912
    ta = FLASH_START + (i*PAGE_SIZE);
913
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
914
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
915
  }
916
 
917
  /* Set dtlb no permisions */
918
  itlb_val = SPR_ITLBTR_CI;
919
 
920
  /* Invalidate all entries in DTLB */
921
  for (i = 0; i < DTLB_WAYS; i++) {
922
    for (j = 0; j < DTLB_SETS; j++) {
923
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
924
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
925
    }
926
  }
927
 
928
  /* Set one to one translation for the use of this program */
929
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
930
    ea = RAM_START + (i*PAGE_SIZE);
931
    ta = RAM_START + (i*PAGE_SIZE);
932
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
933
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
934
  }
935
 
936
  /* Init tick timer */
937
  tick_init (1, 1);
938
 
939
  /* Set dtlb no permisions */
940
  dtlb_val = SPR_DTLBTR_CI;
941
 
942
  /* Reset except counter */
943
  except_count = 0;
944
  except_mask = 0;
945
  except_pc = 0;
946
  except_ea = 0;
947
 
948
  /* Enable IMMU */
949
  immu_enable ();
950
 
951
  /* Check if there was INT exception */
952
  call_with_int (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
953
  ASSERT(except_count == 1);
954
  ASSERT(except_mask == (1 << V_HPINT));
955
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
956
  ASSERT(except_ea == 0);
957
 
958
  /* Reset except counter */
959
  except_count = 0;
960
  except_mask = 0;
961
  except_pc = 0;
962
  except_ea = 0;
963
 
964
  /* Check if there was ITLB exception */
965
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
966
  ASSERT(except_count == 1);
967
  ASSERT(except_mask == (1 << V_ITLB_MISS));
968
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
969
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
970
 
971
  /* Set dtlb permisions */
972
  itlb_val |= SPR_ITLBTR_SXE;
973
 
974
  /* Reset except counter */
975
  except_count = 0;
976
  except_mask = 0;
977
  except_pc = 0;
978
  except_ea = 0;
979
 
980
  /* Check if there was IPF exception */
981
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
982
  ASSERT(except_count == 1);
983
  ASSERT(except_mask == (1 << V_IPF));
984
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
985
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
986
 
987
  /* Reset except counter */
988
  except_count = 0;
989
  except_mask = 0;
990
  except_pc = 0;
991
  except_ea = 0;
992
 
993
  /* Check if there was bus error exception */
994
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
995
  ASSERT(except_count == 1);
996
  ASSERT(except_mask == (1 << V_BERR));
997
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
998
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
999
 
1000
  /* Reset except counter */
1001
  except_count = 0;
1002
  except_mask = 0;
1003
  except_pc = 0;
1004
  except_ea = 0;
1005
 
1006
  /* Disable MMU */
1007
  immu_disable ();
1008
 
1009
  /* Set illegal instruction */
1010
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 0) = 0x00000000;
1011
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4) = 0xffffffff;
1012
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 8) = 0x00000000;
1013
 
1014
  /* Check if there was illegal insn exception */
1015
  call (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4, 0);
1016
  ASSERT(except_count == 1);
1017
  ASSERT(except_mask == (1 << V_ILLINSN));
1018
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4));
1019
  ASSERT(except_ea == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4 ));
1020
 
1021
  /* Reset except counter */
1022
  except_count = 0;
1023
  except_mask = 0;
1024
  except_pc = 0;
1025
  except_ea = 0;
1026
 
1027
  /* Enable DMMU */
1028
  dmmu_enable ();
1029
 
1030
  /* Check if there was alignment exception on read insn */
1031
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
1032
  ASSERT(except_count == 1);
1033
  ASSERT(except_mask == (1 << V_ALIGN));
1034
  ASSERT(ret == 0x12345678);
1035
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1036
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
1037
 
1038
  /* Reset except counter */
1039
  except_count = 0;
1040
  except_mask = 0;
1041
  except_pc = 0;
1042
  except_ea = 0;
1043
 
1044
  /* Check if there was DTLB exception */
1045
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1046
  ASSERT(except_count == 1);
1047
  ASSERT(except_mask == (1 << V_DTLB_MISS));
1048
  ASSERT(ret == 0x12345678);
1049
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1050
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1051
 
1052
  /* Reset except counter */
1053
  except_count = 0;
1054
  except_mask = 0;
1055
  except_pc = 0;
1056
  except_ea = 0;
1057
 
1058
  /* Set dtlb permisions */
1059
  dtlb_val |= SPR_DTLBTR_SRE;
1060
 
1061
  /* Check if there was DPF exception */
1062
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1063
  ASSERT(except_count == 1);
1064
  ASSERT(except_mask == (1 << V_DPF));
1065
  ASSERT(ret == 0x12345678);
1066
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1067
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1068
 
1069
  /* Reset except counter */
1070
  except_count = 0;
1071
  except_mask = 0;
1072
  except_pc = 0;
1073
  except_ea = 0;
1074
 
1075
  /* Check if there was bus error exception */
1076
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1077
  ASSERT(except_count == 1);
1078
  ASSERT(except_mask == (1 << V_BERR));
1079
  ASSERT(ret == 0x12345678);
1080
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1081
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1082
 
1083
  /* Reset except counter */
1084
  except_count = 0;
1085
  except_mask = 0;
1086
  except_pc = 0;
1087
  except_ea = 0;
1088
 
1089
  /* Check if there was trap exception */
1090
  call ((unsigned long)&trap, 0);
1091
  ASSERT(except_count == 1);
1092
  ASSERT(except_mask == (1 << V_TRAP));
1093
  ASSERT(except_pc == (unsigned long)(trap));
1094
  ASSERT(except_ea == 0);
1095
 
1096
  /* Reset except counter */
1097
  except_count = 0;
1098
  except_mask = 0;
1099
  except_pc = 0;
1100
  except_ea = 0;
1101
 
1102
  /* Check if there was range exception */
1103
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
1104
  call ((unsigned long)&range, 0);
1105
  ASSERT(except_count == 1);
1106
  ASSERT(except_mask == (1 << V_RANGE));
1107
  ASSERT(except_pc == (unsigned long)(range));
1108
  ASSERT(except_ea == 0);
1109
}
1110
 
1111
int main (void)
1112
{
1113
  int ret;
1114
 
1115 520 simons
  printf("except_test\n");
1116
 
1117 516 markom
  /* Register bus error handler */
1118
  excpt_buserr = (unsigned long)bus_err_handler;
1119
 
1120
  /* Register illegal insn handler */
1121
  excpt_illinsn = (unsigned long)ill_insn_handler;
1122
 
1123
  /* Register low priority interrupt handler */
1124
  excpt_lpint = (unsigned long)lp_int_handler;
1125
 
1126
  /* Register high priority interrupt handler */
1127
  excpt_hpint = (unsigned long)hp_int_handler;
1128
 
1129
  /* Register ITLB miss handler */
1130
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
1131
 
1132
  /* Register instruction page fault handler */
1133
  excpt_ipfault = (unsigned long)ipage_fault_handler;
1134
 
1135
  /* Register DTLB miss handler */
1136
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
1137
 
1138
  /* Register data page fault handler */
1139
  excpt_dpfault = (unsigned long)dpage_fault_handler;
1140
 
1141
  /* Register trap handler */
1142
  excpt_trap = (unsigned long)trap_handler;
1143
 
1144
  /* Register align handler */
1145
  excpt_align = (unsigned long)align_handler;
1146
 
1147
  /* Register range handler */
1148
  excpt_range = (unsigned long)range_handler;
1149
 
1150
  /* Exception basic test */
1151
  ret = except_basic ();
1152
  ASSERT(ret == 0);
1153
 
1154
  /* Interrupt exception test */
1155
  interrupt_test ();
1156
 
1157
  /* ITLB exception test */
1158
  itlb_test ();
1159
 
1160
  /* DTLB exception test */
1161
  dtlb_test ();
1162
 
1163
  /* Bus error exception test */
1164
  buserr_test ();
1165
 
1166
  /* Illegal insn test */
1167
  illegal_insn_test ();
1168
 
1169
  /* Alignment test */
1170
  align_test ();
1171
 
1172
  /* Trap test */
1173
  trap_test ();
1174
 
1175
  /* Range test */
1176 520 simons
//  range_test ();
1177 516 markom
 
1178
  /* Exception priority test */
1179
  except_priority_test ();
1180
 
1181
  report (0xdeaddead);
1182
  exit (0);
1183
 
1184
  return 0;
1185
}
1186
 

powered by: WebSVN 2.1.0

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