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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [orp/] [orp_soc/] [sw/] [except/] [except_test.c] - Blame information for rev 990

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

Line No. Rev Author Line
1 969 lampret
/* 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 0x04000000
11
#define FLASH_SIZE  0x00200000
12
#define RAM_START   0x00000000
13 990 simons
#define RAM_SIZE    0x00400000
14 969 lampret
 
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 6
37
 
38
#define TLB_CODE_MASK   0xffffc000
39
#define TLB_PR_MASK     0x00003fff
40 990 simons
 
41
#define DTLB_PR_NOLIMIT  (SPR_DTLBTR_URE  | \
42 969 lampret
                          SPR_DTLBTR_UWE  | \
43
                          SPR_DTLBTR_SRE  | \
44
                          SPR_DTLBTR_SWE  )
45
 
46 990 simons
#define ITLB_PR_NOLIMIT  (SPR_ITLBTR_SXE  | \
47 969 lampret
                          SPR_ITLBTR_UXE  )
48
 
49
/* fails if x is false */
50
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
51
 
52
/* Exception vectors */
53
#define V_RESET       1
54
#define V_BERR        2
55
#define V_DPF         3
56
#define V_IPF         4
57
#define V_TICK        5
58
#define V_ALIGN       6
59
#define V_ILLINSN     7
60
#define V_INT         8
61
#define V_DTLB_MISS   9
62
#define V_ITLB_MISS   10
63
#define V_RANGE       11
64
#define V_SYS         12
65
#define V_TRAP        14
66
 
67
#if 1
68
#define debug printf
69
#else
70
#define debug
71
#endif
72
 
73
/* Extern functions */
74
extern void lo_dmmu_en (void);
75
extern void lo_immu_en (void);
76
extern unsigned long call (unsigned long add, unsigned long val);
77
extern unsigned long call_with_int (unsigned long add, unsigned long val);
78
extern void trap (void);
79
extern void b_trap (void);
80
extern void range (void);
81
extern void b_range (void);
82
extern int except_basic (void);
83
extern void (*test)(void);
84
extern int load_acc_32 (unsigned long add);
85
extern int load_acc_16 (unsigned long add);
86
extern int store_acc_32 (unsigned long add);
87
extern int store_acc_16 (unsigned long add);
88
extern int load_b_acc_32 (unsigned long add);
89
extern int int_trigger (void);
90
extern int int_loop (void);
91
extern int jump_back (void);
92 990 simons
extern int ic_invalidate (void);
93 969 lampret
 
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
  report(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 tick_handler (void)
160
{
161
 
162
  /* Disable interrupt recognition */
163
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_TEE);
164
 
165
  except_mask |= 1 << V_TICK;
166
  except_count++;
167
}
168
 
169
/* High priority interrupt handler */
170
void int_handler (void)
171
{
172
 
173
  /* Disable interrupt recognition */
174
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_IEE);
175
 
176
  except_mask |= 1 << V_INT;
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 tick timer exception recognition */
339
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
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
  /* 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
  ASSERT(except_mask == (1 << V_TICK));
367
/*  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
  tick_init (100, 1);
378
 
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_VPN | SPR_ITLBMR_V);
408
    mtspr (SPR_ITLBTR_BASE(0) + i, ta & SPR_ITLBTR_PPN| ITLB_PR_NOLIMIT);
409
  }
410
 
411
  /* Set dtlb no permisions */
412 990 simons
  itlb_val = 0;
413 969 lampret
 
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 990 simons
  itlb_val = SPR_ITLBTR_SXE;
436 969 lampret
 
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 990 simons
  itlb_val = 0;
452 969 lampret
 
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 990 simons
  itlb_val = SPR_ITLBTR_SXE;
468 969 lampret
 
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_DTLBMR_VPN | SPR_ITLBMR_V);
517
    mtspr (SPR_DTLBTR_BASE(0) + i, ta & SPR_DTLBTR_PPN | DTLB_PR_NOLIMIT);
518
  }
519
 
520
  /* Set dtlb no permisions */
521 990 simons
  dtlb_val = 0;
522 969 lampret
 
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 990 simons
  dtlb_val = SPR_DTLBTR_SRE;
