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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [sw/] [except/] [except_test.c] - Blame information for rev 52

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

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

powered by: WebSVN 2.1.0

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