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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [or1k/] [except.c] - Diff between revs 1386 and 1419

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

Rev 1386 Rev 1419
/* except.c -- Simulation of OR1K exceptions
/* except.c -- Simulation of OR1K exceptions
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
 
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
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
 
 
#include "config.h"
#include "config.h"
 
 
#ifdef HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#include <inttypes.h>
#endif
#endif
 
 
#include "port.h"
#include "port.h"
#include "arch.h"
#include "arch.h"
#include "abstract.h"
#include "abstract.h"
#include "except.h"
#include "except.h"
#include "sprs.h"
#include "sprs.h"
#include "sim-config.h"
#include "sim-config.h"
#include "debug_unit.h"
#include "debug_unit.h"
#include "execute.h"
#include "execute.h"
 
 
extern int delay_insn;
extern int delay_insn;
extern oraddr_t pcprev;
extern oraddr_t pcprev;
extern oraddr_t pcdelay;
extern oraddr_t pcdelay;
 
 
int except_pending = 0;
int except_pending = 0;
 
 
static const char *except_names[] = {
static const char *except_names[] = {
 NULL,
 NULL,
 "Reset",
 "Reset",
 "Bus Error",
 "Bus Error",
 "Data Page Fault",
 "Data Page Fault",
 "Insn Page Fault",
 "Insn Page Fault",
 "Tick timer",
 "Tick timer",
 "Alignment",
 "Alignment",
 "Illegal instruction",
 "Illegal instruction",
 "Interrupt",
 "Interrupt",
 "Data TLB Miss",
 "Data TLB Miss",
 "Insn TLB Miss",
 "Insn TLB Miss",
 "Range",
 "Range",
 "System Call",
 "System Call",
 "Trap" };
 "Trap" };
 
 
static const char *except_name(oraddr_t except)
static const char *except_name(oraddr_t except)
{
{
  return except_names[except >> 8];
  return except_names[except >> 8];
}
}
 
 
/* Asserts OR1K exception. */
/* Asserts OR1K exception. */
void except_handle(oraddr_t except, oraddr_t ea)
void except_handle(oraddr_t except, oraddr_t ea)
{
{
  if(debug_ignore_exception (except))
  if(debug_ignore_exception (except))
    return;
    return;
 
 
  except_pending = 1;
  except_pending = 1;
 
 
  if (config.sim.verbose)
  if (config.sim.verbose)
    PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
    PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
           ", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
           ", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
           ", cycles %lld, #%lld\n",
           ", cycles %lld, #%lld\n",
           except, except_name(except), pcprev, ea, pc, pcnext, pcdelay,
           except, except_name(except), pcprev, ea, pc, pcnext, pcdelay,
           runtime.sim.cycles, runtime.cpu.instructions);
           runtime.sim.cycles, runtime.cpu.instructions);
 
 
  pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
  pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
 
 
  switch(except) {
  switch(except) {
  /* EPCR is irrelevent */
  /* EPCR is irrelevent */
  case EXCEPT_RESET:
  case EXCEPT_RESET:
    break;
    break;
  /* EPCR is loaded with address of instruction that caused the exception */
  /* EPCR is loaded with address of instruction that caused the exception */
  /* All these exceptions happen during a simulated instruction */
  /* All these exceptions happen during a simulated instruction */
  case EXCEPT_BUSERR:
  case EXCEPT_BUSERR:
  case EXCEPT_DPF:
  case EXCEPT_DPF:
  case EXCEPT_IPF:
  case EXCEPT_IPF:
  case EXCEPT_ALIGN:
  case EXCEPT_ALIGN:
  case EXCEPT_ILLEGAL:
  case EXCEPT_ILLEGAL:
  case EXCEPT_DTLBMISS:
  case EXCEPT_DTLBMISS:
  case EXCEPT_ITLBMISS:
  case EXCEPT_ITLBMISS:
  case EXCEPT_RANGE:
  case EXCEPT_RANGE:
  case EXCEPT_TRAP:
  case EXCEPT_TRAP:
    mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
    mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
    break;
    break;
  /* EPCR is loaded with address of next not-yet-executed instruction */
  /* EPCR is loaded with address of next not-yet-executed instruction */
  case EXCEPT_SYSCALL:
  case EXCEPT_SYSCALL:
    mtspr(SPR_EPCR_BASE, (pc + 4) - (delay_insn ? 4 : 0));
    mtspr(SPR_EPCR_BASE, (pc + 4) - (delay_insn ? 4 : 0));
    break;
    break;
  /* These exceptions happen AFTER (or before) an instruction has been
  /* These exceptions happen AFTER (or before) an instruction has been
   * simulated, therefore the pc already points to the *next* instruction */
   * simulated, therefore the pc already points to the *next* instruction */
  case EXCEPT_TICK:
  case EXCEPT_TICK:
  case EXCEPT_INT:
  case EXCEPT_INT:
    mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
    mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
    /* If we don't update the pc now, then it will only happen *after* the next
    /* If we don't update the pc now, then it will only happen *after* the next
     * instruction (There would be serious problems if the next instruction just
     * instruction (There would be serious problems if the next instruction just
     * happens to be a branch), when it should happen NOW. */
     * happens to be a branch), when it should happen NOW. */
    pc = pcnext;
    pc = pcnext;
    pcnext += 4;
    pcnext += 4;
    break;
    break;
  }
  }
 
 
  mtspr(SPR_EEAR_BASE, ea);
  mtspr(SPR_EEAR_BASE, ea);
  mtspr(SPR_ESR_BASE, mfspr(SPR_SR));
  mtspr(SPR_ESR_BASE, mfspr(SPR_SR));
 
 
  /* Address translation is always disabled when starting exception. */
  /* Address translation is always disabled when starting exception. */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_DME));
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_DME));
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IME));
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IME));
 
 
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE);   /* Disable overflow flag exception. */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE);   /* Disable overflow flag exception. */
 
 
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM);     /* SUPV mode */
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM);     /* SUPV mode */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE));    /* Disable interrupts. */
  mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE));    /* Disable interrupts. */
 
 
  delay_insn = 0;
  delay_insn = 0;
}
}
 
 

powered by: WebSVN 2.1.0

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