546 969 lampret
 
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 990 simons
  itlb_val = SPR_ITLBTR_SXE;
624 969 lampret
  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
  ASSERT(except_ea == ea);
636
 
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 990 simons
//  ic_invalidate ();
651
 
652 969 lampret
  /* Check if there was bus error exception */
653
  ret = call (ea, 0);
654
  ASSERT(except_count == 1);
655
  ASSERT(except_mask == (1 << V_BERR));
656
  ASSERT(except_pc == ea + 4);
657
  ASSERT(except_ea == ea + 8);
658
 
659
  /* Reset except counter */
660
  except_count = 0;
661
  except_mask = 0;
662
  except_pc = 0;
663
  except_ea = 0;
664
 
665
  /* Set DMMU translation */
666
  ea = RAM_START + (RAM_SIZE) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
667 990 simons
  dtlb_val = SPR_DTLBTR_SRE;
668 969 lampret
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
669
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, ((ea + PAGE_SIZE) & SPR_DTLBTR_PPN) | dtlb_val);
670
 
671
  /* Enable DMMU */
672
  dmmu_enable ();
673
 
674
  /* Check if there was bus error exception */
675
  ret = call ((unsigned long)&load_acc_32, ea );
676
  ASSERT(except_count == 1);
677
  ASSERT(except_mask == (1 << V_BERR));
678
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
679
  ASSERT(except_ea == ea);
680
  ASSERT(ret == 0x12345678);
681
 
682
  /* Disable DMMU */
683
  dmmu_disable ();
684
 
685
  /* Reset except counter */
686
  except_count = 0;
687
  except_mask = 0;
688
  except_pc = 0;
689
  except_ea = 0;
690
 
691
  /* Check if there was bus error exception */
692
  ret = call ((unsigned long)&load_b_acc_32, ea );
693
  ASSERT(except_count == 1);
694
  ASSERT(except_mask == (1 << V_BERR));
695
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
696
  ASSERT(except_ea == ea);
697
  ASSERT(ret == 0x12345678);
698
 
699
  return 0;
700
}
701
 
702
/* Illegal instruction test */
703
int illegal_insn_test (void)
704
{
705
  int ret;
706
 
707
  /* Reset except counter */
708
  except_count = 0;
709
  except_mask = 0;
710
  except_pc = 0;
711
  except_ea = 0;
712
 
713
  /* Set illegal insn */
714
  REG32(RAM_START + 0) = REG32((unsigned long)jump_back + 4);
715
  REG32(RAM_START + 4) = 0xffffffff;
716
 
717
  /* Check if there was illegal insn exception */
718
  ret = call (RAM_START + 4, 0 );
719
  ASSERT(except_count == 1);
720
  ASSERT(except_mask == (1 << V_ILLINSN));
721
  ASSERT(except_pc == RAM_START + 4);
722
 
723
  /* Reset except counter */
724
  except_count = 0;
725
  except_mask = 0;
726
  except_pc = 0;
727
  except_ea = 0;
728
 
729
  /* Check if there was illegal insn exception */
730
  ret = call (RAM_START, 0 );
731
  ASSERT(except_count == 1);
732
  ASSERT(except_mask == (1 << V_ILLINSN));
733
  ASSERT(except_pc == RAM_START);
734
 
735
  return 0;
736
}
737
 
