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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [except-test/] [except-test.c] - Diff between revs 458 and 538

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 458 Rev 538
/* except-test.c. Test of Or1ksim exception handling
/* except-test.c. Test of Or1ksim exception handling
 
 
   Copyright (C) 1999-2006 OpenCores
   Copyright (C) 1999-2006 OpenCores
   Copyright (C) 2010 Embecosm Limited
   Copyright (C) 2010 Embecosm Limited
 
 
   Contributors various OpenCores participants
   Contributors various OpenCores participants
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of OpenRISC 1000 Architectural Simulator.
   This file is part of OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
 
 
/* ----------------------------------------------------------------------------
/* ----------------------------------------------------------------------------
   This code is commented throughout for use with Doxygen.
   This code is commented throughout for use with Doxygen.
   --------------------------------------------------------------------------*/
   --------------------------------------------------------------------------*/
 
 
#include "spr-defs.h"
#include "spr-defs.h"
#include "support.h"
#include "support.h"
#include "int.h"
#include "int.h"
 
 
/* Define RAM physical location and size
/* Define RAM physical location and size
   Bottom half will be used for this program, the rest
   Bottom half will be used for this program, the rest
   will be used for testing */
   will be used for testing */
#define RAM_START   0x00000000
#define RAM_START   0x00000000
#define RAM_SIZE    0x00200000
#define RAM_SIZE    0x00200000
 
 
/* MMU page size */
/* MMU page size */
#define PAGE_SIZE 8192
#define PAGE_SIZE 8192
 
 
/* Number of DTLB sets used (power of 2, max is 256) */
/* Number of DTLB sets used (power of 2, max is 256) */
#define DTLB_SETS 32
#define DTLB_SETS 32
 
 
/* Number of DTLB ways (2, 2, 3 etc., max is 4). */
/* Number of DTLB ways (2, 2, 3 etc., max is 4). */
#define DTLB_WAYS 1
#define DTLB_WAYS 1
 
 
/* Number of ITLB sets used (power of 2, max is 256) */
/* Number of ITLB sets used (power of 2, max is 256) */
#define ITLB_SETS 32
#define ITLB_SETS 32
 
 
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
/* Number of ITLB ways (1, 2, 3 etc., max is 4). */
#define ITLB_WAYS 1
#define ITLB_WAYS 1
 
 
/* TLB mode codes */
/* TLB mode codes */
#define TLB_CODE_ONE_TO_ONE     0x00000000
#define TLB_CODE_ONE_TO_ONE     0x00000000
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
#define TLB_CODE_PLUS_ONE_PAGE  0x10000000
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
#define TLB_CODE_MINUS_ONE_PAGE 0x20000000
 
 
#define TLB_TEXT_SET_NB 8
#define TLB_TEXT_SET_NB 8
#define TLB_DATA_SET_NB 8
#define TLB_DATA_SET_NB 8
 
 
#define TLB_CODE_MASK   0xfffff000
#define TLB_CODE_MASK   0xfffff000
#define TLB_PR_MASK     0x00000fff
#define TLB_PR_MASK     0x00000fff
#define DTLB_PR_NOLIMIT  ( SPR_DTLBTR_CI   | \
#define DTLB_PR_NOLIMIT  ( SPR_DTLBTR_CI   | \
                          SPR_DTLBTR_URE  | \
                          SPR_DTLBTR_URE  | \
                          SPR_DTLBTR_UWE  | \
                          SPR_DTLBTR_UWE  | \
                          SPR_DTLBTR_SRE  | \
                          SPR_DTLBTR_SRE  | \
                          SPR_DTLBTR_SWE  )
                          SPR_DTLBTR_SWE  )
 
 
#define ITLB_PR_NOLIMIT  ( SPR_ITLBTR_CI   | \
#define ITLB_PR_NOLIMIT  ( SPR_ITLBTR_CI   | \
                          SPR_ITLBTR_SXE  | \
                          SPR_ITLBTR_SXE  | \
                          SPR_ITLBTR_UXE  )
                          SPR_ITLBTR_UXE  )
 
 
