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

Subversion Repositories openrisc

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

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 430 julius
      /* When configured with level triggered interrupts we clear PICSR in PIC
158
         when IRQ goes low */
159 19 jeremybenn
      cpu_state.sprs[SPR_PICSR] = prev_val;
160
    break;
161
  case SPR_PICMR:
162
    if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
163
      pic_ints_en();
164
    break;
165
  case SPR_PMR:
166
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
167
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
168
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
169
      sim_done();
170
    }
171
    break;
172
  default:
173
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
174
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
175
      if((regno & 0xff) < 0x80)
176
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
177
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
178
      else
179
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
180
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
181
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
182
                              SPR_DTLBTR_SWE));
183
    }
184
 
185
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
186
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
187
      if((regno & 0xff) < 0x80)
188
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
189
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
190
      else
191
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
192
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
193
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
194
 
195
#if DYNAMIC_EXECUTION
196
      if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
197
        /* The immu got reconfigured.  Recheck if the current page in execution
198
         * is resident in the immu ways.  This check would be done during the
199
         * instruction fetch but since the dynamic execution model does not do
200
         * instruction fetchs, do it now. */
201
        recheck_immu(0);
202
      }
203
#endif
204
    }
205
 
206
    /* Links to GPRS */
207
    if(regno >= 0x0400 && regno < 0x0420) {
208
      cpu_state.reg[regno - 0x0400] = value;
209
    }
210
    break;
211
  }
212
}
213
 
214
/* Get a specific SPR. */
215
uorreg_t mfspr(const uint16_t regno)
216
{
217
  uorreg_t ret;
218
 
219
  ret = cpu_state.sprs[regno];
220
 
221
  switch (regno) {
222
  case SPR_NPC:
223
 
224
    /* The NPC is the program counter UNLESS the NPC has been changed and we
225
       are stalled, which will have flushed the pipeline, so the value is
226
       zero. Currently this is optional behavior, since it breaks GDB.
227
    */
228
 
229
    if (config.sim.strict_npc && cpu_state.npc_not_valid)
230
      {
231
        ret = 0;
232
      }
233
    else
234
      {
235
        ret = cpu_state.pc;
236
      }
237
    break;
238
 
239
  case SPR_TTCR:
240
    ret = spr_read_ttcr();
241
    break;
242 226 julius
  case SPR_FPCSR:
243
    // If hard floating point is disabled - return 0
244
    if (!config.cpu.hardfloat)
245
      ret = 0;
246
    break;
247 19 jeremybenn
  default:
248
    /* Links to GPRS */
249
    if(regno >= 0x0400 && regno < 0x0420)
250
      ret = cpu_state.reg[regno - 0x0400];
251
  }
252
 
253
  return ret;
254
}
255
 
256
/* Show status of important SPRs. */
257
void sprs_status(void)
258
{
259
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
260
         cpu_state.sprs[SPR_UPR]);
261
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
262
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
263
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
264
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
265
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
266
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
267
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
268
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
269
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
270
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
271
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
272
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
273
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
274
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
275
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
276
}

powered by: WebSVN 2.1.0

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