738
/* Align test */
739
int align_test (void)
740
{
741
  int ret;
742
 
743
  /* Reset except counter */
744
  except_count = 0;
745
  except_mask = 0;
746
  except_pc = 0;
747
  except_ea = 0;
748
 
749
  /* Check if there was alignment exception on read insn */
750
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
751
  ASSERT(except_count == 1);
752
  ASSERT(except_mask == (1 << V_ALIGN));
753
  ASSERT(ret == 0x12345678);
754
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
755
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
756
 
757
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
758
  ASSERT(except_count == 2);
759
  ASSERT(except_mask == (1 << V_ALIGN));
760
  ASSERT(ret == 0x12345678);
761
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
762
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
763
 
764
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
765
  ASSERT(except_count == 3);
766
  ASSERT(except_mask == (1 << V_ALIGN));
767
  ASSERT(ret == 0x12345678);
768
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
769
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
770
 
771
  ret = call ((unsigned long)&load_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
772
  ASSERT(except_count == 4);
773
  ASSERT(except_mask == (1 << V_ALIGN));
774
  ASSERT(ret == 0x12345678);
775
  ASSERT(except_pc == ((unsigned long)(load_acc_16) + 8));
776
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
777
 
778
  /* Check alignment exception on write  insn */
779
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
780
  ASSERT(except_count == 5);
781
  ASSERT(except_mask == (1 << V_ALIGN));
782
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
783
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
784
 
785
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
786
  ASSERT(except_count == 6);
787
  ASSERT(except_mask == (1 << V_ALIGN));
788
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
789
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
790
 
791
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
792
  ASSERT(except_count == 7);
793
  ASSERT(except_mask == (1 << V_ALIGN));
794
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
795
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
796
 
797
  call ((unsigned long)&store_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
798
  ASSERT(except_count == 8);
799
  ASSERT(except_mask == (1 << V_ALIGN));
800
  ASSERT(except_pc == ((unsigned long)(store_acc_16) + 8));
801
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
802
 
803
 
804
  ret = call ((unsigned long)&load_b_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
805
  ASSERT(except_count == 9);
806
  ASSERT(except_mask == (1 << V_ALIGN));
807
  ASSERT(ret == 0x12345678);
808
  ASSERT(except_pc == ((unsigned long)(load_b_acc_32) + 8));
809
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
810
 
811
 
812
  return 0;
813
}
814
 
815
/* Trap test */
816
int trap_test (void)
817
{
818
  /* Reset except counter */
819
  except_count = 0;
820
  except_mask = 0;
821
  except_pc = 0;
822
  except_ea = 0;
823
 
824
  /* Check if there was trap exception */
825
  call ((unsigned long)&trap, 0);
826
  ASSERT(except_count == 1);
827
  ASSERT(except_mask == (1 << V_TRAP));
828
  ASSERT(except_pc == (unsigned long)(trap));
829
 
830
  /* Check if there was trap exception */
831
  call ((unsigned long)&b_trap, 0);
832
  ASSERT(except_count == 2);
833
  ASSERT(except_mask == (1 << V_TRAP));
834
  ASSERT(except_pc == (unsigned long)(b_trap));
835
 
836
  return 0;
837
}
838
 
839
/* Range test */
840
int range_test (void)
841
{
842
  /* Reset except counter */
843
  except_count = 0;
844
  except_mask = 0;
845
  except_pc = 0;
846
  except_ea = 0;
847
 
848
  /* Check if there was range exception */
849
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
850
  call ((unsigned long)&range, 0);
851
  ASSERT(except_count == 1);
852
  ASSERT(except_mask == (1 << V_RANGE));
853
  ASSERT(except_pc == (unsigned long)(range));
854
  ASSERT(except_ea == 0);
855
 
856
  /* Check if there was range exception */
857
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
858
  call ((unsigned long)&b_range, 0);
859
  ASSERT(except_count == 2);
860
  ASSERT(except_mask == (1 << V_RANGE));
861
  ASSERT(except_pc == (unsigned long)(b_range));
862
 
863
  return 0;
864
}
865
 
866
/* Exception priority test */
867
void except_priority_test (void)
868
{
869
  int i, j;
870
  unsigned long ea, ta, ret;
871
 
872
  /* Invalidate all entries in ITLB */
873
  for (i = 0; i < ITLB_WAYS; i++) {
874
    for (j = 0; j < ITLB_SETS; j++) {
875
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
876
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
877
    }
878
  }
879
 
880
  /* Set one to one translation for the use of this program */
881
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
882
    ea = FLASH_START + (i*PAGE_SIZE);
883
    ta = FLASH_START + (i*PAGE_SIZE);
884
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
885
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
886
  }
887
 
888
  /* Set dtlb no permisions */
889 990 simons
  itlb_val = 0;
890 969 lampret
 
891
  /* Invalidate all entries in DTLB */
892
  for (i = 0; i < DTLB_WAYS; i++) {
893
    for (j = 0; j < DTLB_SETS; j++) {
894
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
895
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
896
    }
897
  }
898
 
899
  /* Set one to one translation for the use of this program */
900
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
901
    ea = RAM_START + (i*PAGE_SIZE);
902
    ta = RAM_START + (i*PAGE_SIZE);
903
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
904
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
905
  }
906
 
907
  /* Init tick timer */
908
  tick_init (1, 1);
909
 
910
  /* Set dtlb no permisions */
911 990 simons
  dtlb_val = 0;
912 969 lampret
 
913
  /* Reset except counter */
914
  except_count = 0;
915
  except_mask = 0;
916
  except_pc = 0;
917
  except_ea = 0;
918
 
919
  /* Enable IMMU */
920
  immu_enable ();
921
 
922
  /* Check if there was INT exception */
923
  call_with_int (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
924
  ASSERT(except_count == 1);
925
  ASSERT(except_mask == (1 << V_TICK));
926
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
927
 
928
  /* Reset except counter */
929
  except_count = 0;
930
  except_mask = 0;
931
  except_pc = 0;
932
  except_ea = 0;
933
 
934
  /* Check if there was ITLB exception */
935
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
936
  ASSERT(except_count == 1);
937
  ASSERT(except_mask == (1 << V_ITLB_MISS));
938
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
939
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
940
 
941
  /* Set dtlb permisions */
942
  itlb_val |= SPR_ITLBTR_SXE;
943
 
944
  /* Reset except counter */
945
  except_count = 0;
946
  except_mask = 0;
947
  except_pc = 0;
948
  except_ea = 0;
949
 
950
  /* Check if there was IPF exception */
951
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
952
  ASSERT(except_count == 1);
953
  ASSERT(except_mask == (1 << V_IPF));
954
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
955
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
956
 
957
  /* Reset except counter */
958
  except_count = 0;
959
  except_mask = 0;
960
  except_pc = 0;
961
  except_ea = 0;
962
 
963
  /* Check if there was bus error exception */
964
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
965
  ASSERT(except_count == 1);
966
  ASSERT(except_mask == (1 << V_BERR));
967
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
968
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
969
 
970
  /* Reset except counter */
971
  except_count = 0;
972
  except_mask = 0;
973
  except_pc = 0;
974
  except_ea = 0;
975
 
976
  /* Disable MMU */
977
  immu_disable ();
978
 
979
  /* Set illegal instruction */
980
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 0) = 0x00000000;
981
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4) = 0xffffffff;
982
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 8) = 0x00000000;
983
 
