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

Subversion Repositories openrisc_me

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

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
static int audio_cnt = 0;
54
 
55
static FILE *fo = 0;
56
 
57
/* Set a specific SPR with a value. */
58
void mtspr(uint16_t regno, const uorreg_t value)
59
{
60
  uorreg_t prev_val;
61
 
62
  prev_val = cpu_state.sprs[regno];
63
  cpu_state.sprs[regno] = value;
64
 
65
  /* MM: Register hooks.  */
66
  switch (regno) {
67
  case SPR_TTCR:
68
    spr_write_ttcr (value);
69
    break;
70
  case SPR_TTMR:
71
    spr_write_ttmr (prev_val);
72
    break;
73
  /* Data cache simulateing stuff */
74
  case SPR_DCBPR:
75
    /* FIXME: This is not correct.  The arch. manual states: "Memory accesses
76
     * are not recorded (Unlike load or store instructions) and cannot invoke
77
     * any exception".  If the physical address is invalid a bus error will be
78
     * generated.  Also if the effective address is not resident in the mmu
79
     * the read will happen from address 0, which is naturally not correct. */
80
    dc_simulate_read(peek_into_dtlb(value, 0, 1), value, 4);
81
    cpu_state.sprs[SPR_DCBPR] = 0;
82
    break;
83
  case SPR_DCBFR:
84
    dc_inv(value);
85
    cpu_state.sprs[SPR_DCBFR] = -1;
86
    break;
87
  case SPR_DCBIR:
88
    dc_inv(value);
89
    cpu_state.sprs[SPR_DCBIR] = 0;
90
    break;
91
  case SPR_DCBWR:
92
    cpu_state.sprs[SPR_DCBWR] = 0;
93
    break;
94
  case SPR_DCBLR:
95
    cpu_state.sprs[SPR_DCBLR] = 0;
96
    break;
97
  /* Instruction cache simulateing stuff */
98
  case SPR_ICBPR:
99
    /* FIXME: The arch manual does not say what happens when an invalid memory
100
     * location is specified.  I guess the same as for the DCBPR register */
101
    ic_simulate_fetch(peek_into_itlb(value), value);
102
    cpu_state.sprs[SPR_ICBPR] = 0;
103
    break;
104
  case SPR_ICBIR:
105
    ic_inv(value);
106
    cpu_state.sprs[SPR_ICBIR] = 0;
107
    break;
108
  case SPR_ICBLR:
109
    cpu_state.sprs[SPR_ICBLR] = 0;
110
    break;
111
  case SPR_SR:
112
    cpu_state.sprs[regno] |= SPR_SR_FO;
113
    if((value & SPR_SR_IEE) && !(prev_val & SPR_SR_IEE))
114
      pic_ints_en();
115
#if DYNAMIC_EXECUTION
116
    if((value & SPR_SR_IME) && !(prev_val & SPR_SR_IME)) {
117
      TRACE_(immu)("IMMU just became enabled (%lli).\n", runtime.sim.cycles);
118
      recheck_immu(IMMU_GOT_ENABLED);
119
    } else if(!(value & SPR_SR_IME) && (prev_val & SPR_SR_IME)) {
120
      TRACE_(immu)("Remove counting of mmu hit delay with cycles (%lli)\n",
121
                   runtime.sim.cycles);
122
      recheck_immu(IMMU_GOT_DISABLED);
123
    }
124
#endif
125
    break;
126
  case SPR_NPC:
127
    {
128
      /* The debugger has redirected us to a new address */
129
      /* This is usually done to reissue an instruction
130
         which just caused a breakpoint exception. */
131
 
132
      /* JPB patch. When GDB stepi, this may be used to set the PC to the
133
         value it is already at. If this is the case, then we do nothing (in
134
         particular we do not trash a delayed branch) */
135
 
136
      if (value != cpu_state.pc)
137
        {
138
          cpu_state.pc = value;
139
 
140
          if(!value && config.sim.verbose)
141
            PRINTF("WARNING: PC just set to 0!\n");
142
 
143
          /* Clear any pending delay slot jumps also */
144
          cpu_state.delay_insn = 0;
145
          pcnext = value + 4;
146
 
147
          /* Further JPB patch. If the processor is stalled, then subsequent
148
             reads of the NPC should return 0 until the processor is
149
             unstalled. If the processor is stalled, note that the NPC has
150
             been updated while the processor was stalled. */
151
 
152
          if (runtime.cpu.stalled)
153
            {
154
              cpu_state.npc_not_valid = 1;
155
            }
156
        }
157
    }
158
    break;
159
  case SPR_PICSR:
160
    if(!config.pic.edge_trigger)
161
      cpu_state.sprs[SPR_PICSR] = prev_val;
162
    break;
163
  case SPR_PICMR:
164
    if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
165
      pic_ints_en();
166
    break;
167
  case 0xFFFD:
168
    fo = fopen ("audiosim.pcm", "wb+");
169
    if (!fo) PRINTF("Cannot open audiosim.pcm\n");
170
    PRINTF("Audio opened.\n");
171
    break;
172
  case 0xFFFE:
173
    if (!fo) PRINTF("audiosim.pcm not opened\n");
174
    fputc (value & 0xFF, fo);
175
    if ((audio_cnt % 1024) == 0)
176
      PRINTF("%i\n", audio_cnt);
177
    audio_cnt++;
178
    break;
179
  case 0xFFFF:
180
    fclose(fo);
181
    PRINTF("Audio closed.\n");
182
    sim_done();
183
    break;
184
  case SPR_PMR:
185
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
186
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
187
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
188
      sim_done();
189
    }
190
    break;
191
  default:
192
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
193
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
194
      if((regno & 0xff) < 0x80)
195
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
196
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
197
      else
198
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
199
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
200
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
201
                              SPR_DTLBTR_SWE));
