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

Subversion Repositories openrisc

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

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
    break;
112
  case SPR_NPC:
113
    {
114
      /* The debugger has redirected us to a new address */
115
      /* This is usually done to reissue an instruction
116
         which just caused a breakpoint exception. */
117
 
118
      /* JPB patch. When GDB stepi, this may be used to set the PC to the
119
         value it is already at. If this is the case, then we do nothing (in
120
         particular we do not trash a delayed branch) */
121
 
122
      if (value != cpu_state.pc)
123
        {
124
          cpu_state.pc = value;
125
 
126
          if(!value && config.sim.verbose)
127
            PRINTF("WARNING: PC just set to 0!\n");
128
 
129
          /* Clear any pending delay slot jumps also */
130
          cpu_state.delay_insn = 0;
131
          pcnext = value + 4;
132
 
133
          /* Further JPB patch. If the processor is stalled, then subsequent
134
             reads of the NPC should return 0 until the processor is
135
             unstalled. If the processor is stalled, note that the NPC has
136
             been updated while the processor was stalled. */
137
 
138
          if (runtime.cpu.stalled)
139
            {
140
              cpu_state.npc_not_valid = 1;
141
            }
142
        }
143
    }
144
    break;
145
  case SPR_PICSR:
146
    if(!config.pic.edge_trigger)
147 436 julius
      /* When configured with level triggered interrupts we clear PICSR in PIC
148
         peripheral model when incoming IRQ goes low */
149 19 jeremybenn
      cpu_state.sprs[SPR_PICSR] = prev_val;
150
    break;
151
  case SPR_PICMR:
152 432 jeremybenn
    /* If we have non-maskable interrupts, then the bottom two bits are always
153
       one. */
154
    if (config.pic.use_nmi)
155
      {
156 508 jeremybenn
        cpu_state.sprs[SPR_PICMR] |= 0x00000003;
157 432 jeremybenn
      }
158
 
159 19 jeremybenn
    if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
160
      pic_ints_en();
161
    break;
162
  case SPR_PMR:
163
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
164
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
165
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
166
      sim_done();
167
    }
168
    break;
169
  default:
170
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
171
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
172
      if((regno & 0xff) < 0x80)
173
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
174
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
175
      else
176
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
177
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
178
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
179
                              SPR_DTLBTR_SWE));
180
    }
181
 
182
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
183
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
184
      if((regno & 0xff) < 0x80)
185
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
186
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
187
      else
188
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
189
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
190
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
191
 
192
    }
193
 
194
    /* Links to GPRS */
195
    if(regno >= 0x0400 && regno < 0x0420) {
196
      cpu_state.reg[regno - 0x0400] = value;
197
    }
198
    break;
199
  }
200
}
201
 
202
/* Get a specific SPR. */
203
uorreg_t mfspr(const uint16_t regno)
204
{
205
  uorreg_t ret;
206
 
207
  ret = cpu_state.sprs[regno];
208
 
209
  switch (regno) {
210
  case SPR_NPC:
211
 
212
    /* The NPC is the program counter UNLESS the NPC has been changed and we
213
       are stalled, which will have flushed the pipeline, so the value is
214
       zero. Currently this is optional behavior, since it breaks GDB.
215
    */
216
 
217
    if (config.sim.strict_npc && cpu_state.npc_not_valid)
218
      {
219
        ret = 0;
220
      }
221
    else
222
      {
223
        ret = cpu_state.pc;
224
      }
225
    break;
226
 
227
  case SPR_TTCR:
228
    ret = spr_read_ttcr();
229
    break;
230 226 julius
  case SPR_FPCSR:
231
    // If hard floating point is disabled - return 0
232
    if (!config.cpu.hardfloat)
233
      ret = 0;
234
    break;
235 19 jeremybenn
  default:
236
    /* Links to GPRS */
237
    if(regno >= 0x0400 && regno < 0x0420)
238
      ret = cpu_state.reg[regno - 0x0400];
239
  }
240
 
241
  return ret;
242
}
243
 
244
/* Show status of important SPRs. */
245
void sprs_status(void)
246
{
247
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
248
         cpu_state.sprs[SPR_UPR]);
249
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
250
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
251
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
252
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
253
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
254
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
255
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
256
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
257
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
258
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
259
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
260
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
261
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
262
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
263
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
264
}

powered by: WebSVN 2.1.0

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