984
  /* Check if there was illegal insn exception */
985
  call (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4, 0);
986
  ASSERT(except_count == 1);
987
  ASSERT(except_mask == (1 << V_ILLINSN));
988
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4));
989
  ASSERT(except_ea == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4 ));
990
 
991
  /* Reset except counter */
992
  except_count = 0;
993
  except_mask = 0;
994
  except_pc = 0;
995
  except_ea = 0;
996
 
997
  /* Enable DMMU */
998
  dmmu_enable ();
999
 
1000
  /* Check if there was alignment exception on read insn */
1001
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
1002
  ASSERT(except_count == 1);
1003
  ASSERT(except_mask == (1 << V_ALIGN));
1004
  ASSERT(ret == 0x12345678);
1005
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1006
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
1007
 
1008
  /* Reset except counter */
1009
  except_count = 0;
1010
  except_mask = 0;
1011
  except_pc = 0;
1012
  except_ea = 0;
1013
 
1014
  /* Check if there was DTLB exception */
1015
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1016
  ASSERT(except_count == 1);
1017
  ASSERT(except_mask == (1 << V_DTLB_MISS));
1018
  ASSERT(ret == 0x12345678);
1019
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1020
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1021
 
1022
  /* Reset except counter */
1023
  except_count = 0;
1024
  except_mask = 0;
1025
  except_pc = 0;
1026
  except_ea = 0;
1027
 
1028
  /* Set dtlb permisions */
1029
  dtlb_val |= SPR_DTLBTR_SRE;
1030
 
1031
  /* Check if there was DPF exception */
1032
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1033
  ASSERT(except_count == 1);
1034
  ASSERT(except_mask == (1 << V_DPF));
1035
  ASSERT(ret == 0x12345678);
1036
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1037
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1038
 
1039
  /* Reset except counter */
1040
  except_count = 0;
