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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cpu/] [or1k/] [except.c] - Blame information for rev 1748

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

Line No. Rev Author Line
1 33 lampret
/* except.c -- Simulation of OR1K exceptions
2 1748 jeremybenn
 
3 33 lampret
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
5 33 lampret
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 33 lampret
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 33 lampret
 
10 1748 jeremybenn
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14 33 lampret
 
15 1748 jeremybenn
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19 33 lampret
 
20 1748 jeremybenn
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22 33 lampret
 
23 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28 1350 nogj
#include "config.h"
29
 
30 1748 jeremybenn
/* Package includes */
31 33 lampret
#include "except.h"
32 344 markom
#include "sim-config.h"
33 1748 jeremybenn
#include "arch.h"
34
#include "debug.h"
35
#include "spr-defs.h"
36 1350 nogj
#include "execute.h"
37 1748 jeremybenn
#include "debug-unit.h"
38 33 lampret
 
39 1452 nogj
#if DYNAMIC_EXECUTION
40
#include "sched.h"
41
#include "op_support.h"
42
#endif
43
 
44 82 lampret
 
45 1748 jeremybenn
DEFAULT_DEBUG_CHANNEL (except);
46
 
47 1386 nogj
int except_pending = 0;
48 139 chris
 
49 1386 nogj
static const char *except_names[] = {
50 1748 jeremybenn
  NULL,
51
  "Reset",
52
  "Bus Error",
53
  "Data Page Fault",
54
  "Insn Page Fault",
55
  "Tick timer",
56
  "Alignment",
57
  "Illegal instruction",
58
  "Interrupt",
59
  "Data TLB Miss",
60
  "Insn TLB Miss",
61
  "Range",
62
  "System Call",
63
  "Floating Point",
64
  "Trap"
65
};
66 1386 nogj
 
67 1748 jeremybenn
static const char *
68
except_name (oraddr_t except)
69 139 chris
{
70 1386 nogj
  return except_names[except >> 8];
71 139 chris
}
72
 
73 479 markom
/* Asserts OR1K exception. */
74 1473 nogj
/* WARNING: Don't excpect except_handle to return.  Sometimes it _may_ return at
75
 * other times it may not. */
76 1748 jeremybenn
void
77
except_handle (oraddr_t except, oraddr_t ea)
78 33 lampret
{
79 1452 nogj
  oraddr_t except_vector;
80
 
81 1748 jeremybenn
  if (debug_ignore_exception (except))
82 1386 nogj
    return;
83 139 chris
 
84 1452 nogj
#if !(DYNAMIC_EXECUTION)
85
  /* In the dynamic recompiler, this function never returns, so this is not
86
   * needed.  Ofcourse we could set it anyway, but then all code that checks
87
   * this variable would break, since it is never reset */
88 1386 nogj
  except_pending = 1;
89 1452 nogj
#endif
90 51 lampret
 
91 1748 jeremybenn
  TRACE ("Exception 0x%" PRIxADDR " (%s) at 0x%" PRIxADDR ", EA: 0x%" PRIxADDR
92
         ", cycles %lld, #%lld\n",
93
         except, except_name (except), cpu_state.pc, ea, runtime.sim.cycles,
94
         runtime.cpu.instructions);
95 1386 nogj
 
96 1748 jeremybenn
  except_vector =
97
    except + (cpu_state.sprs[SPR_SR] & SPR_SR_EPH ? 0xf0000000 : 0x00000000);
98 1386 nogj
 
99 1452 nogj
#if !(DYNAMIC_EXECUTION)
100
  pcnext = except_vector;
101
#endif
102
 
103 1748 jeremybenn
  cpu_state.sprs[SPR_EEAR_BASE] = ea;
104 1442 nogj
  cpu_state.sprs[SPR_ESR_BASE] = cpu_state.sprs[SPR_SR];
105
 
106 1748 jeremybenn
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OVE;        /* Disable overflow flag exception. */
107 1442 nogj
 
108 1748 jeremybenn
  cpu_state.sprs[SPR_SR] |= SPR_SR_SM;  /* SUPV mode */
109
  cpu_state.sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE); /* Disable interrupts. */
