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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 28 lampret
/* sprs.c -- Simulation of OR1K special-purpose registers
2 1748 jeremybenn
 
3 23 lampret
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
5 23 lampret
 
6 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7 23 lampret
 
8 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9 23 lampret
 
10 1748 jeremybenn
   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 23 lampret
 
15 1748 jeremybenn
   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 23 lampret
 
20 1748 jeremybenn
   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 23 lampret
#include <stdlib.h>
33
#include <stdio.h>
34 167 markom
#include <errno.h>
35 23 lampret
 
36 1748 jeremybenn
/* Package includes */
37
#include "sprs.h"
38 479 markom
#include "sim-config.h"
39 1748 jeremybenn
#include "debug.h"
40 1350 nogj
#include "execute.h"
41 1748 jeremybenn
#include "spr-defs.h"
42 1557 nogj
#include "tick.h"
43 1748 jeremybenn
#include "dcache-model.h"
44
#include "icache-model.h"
45 1557 nogj
#include "dmmu.h"
46
#include "immu.h"
47 1748 jeremybenn
#include "toplevel-support.h"
48 1715 nogj
#include "pic.h"
49 23 lampret
 
50 1748 jeremybenn
 
51 1452 nogj
DECLARE_DEBUG_CHANNEL(immu);
52 1432 nogj
 
53 1550 nogj
static int audio_cnt = 0;
54 123 markom
 
55 133 markom
static FILE *fo = 0;
56 1532 nogj
 
57 23 lampret
/* Set a specific SPR with a value. */
58 1532 nogj
void mtspr(uint16_t regno, const uorreg_t value)
59 30 lampret
{
60 1508 nogj
  uorreg_t prev_val;
61 1452 nogj
 
62
  prev_val = cpu_state.sprs[regno];
63 1432 nogj
  cpu_state.sprs[regno] = value;
64 1532 nogj
 
65 133 markom
  /* MM: Register hooks.  */
66
  switch (regno) {
67
  case SPR_TTCR:
68 728 markom
    spr_write_ttcr (value);
69 133 markom
    break;
70 728 markom
  case SPR_TTMR:
71 1540 nogj
    spr_write_ttmr (prev_val);
72 728 markom
    break;
73 1402 nogj
  /* Data cache simulateing stuff */
74
  case SPR_DCBPR:
75 1529 nogj
    /* 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 1402 nogj
    break;
83
  case SPR_DCBFR:
84 1529 nogj
    dc_inv(value);
85
    cpu_state.sprs[SPR_DCBFR] = -1;
86 1402 nogj
    break;
87
  case SPR_DCBIR:
88 1529 nogj
    dc_inv(value);
89
    cpu_state.sprs[SPR_DCBIR] = 0;
90 1402 nogj
    break;
91
  case SPR_DCBWR:
92 1432 nogj
    cpu_state.sprs[SPR_DCBWR] = 0;
93 1402 nogj
    break;
94
  case SPR_DCBLR:
95 1432 nogj
    cpu_state.sprs[SPR_DCBLR] = 0;
96 1402 nogj
    break;
97 1404 nogj
  /* Instruction cache simulateing stuff */
98
  case SPR_ICBPR:
99 1529 nogj
    /* 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 1557 nogj
    ic_simulate_fetch(peek_into_itlb(value), value);
102 1529 nogj
    cpu_state.sprs[SPR_ICBPR] = 0;
103 1404 nogj
    break;
104
  case SPR_ICBIR:
105 1529 nogj
    ic_inv(value);
106
    cpu_state.sprs[SPR_ICBIR] = 0;
107 1404 nogj
    break;
108
  case SPR_ICBLR:
109 1432 nogj
    cpu_state.sprs[SPR_ICBLR] = 0;
110 1404 nogj
    break;
111 167 markom
  case SPR_SR:
112 1432 nogj
    cpu_state.sprs[regno] |= SPR_SR_FO;
113 1715 nogj
    if((value & SPR_SR_IEE) && !(prev_val & SPR_SR_IEE))
114
      pic_ints_en();
115 1452 nogj
#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 167 markom
    break;
126 378 markom
  case SPR_NPC:
127 139 chris
    {
128 242 markom
      /* 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 1756 jeremybenn
 
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 242 markom
 
140 1756 jeremybenn
          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 139 chris
    }
158 242 markom
    break;
159 1715 nogj
  case SPR_PICSR:
160 1748 jeremybenn
    if(!config.pic.edge_trigger)
161 1715 nogj
      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 728 markom
  case 0xFFFD:
168
    fo = fopen ("audiosim.pcm", "wb+");
169 997 markom
    if (!fo) PRINTF("Cannot open audiosim.pcm\n");
170
    PRINTF("Audio opened.\n");
171 728 markom
    break;
172
  case 0xFFFE:
173 997 markom
    if (!fo) PRINTF("audiosim.pcm not opened\n");
174 728 markom
    fputc (value & 0xFF, fo);
175
    if ((audio_cnt % 1024) == 0)
176 997 markom
      PRINTF("%i\n", audio_cnt);
177 728 markom
    audio_cnt++;
178
    break;
179
  case 0xFFFF:
180
    fclose(fo);
181 997 markom
    PRINTF("Audio closed.\n");
182 1471 nogj
    sim_done();
183 728 markom
    break;
184 1446 nogj
  case SPR_PMR:
185
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
186 1748 jeremybenn
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
187 1446 nogj
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
188 1471 nogj
      sim_done();
189 1446 nogj
    }
190
    break;
191 479 markom
  default:
192 1549 nogj
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
193 886 simons
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
194
      if((regno & 0xff) < 0x80)
195 1652 nogj
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
196 886 simons
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
197
      else
198 1652 nogj
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
199 886 simons
                              (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 1652 nogj
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
208 886 simons
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
209
      else
210 1652 nogj
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
211 886 simons
                              (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 1452 nogj
 
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 886 simons
    }
224 1432 nogj
 
225 479 markom
    /* Links to GPRS */
226 728 markom
    if(regno >= 0x0400 && regno < 0x0420) {
227 1432 nogj
      cpu_state.reg[regno - 0x0400] = value;
228 728 markom
    }
229 479 markom
    break;
230 378 markom
  }
231 23 lampret
}
232
 
233 1508 nogj
/* Get a specific SPR. */
234
uorreg_t mfspr(const uint16_t regno)
235
{
236 1531 nogj
  uorreg_t ret;
237 1508 nogj
 
238 1531 nogj
  ret = cpu_state.sprs[regno];
239
 
240 1508 nogj
  switch (regno) {
241
  case SPR_NPC:
242 1756 jeremybenn
 
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 1579 nogj
    break;
257 1756 jeremybenn
 
258 1508 nogj
  case SPR_TTCR:
259 1531 nogj
    ret = spr_read_ttcr();
260 1579 nogj
    break;
261 1508 nogj
  default:
262
    /* Links to GPRS */
263
    if(regno >= 0x0400 && regno < 0x0420)
264 1531 nogj
      ret = cpu_state.reg[regno - 0x0400];
265 1508 nogj
  }
266 1531 nogj
 
267
  return ret;
268 1508 nogj
}
269
 
270 30 lampret
/* Show status of important SPRs. */
271 1508 nogj
void sprs_status(void)
272 30 lampret
{
273 1508 nogj
  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 133 markom
}

powered by: WebSVN 2.1.0

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