1041
  except_mask = 0;
1042
  except_pc = 0;
1043
  except_ea = 0;
1044
 
1045
  /* Check if there was bus error exception */
1046
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
1047
  ASSERT(except_count == 1);
1048
  ASSERT(except_mask == (1 << V_BERR));
1049
  ASSERT(ret == 0x12345678);
1050
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
1051
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
1052
 
1053
  /* Reset except counter */
1054
  except_count = 0;
1055
  except_mask = 0;
1056
  except_pc = 0;
1057
  except_ea = 0;
1058
 
1059
  /* Check if there was trap exception */
1060
  call ((unsigned long)&trap, 0);
1061
  ASSERT(except_count == 1);
1062
  ASSERT(except_mask == (1 << V_TRAP));
1063
  ASSERT(except_pc == (unsigned long)(trap));
1064
 
1065
#if 0
1066
  /* Reset except counter */
1067
  except_count = 0;
1068
  except_mask = 0;
1069
  except_pc = 0;
1070
  except_ea = 0;
1071
 
1072
  /* Check if there was range exception */
1073
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
1074
  call ((unsigned long)&range, 0);
1075
  ASSERT(except_count == 1);
1076
  ASSERT(except_mask == (1 << V_RANGE));
1077
  ASSERT(except_pc == (unsigned long)(range));
1078
  ASSERT(except_ea == 0);
1079
#endif
1080
}
1081
 
1082
int main (void)
1083
{
1084
  int ret;
1085
 
1086
  printf("except_test\n");
1087
 
1088
  /* Register bus error handler */
1089
  excpt_buserr = (unsigned long)bus_err_handler;
1090
 
1091
  /* Register illegal insn handler */
1092
  excpt_illinsn = (unsigned long)ill_insn_handler;
1093
 
1094
  /* Register tick timer exception handler */
1095
  excpt_tick = (unsigned long)tick_handler;
1096
 
1097
  /* Register external interrupt handler */
1098
  excpt_int = (unsigned long)int_handler;
1099
 
1100
  /* Register ITLB miss handler */
1101
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
1102
 
1103
  /* Register instruction page fault handler */
1104
  excpt_ipfault = (unsigned long)ipage_fault_handler;
1105
 
1106
  /* Register DTLB miss handler */
1107
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
1108
 
1109
  /* Register data page fault handler */
1110
  excpt_dpfault = (unsigned long)dpage_fault_handler;
1111
 
1112
  /* Register trap handler */
1113
  excpt_trap = (unsigned long)trap_handler;
1114
 
1115
  /* Register align handler */
1116
  excpt_align = (unsigned long)align_handler;
1117
 
1118
  /* Register range handler */
1119
  excpt_range = (unsigned long)range_handler;
1120
 
1121
  /* Exception basic test */
1122
  ret = except_basic ();
1123
  ASSERT(ret == 0);
1124
 
1125
  /* Interrupt exception test */
1126 974 lampret
  interrupt_test (); // OK
1127 969 lampret
 
1128
  /* ITLB exception test */
1129 974 lampret
  itlb_test (); // OK
1130 969 lampret
 
1131
  /* DTLB exception test */
1132 990 simons
  dtlb_test (); // OK [with enabled IC/DC it fails on or1ksim]
1133 969 lampret
 
1134
  /* Bus error exception test */
1135 990 simons
  buserr_test (); // Doesn't work on or1ksim
1136 969 lampret
 
1137
  /* Illegal insn test */
1138 974 lampret
  illegal_insn_test (); // OK
1139 969 lampret
 
1140
  /* Alignment test */
1141 974 lampret
  align_test (); // OK
1142 969 lampret
 
1143
  /* Trap test */
1144 974 lampret
  trap_test (); // OK
1145 969 lampret
 
1146
  /* Range test */
1147 974 lampret
//  range_test ();  // Doesn't work on or1ksim
1148 969 lampret
 
1149
  /* Exception priority test */
1150 990 simons
  except_priority_test (); // Doesn't work on or1ksim
1151 969 lampret
 
1152
  report (0xdeaddead);
1153
  exit (0);
1154
 
1155
  return 0;
1156
}
1157
 

powered by: WebSVN 2.1.0

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