110 1442 nogj
 
111
  /* Address translation is always disabled when starting exception. */
112
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_DME;
113
 
114 1452 nogj
#if DYNAMIC_EXECUTION
115
  /* If we were called from do_scheduler and there were more jobs scheduled to
116
   * run after this, they won't run unless the following call is made since this
117
   * function never returns.  (If we weren't called from do_scheduler, then the
118
   * job at the head of the queue will still have some time remaining) */
119 1748 jeremybenn
  if (scheduler.job_queue->time <= 0)
120
    do_scheduler ();
121 1452 nogj
#endif
122
 
123 1748 jeremybenn
  switch (except)
124
    {
125
      /* EPCR is irrelevent */
126
    case EXCEPT_RESET:
127
      break;
128
      /* EPCR is loaded with address of instruction that caused the exception */
129
    case EXCEPT_ITLBMISS:
130
    case EXCEPT_IPF:
131
      cpu_state.sprs[SPR_EPCR_BASE] = ea - (cpu_state.delay_insn ? 4 : 0);
132 1452 nogj
#if DYNAMIC_EXECUTION
133 1748 jeremybenn
      op_join_mem_cycles ();
134 1686 nogj
#endif
135 1748 jeremybenn
      break;
136
    case EXCEPT_BUSERR:
137
    case EXCEPT_DPF:
138
    case EXCEPT_ALIGN:
139
    case EXCEPT_ILLEGAL:
140
    case EXCEPT_DTLBMISS:
141
    case EXCEPT_RANGE:
142
    case EXCEPT_TRAP:
143
      /* All these exceptions happen during a simulated instruction */
144 1452 nogj
#if DYNAMIC_EXECUTION
145 1748 jeremybenn
      /* Since these exceptions happen during a simulated instruction and this
146
       * function jumps out to the exception vector the scheduler would never have
147
       * a chance to run, therefore run it now */
148
      run_sched_out_of_line ();
149 1452 nogj
#endif
150 1748 jeremybenn
      cpu_state.sprs[SPR_EPCR_BASE] =
151
        cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
152
      break;
153
      /* EPCR is loaded with address of next not-yet-executed instruction */
154
    case EXCEPT_SYSCALL:
155
      cpu_state.sprs[SPR_EPCR_BASE] =
156
        (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0);
157
      break;
158
      /* These exceptions happen AFTER (or before) an instruction has been
159
       * simulated, therefore the pc already points to the *next* instruction */
160
    case EXCEPT_TICK:
161
    case EXCEPT_INT:
162
      cpu_state.sprs[SPR_EPCR_BASE] =
163
        cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
164 1452 nogj
#if !(DYNAMIC_EXECUTION)
165 1748 jeremybenn
      /* If we don't update the pc now, then it will only happen *after* the next
166
       * instruction (There would be serious problems if the next instruction just
167
       * happens to be a branch), when it should happen NOW. */
168
      cpu_state.pc = pcnext;
169
      pcnext += 4;
170 1452 nogj
#endif
171 1748 jeremybenn
      break;
172
    }
173 693 markom
 
174 1452 nogj
  /* Address trnaslation is here because run_sched_out_of_line calls
175
   * eval_insn_direct which checks out the immu for the address translation but
176
   * if it would be disabled above then there would be not much point... */
177
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_IME;
178
 
179
  /* Complex/simple execution strictly don't need this because of the
180
   * next_delay_insn thingy but in the dynamic execution modell that doesn't
181 1481 nogj
   * exist and thus cpu_state.delay_insn would stick in the exception handler
182 1452 nogj
   * causeing grief if the first instruction of the exception handler is also in
183
   * the delay slot of the previous instruction */
184 1432 nogj
  cpu_state.delay_insn = 0;
185 1452 nogj
 
186
#if DYNAMIC_EXECUTION
187 1748 jeremybenn
  do_jump (except_vector);
188 1452 nogj
#endif
189 33 lampret
}

powered by: WebSVN 2.1.0

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