/* fails if x is false */
/* fails if x is false */
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
#define ASSERT(x) ((x)?1: fail (__FUNCTION__, __LINE__))
 
 
/* Exception vectors */
/* Exception vectors */
#define V_RESET       1
#define V_RESET       1
#define V_BERR        2
#define V_BERR        2
#define V_DPF         3
#define V_DPF         3
#define V_IPF         4
#define V_IPF         4
#define V_TICK        5
#define V_TICK        5
#define V_ALIGN       6
#define V_ALIGN       6
#define V_ILLINSN     7
#define V_ILLINSN     7
#define V_INT         8
#define V_INT         8
#define V_DTLB_MISS   9
#define V_DTLB_MISS   9
#define V_ITLB_MISS   10
#define V_ITLB_MISS   10
#define V_RANGE       11
#define V_RANGE       11
#define V_SYS         12
#define V_SYS         12
#define V_TRAP        14
#define V_TRAP        14
 
 
#define debug printf
#define debug printf
 
 
/* Extern functions */
/* Extern functions */
extern void lo_dmmu_en (void);
extern void lo_dmmu_en (void);
extern void lo_immu_en (void);
extern void lo_immu_en (void);
extern unsigned long call (unsigned long add, unsigned long val);
extern unsigned long call (unsigned long add, unsigned long val);
extern unsigned long call_with_int (unsigned long add, unsigned long val);
extern unsigned long call_with_int (unsigned long add, unsigned long val);
extern void trap (void);
extern void trap (void);
extern void b_trap (void);
extern void b_trap (void);
extern void range (void);
extern void range (void);
extern void b_range (void);
extern void b_range (void);
extern int except_basic (void);
extern int except_basic (void);
extern void (*test)(void);
extern void (*test)(void);
extern int load_acc_32 (unsigned long add);
extern int load_acc_32 (unsigned long add);
extern int load_acc_16 (unsigned long add);
extern int load_acc_16 (unsigned long add);
extern int store_acc_32 (unsigned long add);
extern int store_acc_32 (unsigned long add);
extern int store_acc_16 (unsigned long add);
extern int store_acc_16 (unsigned long add);
extern int load_b_acc_32 (unsigned long add);
extern int load_b_acc_32 (unsigned long add);
extern int int_trigger (void);
extern int int_trigger (void);
extern int int_loop (void);
extern int int_loop (void);
extern int jump_back (void);
extern int jump_back (void);
 
 
/* Local functions prototypes */
/* Local functions prototypes */
void dmmu_disable (void);
void dmmu_disable (void);
void immu_disable (void);
void immu_disable (void);
 
 
/* DTLB mode status */
/* DTLB mode status */
volatile unsigned long dtlb_val;
volatile unsigned long dtlb_val;
 
 
/* ITLB mode status */
/* ITLB mode status */
volatile unsigned long itlb_val;
volatile unsigned long itlb_val;
 
 
/* Exception counter */
/* Exception counter */
volatile int except_count;
volatile int except_count;
 
 
/* Exception mask */
/* Exception mask */
volatile unsigned long except_mask;
volatile unsigned long except_mask;
 
 
/* Exception efective address */
/* Exception efective address */
volatile unsigned long except_ea;
volatile unsigned long except_ea;
 
 
/* Eception PC */
/* Eception PC */
volatile unsigned long except_pc;
volatile unsigned long except_pc;
 
 
unsigned long  excpt_buserr;
unsigned long  excpt_buserr;
unsigned long excpt_dpfault;
unsigned long excpt_dpfault;
unsigned long excpt_ipfault;
unsigned long excpt_ipfault;
unsigned long excpt_tick;
unsigned long excpt_tick;
unsigned long excpt_align;
unsigned long excpt_align;
unsigned long excpt_illinsn;
unsigned long excpt_illinsn;
unsigned long excpt_int;
unsigned long excpt_int;
unsigned long excpt_dtlbmiss;
unsigned long excpt_dtlbmiss;
unsigned long excpt_itlbmiss;
unsigned long excpt_itlbmiss;
unsigned long excpt_range;
unsigned long excpt_range;
unsigned long excpt_syscall;
unsigned long excpt_syscall;
unsigned long excpt_break;
unsigned long excpt_break;
unsigned long excpt_trap;
unsigned long excpt_trap;
 
 
 
 
void fail (char *func, int line)
void fail (char *func, int line)
{
{
#ifndef __FUNCTION__
#ifndef __FUNCTION__
#define __FUNCTION__ "?"
#define __FUNCTION__ "?"
#endif
#endif
 
 
  immu_disable ();
  immu_disable ();
  dmmu_disable ();
  dmmu_disable ();
 
 
  debug("Test failed in %s:%i\n", func, line);
  debug("Test failed in %s:%i\n", func, line);
  report (0xeeeeeeee);
  report (0xeeeeeeee);
  exit (1);
  exit (1);
}
}
 
 
void test_dummy (void)
void test_dummy (void)
{
{
        asm("test:");
        asm("test:");
        asm("l.addi\t\tr3,r3,1") ;
        asm("l.addi\t\tr3,r3,1") ;
        asm("l.nop" : :);
        asm("l.nop" : :);
}
}
 
 
void copy_test (unsigned long phy_add)
void copy_test (unsigned long phy_add)
{
{
        memcpy((void *)phy_add, (void *)&test, 8);
        memcpy((void *)phy_add, (void *)&test, 8);
}
}
 
 
/* Bus error handler */
/* Bus error handler */
void bus_err_handler (void)
void bus_err_handler (void)
{
{
 
 
  except_mask |= 1 << V_BERR;
  except_mask |= 1 << V_BERR;
  except_count++;
  except_count++;
}
}
 
 
/* Illegal insn handler */
/* Illegal insn handler */
void ill_insn_handler (void)
void ill_insn_handler (void)
{
{
  except_mask |= 1 << V_ILLINSN;
  except_mask |= 1 << V_ILLINSN;
  except_count++;
  except_count++;
}
}
 
 
/* Low priority interrupt handler */
/* Low priority interrupt handler */
void tick_handler (void)
void tick_handler (void)
{
{
 
 
  /* Disable interrupt recognition */
  /* Disable interrupt recognition */
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_TEE);
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_TEE);
 
 
  except_mask |= 1 << V_TICK;
  except_mask |= 1 << V_TICK;
  except_count++;
  except_count++;
}
}
 
 
/* High priority interrupt handler */
/* High priority interrupt handler */
void int_handler (void)
void int_handler (void)
{
{
 
 
  /* Disable interrupt recognition */
  /* Disable interrupt recognition */
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_IEE);
  mtspr(SPR_ESR_BASE, mfspr(SPR_ESR_BASE) & ~SPR_SR_IEE);
 
 
  except_mask |= 1 << V_INT;
  except_mask |= 1 << V_INT;
  except_count++;
  except_count++;
}
}
 
 
/* Trap handler */
/* Trap handler */
void trap_handler (void)
void trap_handler (void)
{
{
 
 
  except_mask |= 1 << V_TRAP;
  except_mask |= 1 << V_TRAP;
  except_count++;
  except_count++;
}
}
 
 
/* Align handler */
/* Align handler */
void align_handler (void)
void align_handler (void)
{
{
 
 
  except_mask |= 1 << V_ALIGN;
  except_mask |= 1 << V_ALIGN;
  except_count++;
  except_count++;
}
}
 
 
/* Range handler */
/* Range handler */
void range_handler (void)
void range_handler (void)
{
{
  /* Disable range exception */
  /* Disable range exception */
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) & ~SPR_SR_OVE);
  mtspr (SPR_ESR_BASE, mfspr (SPR_ESR_BASE) & ~SPR_SR_OVE);
 
 
  except_mask |= 1 << V_RANGE;
  except_mask |= 1 << V_RANGE;
  except_count++;
  except_count++;
}
}
 
 
/* DTLB miss exception handler */
/* DTLB miss exception handler */
void dtlb_miss_handler (void)
void dtlb_miss_handler (void)
{
{
  unsigned long ea;
  unsigned long ea;
  int set, way = 0;
  int set, way = 0;
  int i;
  int i;
 
 
  /* Get EA that cause the exception */
  /* Get EA that cause the exception */
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EEAR_BASE);
 
 
  /* Find TLB set and LRU way */
  /* Find TLB set and LRU way */
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_LRU) == 0) {
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
  mtspr (SPR_DTLBMR_BASE(way) + set, (ea & SPR_DTLBMR_VPN) | SPR_DTLBMR_V);
  mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | dtlb_val);
  mtspr (SPR_DTLBTR_BASE(way) + set, (ea & SPR_DTLBTR_PPN) | dtlb_val);
 
 
  except_mask |= 1 << V_DTLB_MISS;
  except_mask |= 1 << V_DTLB_MISS;
  except_count++;
  except_count++;
}
}
 
 
/* ITLB miss exception handler */
/* ITLB miss exception handler */
void itlb_miss_handler (void)
void itlb_miss_handler (void)
{
{
  unsigned long ea;
  unsigned long ea;
  int set, way = 0;
  int set, way = 0;
  int i;
  int i;
 
 
  /* Get EA that cause the exception */
  /* Get EA that cause the exception */
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EEAR_BASE);
 
 
  /* Find TLB set and LRU way */
  /* Find TLB set and LRU way */
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_LRU) == 0) {
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
  mtspr (SPR_ITLBMR_BASE(way) + set, (ea & SPR_ITLBMR_VPN) | SPR_ITLBMR_V);
  mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | itlb_val);
  mtspr (SPR_ITLBTR_BASE(way) + set, (ea & SPR_ITLBTR_PPN) | itlb_val);
  except_mask |= 1 << V_ITLB_MISS;
  except_mask |= 1 << V_ITLB_MISS;
  except_count++;
  except_count++;
}
}
 
 
/* Data page fault exception handler */
/* Data page fault exception handler */
void dpage_fault_handler (void)
void dpage_fault_handler (void)
{
{
  unsigned long ea;
  unsigned long ea;
  int set, way = 0;
  int set, way = 0;
  int i;
  int i;
 
 
  /* Get EA that cause the exception */
  /* Get EA that cause the exception */
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EEAR_BASE);
 
 
  /* Find TLB set and way */
  /* Find TLB set and way */
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  set = (ea / PAGE_SIZE) % DTLB_SETS;
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) == (ea & SPR_DTLBMR_VPN)) {
    if ((mfspr (SPR_DTLBMR_BASE(i) + set) & SPR_DTLBMR_VPN) == (ea & SPR_DTLBMR_VPN)) {
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  /* Give permission */
  /* Give permission */
  mtspr (SPR_DTLBTR_BASE(way) + set, (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
  mtspr (SPR_DTLBTR_BASE(way) + set, (mfspr (SPR_DTLBTR_BASE(way) + set) & ~DTLB_PR_NOLIMIT) | dtlb_val);
 
 
  except_mask |= 1 << V_DPF;
  except_mask |= 1 << V_DPF;
  except_count++;
  except_count++;
}
}
 
 
/* Intstruction page fault exception handler */
/* Intstruction page fault exception handler */
void ipage_fault_handler (void)
void ipage_fault_handler (void)
{
{
  unsigned long ea;
  unsigned long ea;
  int set, way = 0;
  int set, way = 0;
  int i;
  int i;
 
 
  /* Get EA that cause the exception */
  /* Get EA that cause the exception */
  ea = mfspr (SPR_EEAR_BASE);
  ea = mfspr (SPR_EEAR_BASE);
 
 
  /* Find TLB set and way */
  /* Find TLB set and way */
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  set = (ea / PAGE_SIZE) % ITLB_SETS;
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_VPN) == (ea & SPR_ITLBMR_VPN)) {
    if ((mfspr (SPR_ITLBMR_BASE(i) + set) & SPR_ITLBMR_VPN) == (ea & SPR_ITLBMR_VPN)) {
      way = i;
      way = i;
      break;
      break;
    }
    }
  }
  }
 
 
  /* Give permission */
  /* Give permission */
  mtspr (SPR_ITLBTR_BASE(way) + set, (mfspr (SPR_ITLBTR_BASE(way) + set) & ~ITLB_PR_NOLIMIT) | itlb_val);
  mtspr (SPR_ITLBTR_BASE(way) + set, (mfspr (SPR_ITLBTR_BASE(way) + set) & ~ITLB_PR_NOLIMIT) | itlb_val);
 
 
  except_mask |= 1 << V_IPF;
  except_mask |= 1 << V_IPF;
  except_count++;
  except_count++;
}
}
 
 
/*Enable DMMU */
/*Enable DMMU */
void dmmu_enable (void)
void dmmu_enable (void)
{
{
  /* Enable DMMU */
  /* Enable DMMU */
  lo_dmmu_en ();
  lo_dmmu_en ();
}
}
 
 
/* Disable DMMU */
/* Disable DMMU */
void dmmu_disable (void)
void dmmu_disable (void)
{
{
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_DME);
}
}
 
 
/* Enable IMMU */
/* Enable IMMU */
void immu_enable (void)
void immu_enable (void)
{
{
  /* Enable IMMU */
  /* Enable IMMU */
  lo_immu_en ();
  lo_immu_en ();
}
}
 
 
/* Disable IMMU */
/* Disable IMMU */
void immu_disable (void)
void immu_disable (void)
{
{
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
  mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IME);
}
}
 
 
/* Tick timer init */
/* Tick timer init */
void tick_init (int period, int hp_int)
void tick_init (int period, int hp_int)
{
{
  /* Disable tick timer exception recognition */
  /* Disable tick timer exception recognition */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
 
 
  /* Set period of one cycle, restartable mode */
  /* Set period of one cycle, restartable mode */
  mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (period & SPR_TTMR_PERIOD));
  mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (period & SPR_TTMR_TP));
 
 
  /* Reset counter */
  /* Reset counter */
  mtspr(SPR_TTCR, 0);
  mtspr(SPR_TTCR, 0);
}
}
 
 
/* Interrupt test */
/* Interrupt test */
int interrupt_test (void)
int interrupt_test (void)
{
{
  unsigned long ret;
  unsigned long ret;
  int i;
  int i;
 
 
  /* Init tick timer */
  /* Init tick timer */
  tick_init (1, 1);
  tick_init (1, 1);
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Test normal high priority interrupt trigger */
  /* Test normal high priority interrupt trigger */
  ret = call ((unsigned long)&int_trigger, 0);
  ret = call ((unsigned long)&int_trigger, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_TICK));
  ASSERT(except_mask == (1 << V_TICK));
  ASSERT(ret == 0);
  ASSERT(ret == 0);
  ASSERT(except_pc == (unsigned long)int_trigger + 16);
  ASSERT(except_pc == (unsigned long)int_trigger + 16);
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Test inetrrupt in delay slot */
  /* Test inetrrupt in delay slot */
  tick_init (100, 1);
  tick_init (100, 1);
 
 
  /* Hopefully we will have interrupt recognition between branch insn and delay slot */
  /* Hopefully we will have interrupt recognition between branch insn and delay slot */
  except_pc = (unsigned long)&int_loop;
  except_pc = (unsigned long)&int_loop;
  for (i = 0; i < 10; i++) {
  for (i = 0; i < 10; i++) {
    call_with_int (except_pc, RAM_START);
    call_with_int (except_pc, RAM_START);
    ASSERT(except_pc == (unsigned long)&int_loop);
    ASSERT(except_pc == (unsigned long)&int_loop);
  }
  }
 
 
  return 0;
  return 0;
}
}
 
 
/* ITLB miss test */
/* ITLB miss test */
int itlb_test (void)
int itlb_test (void)
{
{
  int i, j, ret;
  int i, j, ret;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    for (j = 0; j < ITLB_SETS; j++) {
    for (j = 0; j < ITLB_SETS; j++) {
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  itlb_val = SPR_ITLBTR_CI;
  itlb_val = SPR_ITLBTR_CI;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable ();
  immu_enable ();
 
 
  /* Copy jump instruction to last location of a page */
  /* Copy jump instruction to last location of a page */
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_TEXT_SET_NB + 1)*PAGE_SIZE) - 8;
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_TEXT_SET_NB + 1)*PAGE_SIZE) - 8;
  memcpy((void *)ea, (void *)&jump_back, 12);
  memcpy((void *)ea, (void *)&jump_back, 12);
 
 
  /* Check if there was ITLB miss exception */
  /* Check if there was ITLB miss exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_pc == ea);
  ASSERT(except_pc == ea);
  ASSERT(ret == 0);
  ASSERT(ret == 0);
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was IPF miss exception */
  /* Check if there was IPF miss exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_pc == ea);
  ASSERT(except_pc == ea);
  ASSERT(ret == 0);
  ASSERT(ret == 0);
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  itlb_val = SPR_ITLBTR_CI;
  itlb_val = SPR_ITLBTR_CI;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was ITLB miss exception */
  /* Check if there was ITLB miss exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_pc == ea + 4);
  ASSERT(except_pc == ea + 4);
  ASSERT(ret == 0);
  ASSERT(ret == 0);
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was IPF exception */
  /* Check if there was IPF exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_pc == ea + 4);
  ASSERT(except_pc == ea + 4);
  ASSERT(ret == 0);
  ASSERT(ret == 0);
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 0);
  ASSERT(except_count == 0);
  ASSERT(ret == 1);
  ASSERT(ret == 1);
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable ();
  immu_disable ();
 
 
  return 0;
  return 0;
}
}
 
 
/* DTLB miss test */
/* DTLB miss test */
int dtlb_test (void)
int dtlb_test (void)
{
{
  int i, j, ret;
  int i, j, ret;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  dtlb_val = SPR_DTLBTR_CI;
  dtlb_val = SPR_DTLBTR_CI;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set pattern */
  /* Set pattern */
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
  ea = RAM_START + (RAM_SIZE/2) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
  REG32(ea) = 0x87654321;
  REG32(ea) = 0x87654321;
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  dmmu_enable ();
  dmmu_enable ();
 
 
  /* Check if there was DTLB miss exception */
  /* Check if there was DTLB miss exception */
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_DTLB_MISS));
  ASSERT(except_mask == (1 << V_DTLB_MISS));
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was DPF miss exception */
  /* Check if there was DPF miss exception */
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_DPF));
  ASSERT(except_mask == (1 << V_DPF));
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
  ASSERT(except_pc == (unsigned long)load_b_acc_32 + 8);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ret = call ((unsigned long)&load_b_acc_32, ea);
  ASSERT(except_count == 0);
  ASSERT(except_count == 0);
  ASSERT(ret == 0x87654321);
  ASSERT(ret == 0x87654321);
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable ();
  dmmu_disable ();
 
 
  return 0;
  return 0;
}
}
 
 
/* Bus error test */
/* Bus error test */
int buserr_test (void)
int buserr_test (void)
{
{
  int i, j, ret;
  int i, j, ret;
  unsigned long ea, ta;
  unsigned long ea, ta;
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    for (j = 0; j < ITLB_SETS; j++) {
    for (j = 0; j < ITLB_SETS; j++) {
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set IMMU translation */
  /* Set IMMU translation */
  ea = RAM_START + (RAM_SIZE) + ((TLB_TEXT_SET_NB)*PAGE_SIZE);
  ea = RAM_START + (RAM_SIZE) + ((TLB_TEXT_SET_NB)*PAGE_SIZE);
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  itlb_val = SPR_ITLBTR_CI | SPR_ITLBTR_SXE;
  mtspr (SPR_ITLBMR_BASE(0) + TLB_TEXT_SET_NB, (ea & SPR_ITLBMR_VPN) |
  mtspr (SPR_ITLBMR_BASE(0) + TLB_TEXT_SET_NB, (ea & SPR_ITLBMR_VPN) |
         SPR_ITLBMR_V);
         SPR_ITLBMR_V);
  // Set translate to invalid address: 0xee000000
  // Set translate to invalid address: 0xee000000
  mtspr (SPR_ITLBTR_BASE(0) + TLB_TEXT_SET_NB, (0xee000000 & SPR_ITLBTR_PPN) |
  mtspr (SPR_ITLBTR_BASE(0) + TLB_TEXT_SET_NB, (0xee000000 & SPR_ITLBTR_PPN) |
         itlb_val);
         itlb_val);
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable ();
  immu_enable ();
 
 
  /* Check if there was bus error exception */
  /* Check if there was bus error exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_pc == ea);
  ASSERT(except_pc == ea);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
 
 
  /* Disable IMMU */
  /* Disable IMMU */
  immu_disable ();
  immu_disable ();
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set EA as an invalid memory location */
  /* Set EA as an invalid memory location */
  ea  = 0xee000000;
  ea  = 0xee000000;
 
 
  /* Check if there was bus error exception */
  /* Check if there was bus error exception */
  ret = call (ea, 0);
  ret = call (ea, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_pc == ea);
  ASSERT(except_pc == ea);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set DMMU translation */
  /* Set DMMU translation */
  ea = RAM_START + (RAM_SIZE) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
  ea = RAM_START + (RAM_SIZE) + ((TLB_DATA_SET_NB)*PAGE_SIZE);
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
  dtlb_val = SPR_DTLBTR_CI | SPR_DTLBTR_SRE;
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, (ea & SPR_DTLBMR_VPN) |
  mtspr (SPR_DTLBMR_BASE(0) + TLB_DATA_SET_NB, (ea & SPR_DTLBMR_VPN) |
         SPR_DTLBMR_V);
         SPR_DTLBMR_V);
  // Set translate to invalid address: 0xee000000
  // Set translate to invalid address: 0xee000000
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, (0xee000000 & SPR_DTLBTR_PPN) |
  mtspr (SPR_DTLBTR_BASE(0) + TLB_DATA_SET_NB, (0xee000000 & SPR_DTLBTR_PPN) |
         dtlb_val);
         dtlb_val);
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  dmmu_enable ();
  dmmu_enable ();
 
 
  /* Check if there was bus error exception */
  /* Check if there was bus error exception */
  ret = call ((unsigned long)&load_acc_32, ea );
  ret = call ((unsigned long)&load_acc_32, ea );
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
 
 
  /* Disable DMMU */
  /* Disable DMMU */
  dmmu_disable ();
  dmmu_disable ();
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  // Set ea to invalid address
  // Set ea to invalid address
  ea = 0xee000000;
  ea = 0xee000000;
 
 
  /* Check if there was bus error exception */
  /* Check if there was bus error exception */
  ret = call ((unsigned long)&load_acc_32, ea );
  ret = call ((unsigned long)&load_acc_32, ea );
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_mask == (1 << V_BERR));
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
  ASSERT(except_pc == (unsigned long)load_acc_32 + 8);
  ASSERT(except_ea == ea);
  ASSERT(except_ea == ea);
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
 
 
  return 0;
  return 0;
}
}
 
 
/* Illegal instruction test */
/* Illegal instruction test */
int illegal_insn_test (void)
int illegal_insn_test (void)
{
{
  int ret;
  int ret;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set illegal insn code.
  /* Set illegal insn code.
 
 
     Original code had two bugs. First it jumped to the illegal instruction,
     Original code had two bugs. First it jumped to the illegal instruction,
     rather than the immediately preceding l.jr r9 (allowing us to
     rather than the immediately preceding l.jr r9 (allowing us to
     recover). Secondly it used 0xffffffff as an illegal instruction. Except
     recover). Secondly it used 0xffffffff as an illegal instruction. Except
     it isn't - it's l.cust8 0x3ffffff.
     it isn't - it's l.cust8 0x3ffffff.
 
 
     Fixed by a) jumping to the correct location and b) really using an
     Fixed by a) jumping to the correct location and b) really using an
     illegal instruction (opcode 0x3a. */
     illegal instruction (opcode 0x3a. */
  REG32(RAM_START + (RAM_SIZE/2)) = REG32((unsigned long)jump_back + 4);
  REG32(RAM_START + (RAM_SIZE/2)) = REG32((unsigned long)jump_back + 4);
  REG32(RAM_START + (RAM_SIZE/2) + 4) = 0xe8000000;
  REG32(RAM_START + (RAM_SIZE/2) + 4) = 0xe8000000;
 
 
  /* Check if there was illegal insn exception. Note that if an illegal
  /* Check if there was illegal insn exception. Note that if an illegal
     instruction occurs in a delay slot (like this one), then the exception
     instruction occurs in a delay slot (like this one), then the exception
     PC is the address of the jump instruction. */
     PC is the address of the jump instruction. */
  ret = call (RAM_START + (RAM_SIZE/2), 0 );     /* JPB */
  ret = call (RAM_START + (RAM_SIZE/2), 0 );     /* JPB */
 
 
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ILLINSN));
  ASSERT(except_mask == (1 << V_ILLINSN));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2)));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2)));
 
 
  return 0;
  return 0;
}
}
 
 
/* Align test */
/* Align test */
int align_test (void)
int align_test (void)
{
{
  int ret;
  int ret;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was alignment exception on read insn */
  /* Check if there was alignment exception on read insn */
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
  ASSERT(except_count == 2);
  ASSERT(except_count == 2);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
 
 
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
  ASSERT(except_count == 3);
  ASSERT(except_count == 3);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
 
 
  ret = call ((unsigned long)&load_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ret = call ((unsigned long)&load_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 4);
  ASSERT(except_count == 4);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_16) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_16) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
  /* Check alignment exception on write  insn */
  /* Check alignment exception on write  insn */
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 5);
  ASSERT(except_count == 5);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 2);
  ASSERT(except_count == 6);
  ASSERT(except_count == 6);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 2)));
 
 
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
  call ((unsigned long)&store_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 3);
  ASSERT(except_count == 7);
  ASSERT(except_count == 7);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(store_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 3)));
 
 
  call ((unsigned long)&store_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  call ((unsigned long)&store_acc_16, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 8);
  ASSERT(except_count == 8);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_pc == ((unsigned long)(store_acc_16) + 8));
  ASSERT(except_pc == ((unsigned long)(store_acc_16) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
 
 
  ret = call ((unsigned long)&load_b_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ret = call ((unsigned long)&load_b_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 9);
  ASSERT(except_count == 9);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_b_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_b_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
 
 
  return 0;
  return 0;
}
}
 
 
/* Trap test */
/* Trap test */
int trap_test (void)
int trap_test (void)
{
{
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was trap exception */
  /* Check if there was trap exception */
  call ((unsigned long)&trap, 0);
  call ((unsigned long)&trap, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_pc == (unsigned long)(trap));
  ASSERT(except_pc == (unsigned long)(trap));
 
 
  /* Check if there was trap exception */
  /* Check if there was trap exception */
  call ((unsigned long)&b_trap, 0);
  call ((unsigned long)&b_trap, 0);
  ASSERT(except_count == 2);
  ASSERT(except_count == 2);
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_pc == (unsigned long)(b_trap));
  ASSERT(except_pc == (unsigned long)(b_trap));
 
 
  return 0;
  return 0;
}
}
 
 
/* Range test */
/* Range test */
int range_test (void)
int range_test (void)
{
{
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was range exception */
  /* Check if there was range exception */
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
  call ((unsigned long)&range, 0);
  call ((unsigned long)&range, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_RANGE));
  ASSERT(except_mask == (1 << V_RANGE));
  ASSERT(except_pc == (unsigned long)(range));
  ASSERT(except_pc == (unsigned long)(range));
  ASSERT(except_ea == 0);
  ASSERT(except_ea == 0);
 
 
  /* Check if there was range exception */
  /* Check if there was range exception */
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_OVE);
  call ((unsigned long)&b_range, 0);
  call ((unsigned long)&b_range, 0);
  ASSERT(except_count == 2);
  ASSERT(except_count == 2);
  ASSERT(except_mask == (1 << V_RANGE));
  ASSERT(except_mask == (1 << V_RANGE));
  ASSERT(except_pc == (unsigned long)(b_range));
  ASSERT(except_pc == (unsigned long)(b_range));
 
 
  return 0;
  return 0;
}
}
 
 
/* Exception priority test */
/* Exception priority test */
void except_priority_test (void)
void except_priority_test (void)
{
{
  int i, j;
  int i, j;
  unsigned long ea, ta, ret;
  unsigned long ea, ta, ret;
 
 
  /* Invalidate all entries in ITLB */
  /* Invalidate all entries in ITLB */
  for (i = 0; i < ITLB_WAYS; i++) {
  for (i = 0; i < ITLB_WAYS; i++) {
    for (j = 0; j < ITLB_SETS; j++) {
    for (j = 0; j < ITLB_SETS; j++) {
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBMR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
      mtspr (SPR_ITLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
  for (i = 0; i < TLB_TEXT_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
    mtspr (SPR_ITLBTR_BASE(0) + i, ta | ITLB_PR_NOLIMIT);
  }
  }
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  itlb_val = SPR_ITLBTR_CI;
  itlb_val = SPR_ITLBTR_CI;
 
 
  /* Invalidate all entries in DTLB */
  /* Invalidate all entries in DTLB */
  for (i = 0; i < DTLB_WAYS; i++) {
  for (i = 0; i < DTLB_WAYS; i++) {
    for (j = 0; j < DTLB_SETS; j++) {
    for (j = 0; j < DTLB_SETS; j++) {
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBMR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
      mtspr (SPR_DTLBTR_BASE(i) + j, 0);
    }
    }
  }
  }
 
 
  /* Set one to one translation for the use of this program */
  /* Set one to one translation for the use of this program */
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
  for (i = 0; i < TLB_DATA_SET_NB; i++) {
    ea = RAM_START + (i*PAGE_SIZE);
    ea = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    ta = RAM_START + (i*PAGE_SIZE);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_ITLBMR_V);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
    mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
  }
  }
 
 
  /* Init tick timer */
  /* Init tick timer */
  tick_init (1, 1);
  tick_init (1, 1);
 
 
  /* Set dtlb no permisions */
  /* Set dtlb no permisions */
  dtlb_val = SPR_DTLBTR_CI;
  dtlb_val = SPR_DTLBTR_CI;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Enable IMMU */
  /* Enable IMMU */
  immu_enable ();
  immu_enable ();
 
 
  /* The following is currently disabled due to differing behavior between
  /* The following is currently disabled due to differing behavior between
     or1ksim and the OR1200 RTL. Or1ksim appears to receive only 1 exception
     or1ksim and the OR1200 RTL. Or1ksim appears to receive only 1 exception
     during the call_with_int() call. The OR1200 correctly, in my opionion,
     during the call_with_int() call. The OR1200 correctly, in my opionion,
     reports 2 exceptions - ITLB miss and tick timer. -- Julius
     reports 2 exceptions - ITLB miss and tick timer. -- Julius
 
 
     TODO: Investigate why or1ksim isn't reporting ITLB miss.
     TODO: Investigate why or1ksim isn't reporting ITLB miss.
 
 
  */
  */
 
 
#if 0
#if 0
  /* Check if there was INT exception */
  /* Check if there was INT exception */
  call_with_int (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  call_with_int (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  printf("ec:%d 0x%lx\n",except_count,except_mask);  ASSERT(except_count == 2);
  printf("ec:%d 0x%lx\n",except_count,except_mask);  ASSERT(except_count == 2);
  ASSERT(except_mask == ((1 << V_TICK) | (1 << V_ITLB_MISS)));
  ASSERT(except_mask == ((1 << V_TICK) | (1 << V_ITLB_MISS)));
  printf("epc %8lx\n",except_pc);
  printf("epc %8lx\n",except_pc);
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
#endif
#endif
 
 
  /* Check if there was ITLB exception */
  /* Check if there was ITLB exception */
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_mask == (1 << V_ITLB_MISS));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
 
 
  /* Set dtlb permisions */
  /* Set dtlb permisions */
  itlb_val |= SPR_ITLBTR_SXE;
  itlb_val |= SPR_ITLBTR_SXE;
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was IPF exception */
  /* Check if there was IPF exception */
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  call (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE), 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_mask == (1 << V_IPF));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_TEXT_SET_NB*PAGE_SIZE)));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Disable MMU */
  /* Disable MMU */
  immu_disable ();
  immu_disable ();
 
 
  /* Set illegal instruction. JPB. Use a really illegal instruction, not
  /* Set illegal instruction. JPB. Use a really illegal instruction, not
     l.cust8 0x3ffffff. */
     l.cust8 0x3ffffff. */
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 0) = 0x00000000;
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 0) = 0x00000000;
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4) = 0xe8000000;
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4) = 0xe8000000;
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 8) = 0x00000000;
  REG32(RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 8) = 0x00000000;
 
 
  /* Check if there was illegal insn exception */
  /* Check if there was illegal insn exception */
  call (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4, 0);
  call (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ILLINSN));
  ASSERT(except_mask == (1 << V_ILLINSN));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4));
  ASSERT(except_pc == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4 ));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE/2) + (TLB_TEXT_SET_NB*PAGE_SIZE) + 4 ));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Enable DMMU */
  /* Enable DMMU */
  dmmu_enable ();
  dmmu_enable ();
 
 
  /* Check if there was alignment exception on read insn */
  /* Check if there was alignment exception on read insn */
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE) + 1);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(except_mask == (1 << V_ALIGN));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE + 1)));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was DTLB exception */
  /* Check if there was DTLB exception */
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_DTLB_MISS));
  ASSERT(except_mask == (1 << V_DTLB_MISS));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Set dtlb permisions */
  /* Set dtlb permisions */
  dtlb_val |= SPR_DTLBTR_SRE;
  dtlb_val |= SPR_DTLBTR_SRE;
 
 
  /* Check if there was DPF exception */
  /* Check if there was DPF exception */
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
  ret = call ((unsigned long)&load_acc_32, RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE));
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_DPF));
  ASSERT(except_mask == (1 << V_DPF));
  ASSERT(ret == 0x12345678);
  ASSERT(ret == 0x12345678);
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_pc == ((unsigned long)(load_acc_32) + 8));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
  ASSERT(except_ea == (RAM_START + (RAM_SIZE) + (TLB_DATA_SET_NB*PAGE_SIZE)));
 
 
  /* Reset except counter */
  /* Reset except counter */
  except_count = 0;
  except_count = 0;
  except_mask = 0;
  except_mask = 0;
  except_pc = 0;
  except_pc = 0;
  except_ea = 0;
  except_ea = 0;
 
 
  /* Check if there was trap exception */
  /* Check if there was trap exception */
  call ((unsigned long)&trap, 0);
  call ((unsigned long)&trap, 0);
  ASSERT(except_count == 1);
  ASSERT(except_count == 1);
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_mask == (1 << V_TRAP));
  ASSERT(except_pc == (unsigned long)(trap));
  ASSERT(except_pc == (unsigned long)(trap));
 
 
}
}
 
 
int main (void)
int main (void)
{
{
  int ret;
  int ret;
 
 
  printf("except_test\n");
  printf("except_test\n");
 
 
  /* Register bus error handler */
  /* Register bus error handler */
  excpt_buserr = (unsigned long)bus_err_handler;
  excpt_buserr = (unsigned long)bus_err_handler;
 
 
  /* Register illegal insn handler */
  /* Register illegal insn handler */
  excpt_illinsn = (unsigned long)ill_insn_handler;
  excpt_illinsn = (unsigned long)ill_insn_handler;
 
 
  /* Register tick timer exception handler */
  /* Register tick timer exception handler */
  excpt_tick = (unsigned long)tick_handler;
  excpt_tick = (unsigned long)tick_handler;
 
 
  /* Register external interrupt handler */
  /* Register external interrupt handler */
  excpt_int = (unsigned long)int_handler;
  excpt_int = (unsigned long)int_handler;
 
 
  /* Register ITLB miss handler */
  /* Register ITLB miss handler */
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
  excpt_itlbmiss = (unsigned long)itlb_miss_handler;
 
 
  /* Register instruction page fault handler */
  /* Register instruction page fault handler */
  excpt_ipfault = (unsigned long)ipage_fault_handler;
  excpt_ipfault = (unsigned long)ipage_fault_handler;
 
 
  /* Register DTLB miss handler */
  /* Register DTLB miss handler */
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
  excpt_dtlbmiss = (unsigned long)dtlb_miss_handler;
 
 
  /* Register data page fault handler */
  /* Register data page fault handler */
  excpt_dpfault = (unsigned long)dpage_fault_handler;
  excpt_dpfault = (unsigned long)dpage_fault_handler;
 
 
  /* Register trap handler */
  /* Register trap handler */
  excpt_trap = (unsigned long)trap_handler;
  excpt_trap = (unsigned long)trap_handler;
 
 
  /* Register align handler */
  /* Register align handler */
  excpt_align = (unsigned long)align_handler;
  excpt_align = (unsigned long)align_handler;
 
 
  /* Register range handler */
  /* Register range handler */
  excpt_range = (unsigned long)range_handler;
  excpt_range = (unsigned long)range_handler;
 
 
  /* Exception basic test */
  /* Exception basic test */
  ret = except_basic ();
  ret = except_basic ();
  ASSERT(ret == 0);
  ASSERT(ret == 0);
printf("interupt_test\n");
printf("interupt_test\n");
  /* Interrupt exception test */
  /* Interrupt exception test */
  interrupt_test ();
  interrupt_test ();
 
 
printf("itlb_test\n");
printf("itlb_test\n");
  /* ITLB exception test */
  /* ITLB exception test */
  itlb_test ();
  itlb_test ();
 
 
printf("dtlb_test\n");
printf("dtlb_test\n");
  /* DTLB exception test */
  /* DTLB exception test */
  dtlb_test ();
  dtlb_test ();
 
 
printf("buserr_test\n");
printf("buserr_test\n");
  /* Bus error exception test */
  /* Bus error exception test */
  buserr_test ();
  buserr_test ();
 
 
printf("illegal_insn_test\n");
printf("illegal_insn_test\n");
  /* Bus error exception test */
  /* Bus error exception test */
  /* Illegal insn test */
  /* Illegal insn test */
  illegal_insn_test ();
  illegal_insn_test ();
 
 
printf("align_test\n");
printf("align_test\n");
  /* Alignment test */
  /* Alignment test */
  align_test ();
  align_test ();
 
 
printf("trap_test\n");
printf("trap_test\n");
  /* Trap test */
  /* Trap test */
  trap_test ();
  trap_test ();
 
 
printf("except_priority_test\n");
printf("except_priority_test\n");
  /* Range test */
  /* Range test */
//  range_test ();
//  range_test ();
 
 
  /* Exception priority test */
  /* Exception priority test */
  except_priority_test ();
  except_priority_test ();
 
 
  report (0xdeaddead);
  report (0xdeaddead);
  exit (0);
  exit (0);
 
 
  return 0;
  return 0;
}
}
 
 
 
 

powered by: WebSVN 2.1.0

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