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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [cpu/] [or1k/] [sprs.c] - Blame information for rev 1765

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

powered by: WebSVN 2.1.0

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