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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or1k/] [sprs.c] - Blame information for rev 436

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

Line No. Rev Author Line
1 19 jeremybenn
/* sprs.c -- Simulation of OR1K special-purpose registers
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9
 
10
   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
 
15
   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
 
20
   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
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28
#include "config.h"
29
#include "port.h"
30
 
31
/* System includes */
32
#include <stdlib.h>
33
#include <stdio.h>
34
#include <errno.h>
35
 
36
/* Package includes */
37
#include "sprs.h"
38
#include "sim-config.h"
39
#include "debug.h"
40
#include "execute.h"
41
#include "spr-defs.h"
42
#include "tick.h"
43
#include "dcache-model.h"
44
#include "icache-model.h"
45
#include "dmmu.h"
46
#include "immu.h"
47
#include "toplevel-support.h"
48
#include "pic.h"
49
 
50
 
51
DECLARE_DEBUG_CHANNEL(immu);
52
 
53
/* Set a specific SPR with a value. */
54
void mtspr(uint16_t regno, const uorreg_t value)
55
{
56
  uorreg_t prev_val;
57
 
58
  prev_val = cpu_state.sprs[regno];
59
  cpu_state.sprs[regno] = value;
60
 
61
  /* MM: Register hooks.  */
62
  switch (regno) {
63
  case SPR_TTCR:
64
    spr_write_ttcr (value);
65
    break;
66
  case SPR_TTMR:
67
    spr_write_ttmr (prev_val);
68
    break;
69
  /* Data cache simulateing stuff */
70
  case SPR_DCBPR:
71
    /* FIXME: This is not correct.  The arch. manual states: "Memory accesses
72
     * are not recorded (Unlike load or store instructions) and cannot invoke
73
     * any exception".  If the physical address is invalid a bus error will be
74
     * generated.  Also if the effective address is not resident in the mmu
75
     * the read will happen from address 0, which is naturally not correct. */
76
    dc_simulate_read(peek_into_dtlb(value, 0, 1), value, 4);
77
    cpu_state.sprs[SPR_DCBPR] = 0;
78
    break;
79
  case SPR_DCBFR:
80
    dc_inv(value);
81
    cpu_state.sprs[SPR_DCBFR] = -1;
82
    break;
83
  case SPR_DCBIR:
84
    dc_inv(value);
85
    cpu_state.sprs[SPR_DCBIR] = 0;
86
    break;
87
  case SPR_DCBWR:
88
    cpu_state.sprs[SPR_DCBWR] = 0;
89
    break;
90
  case SPR_DCBLR:
91
    cpu_state.sprs[SPR_DCBLR] = 0;
92
    break;
93
  /* Instruction cache simulateing stuff */
94
  case SPR_ICBPR:
95
    /* FIXME: The arch manual does not say what happens when an invalid memory
96
     * location is specified.  I guess the same as for the DCBPR register */
97
    ic_simulate_fetch(peek_into_itlb(value), value);
98
    cpu_state.sprs[SPR_ICBPR] = 0;
99
    break;
100
  case SPR_ICBIR:
101
    ic_inv(value);
102
    cpu_state.sprs[SPR_ICBIR] = 0;
103
    break;
104
  case SPR_ICBLR:
105
    cpu_state.sprs[SPR_ICBLR] = 0;
106
    break;
107
  case SPR_SR:
108
    cpu_state.sprs[regno] |= SPR_SR_FO;
109
    if((value & SPR_SR_IEE) && !(prev_val & SPR_SR_IEE))
110
      pic_ints_en();
111
#if DYNAMIC_EXECUTION
112
    if((value & SPR_SR_IME) && !(prev_val & SPR_SR_IME)) {
113
      TRACE_(immu)("IMMU just became enabled (%lli).\n", runtime.sim.cycles);
114
      recheck_immu(IMMU_GOT_ENABLED);
115
    } else if(!(value & SPR_SR_IME) && (prev_val & SPR_SR_IME)) {
116
      TRACE_(immu)("Remove counting of mmu hit delay with cycles (%lli)\n",
117
                   runtime.sim.cycles);
118
      recheck_immu(IMMU_GOT_DISABLED);
119
    }
120
#endif
121
    break;
122
  case SPR_NPC:
123
    {
124
      /* The debugger has redirected us to a new address */
125
      /* This is usually done to reissue an instruction
126
         which just caused a breakpoint exception. */
127
 
128
      /* JPB patch. When GDB stepi, this may be used to set the PC to the
129
         value it is already at. If this is the case, then we do nothing (in
130
         particular we do not trash a delayed branch) */
131
 
132
      if (value != cpu_state.pc)
133
        {
134
          cpu_state.pc = value;
135
 
136
          if(!value && config.sim.verbose)
137
            PRINTF("WARNING: PC just set to 0!\n");
138
 
139
          /* Clear any pending delay slot jumps also */
140
          cpu_state.delay_insn = 0;
141
          pcnext = value + 4;
142
 
143
          /* Further JPB patch. If the processor is stalled, then subsequent
144
             reads of the NPC should return 0 until the processor is
145
             unstalled. If the processor is stalled, note that the NPC has
146
             been updated while the processor was stalled. */
147
 
148
          if (runtime.cpu.stalled)
149
            {
150
              cpu_state.npc_not_valid = 1;
151
            }
152
        }
153
    }
154
    break;
155
  case SPR_PICSR:
156
    if(!config.pic.edge_trigger)
157 436 julius
      /* When configured with level triggered interrupts we clear PICSR in PIC
158
         peripheral model when incoming IRQ goes low */
159 19 jeremybenn
      cpu_state.sprs[SPR_PICSR] = prev_val;
160
    break;
161
  case SPR_PICMR:
162 432 jeremybenn
    /* If we have non-maskable interrupts, then the bottom two bits are always
163
       one. */
164
    if (config.pic.use_nmi)
165
      {
166
        cpu_state.sprs[SPR_SR] |= 0x00000003;
167
      }
168
 
169 19 jeremybenn
    if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
170
      pic_ints_en();
171
    break;
172
  case SPR_PMR:
173
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
174
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
175
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
176
      sim_done();
177
    }
178
    break;
179
  default:
180
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
181
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
182
      if((regno & 0xff) < 0x80)
183
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
184
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
185
      else
186
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
187
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
188
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
189
                              SPR_DTLBTR_SWE));
