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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc3/] [or1ksim/] [cpu/] [or1k/] [except.c] - Blame information for rev 1686

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

powered by: WebSVN 2.1.0

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