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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [except-test/] [except-test.c] - Blame information for rev 458

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

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

powered by: WebSVN 2.1.0

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