202
    }
203
 
204
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
205
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
206
      if((regno & 0xff) < 0x80)
207
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
208
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
209
      else
210
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
211
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
212
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
213
 
214
#if DYNAMIC_EXECUTION
215
      if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
216
        /* The immu got reconfigured.  Recheck if the current page in execution
217
         * is resident in the immu ways.  This check would be done during the
218
         * instruction fetch but since the dynamic execution model does not do
219
         * instruction fetchs, do it now. */
220
        recheck_immu(0);
221
      }
222
#endif
223
    }
224
 
225
    /* Links to GPRS */
226
    if(regno >= 0x0400 && regno < 0x0420) {
227
      cpu_state.reg[regno - 0x0400] = value;
228
    }
229
    break;
230
  }
231
}
232
 
233
/* Get a specific SPR. */
234
uorreg_t mfspr(const uint16_t regno)
235
{
236
  uorreg_t ret;
237
 
238
  ret = cpu_state.sprs[regno];
239
 
240
  switch (regno) {
241
  case SPR_NPC:
242
 
243
    /* The NPC is the program counter UNLESS the NPC has been changed and we
244
       are stalled, which will have flushed the pipeline, so the value is
245
       zero. Currently this is optional behavior, since it breaks GDB.
246
    */
247
 
248
    if (config.sim.strict_npc && cpu_state.npc_not_valid)
249
      {
250
        ret = 0;
251
      }
252
    else
253
      {
254
        ret = cpu_state.pc;
255
      }
256
    break;
257
 
258
  case SPR_TTCR:
259
    ret = spr_read_ttcr();
260
    break;
261
  default:
262
    /* Links to GPRS */
263
    if(regno >= 0x0400 && regno < 0x0420)
264
      ret = cpu_state.reg[regno - 0x0400];
265
  }
266
 
267
  return ret;
268
}
269
 
270
/* Show status of important SPRs. */
271
void sprs_status(void)
272
{
273
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
274
         cpu_state.sprs[SPR_UPR]);
275
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
276
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
277
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
278
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
279
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
280
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
281
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
282
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
283
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
284
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
285
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
286
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
287
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
288
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
289
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
290
}

powered by: WebSVN 2.1.0

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