190
    }
191
 
192
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
193
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
194
      if((regno & 0xff) < 0x80)
195
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
196
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
197
      else
198
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
199
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
200
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
201
 
202
#if DYNAMIC_EXECUTION
203
      if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
204
        /* The immu got reconfigured.  Recheck if the current page in execution
205
         * is resident in the immu ways.  This check would be done during the
206
         * instruction fetch but since the dynamic execution model does not do
207
         * instruction fetchs, do it now. */
208
        recheck_immu(0);
209
      }
210
#endif
211
    }
212
 
213
    /* Links to GPRS */
214
    if(regno >= 0x0400 && regno < 0x0420) {
215
      cpu_state.reg[regno - 0x0400] = value;
216
    }
217
    break;
218
  }
219
}
220
 
221
/* Get a specific SPR. */
222
uorreg_t mfspr(const uint16_t regno)
223
{
224
  uorreg_t ret;
225
 
226
  ret = cpu_state.sprs[regno];
227
 
228
  switch (regno) {
229
  case SPR_NPC:
230
 
231
    /* The NPC is the program counter UNLESS the NPC has been changed and we
232
       are stalled, which will have flushed the pipeline, so the value is
233
       zero. Currently this is optional behavior, since it breaks GDB.
234
    */
235
 
236
    if (config.sim.strict_npc && cpu_state.npc_not_valid)
237
      {
238
        ret = 0;
239
      }
240
    else
241
      {
242
        ret = cpu_state.pc;
243
      }
244
    break;
245
 
246
  case SPR_TTCR:
247
    ret = spr_read_ttcr();
248
    break;
249 226 julius
  case SPR_FPCSR:
250
    // If hard floating point is disabled - return 0
251
    if (!config.cpu.hardfloat)
252
      ret = 0;
253
    break;
254 19 jeremybenn
  default:
255
    /* Links to GPRS */
256
    if(regno >= 0x0400 && regno < 0x0420)
257
      ret = cpu_state.reg[regno - 0x0400];
258
  }
259
 
260
  return ret;
261
}
262
 
263
/* Show status of important SPRs. */
264
void sprs_status(void)
265
{
266
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
267
         cpu_state.sprs[SPR_UPR]);
268
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
269
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
270
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
271
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
272
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
273
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
274
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
275
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
276
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
277
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
278
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
279
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
280
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
281
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
282
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
283
}

powered by: WebSVN 2.1.0

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