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

Subversion Repositories or1k

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

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 1432 nogj
      cpu_state.pc = value;
132 242 markom
 
133 479 markom
      if(!value && config.sim.verbose)
134 997 markom
        PRINTF("WARNING: PC just set to 0!\n");
135 242 markom
 
136
      /* Clear any pending delay slot jumps also */
137 1432 nogj
      cpu_state.delay_insn = 0;
138 479 markom
      pcnext = value + 4;
139 139 chris
    }
140 242 markom
    break;
141 1715 nogj
  case SPR_PICSR:
142 1748 jeremybenn
    if(!config.pic.edge_trigger)
143 1715 nogj
      cpu_state.sprs[SPR_PICSR] = prev_val;
144
    break;
145
  case SPR_PICMR:
146
    if(cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
147
      pic_ints_en();
148
    break;
149 728 markom
  case 0xFFFD:
150
    fo = fopen ("audiosim.pcm", "wb+");
151 997 markom
    if (!fo) PRINTF("Cannot open audiosim.pcm\n");
152
    PRINTF("Audio opened.\n");
153 728 markom
    break;
154
  case 0xFFFE:
155 997 markom
    if (!fo) PRINTF("audiosim.pcm not opened\n");
156 728 markom
    fputc (value & 0xFF, fo);
157
    if ((audio_cnt % 1024) == 0)
158 997 markom
      PRINTF("%i\n", audio_cnt);
159 728 markom
    audio_cnt++;
160
    break;
161
  case 0xFFFF:
162
    fclose(fo);
163 997 markom
    PRINTF("Audio closed.\n");
164 1471 nogj
    sim_done();
165 728 markom
    break;
166 1446 nogj
  case SPR_PMR:
167
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
168 1748 jeremybenn
    if (config.pm.enabled && (value & SPR_PMR_SUME)) {
169 1446 nogj
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
170 1471 nogj
      sim_done();
171 1446 nogj
    }
172
    break;
173 479 markom
  default:
174 1549 nogj
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
175 886 simons
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
176
      if((regno & 0xff) < 0x80)
177 1652 nogj
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
178 886 simons
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
179
      else
180 1652 nogj
        cpu_state.sprs[regno] = DADDR_PAGE(value) |
181 886 simons
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
182
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
183
                              SPR_DTLBTR_SWE));
184
    }
185
 
186
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
187
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
188
      if((regno & 0xff) < 0x80)
189 1652 nogj
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
190 886 simons
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
191
      else
192 1652 nogj
        cpu_state.sprs[regno] = IADDR_PAGE(value) |
193 886 simons
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
194
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
195 1452 nogj
 
196
#if DYNAMIC_EXECUTION
197
      if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
198
        /* The immu got reconfigured.  Recheck if the current page in execution
199
         * is resident in the immu ways.  This check would be done during the
200
         * instruction fetch but since the dynamic execution model does not do
201
         * instruction fetchs, do it now. */
202
        recheck_immu(0);
203
      }
204
#endif
205 886 simons
    }
206 1432 nogj
 
207 479 markom
    /* Links to GPRS */
208 728 markom
    if(regno >= 0x0400 && regno < 0x0420) {
209 1432 nogj
      cpu_state.reg[regno - 0x0400] = value;
210 728 markom
    }
211 479 markom
    break;
212 378 markom
  }
213 23 lampret
}
214
 
215 1508 nogj
/* Get a specific SPR. */
216
uorreg_t mfspr(const uint16_t regno)
217
{
218 1531 nogj
  uorreg_t ret;
219 1508 nogj
 
220 1531 nogj
  ret = cpu_state.sprs[regno];
221
 
222 1508 nogj
  switch (regno) {
223
  case SPR_NPC:
224 1531 nogj
    ret = cpu_state.pc;
225 1579 nogj
    break;
226 1508 nogj
  case SPR_TTCR:
227 1531 nogj
    ret = spr_read_ttcr();
228 1579 nogj
    break;
229 1508 nogj
  default:
230
    /* Links to GPRS */
231
    if(regno >= 0x0400 && regno < 0x0420)
232 1531 nogj
      ret = cpu_state.reg[regno - 0x0400];
233 1508 nogj
  }
234 1531 nogj
 
235
  return ret;
236 1508 nogj
}
237
 
238 30 lampret
/* Show status of important SPRs. */
239 1508 nogj
void sprs_status(void)
240 30 lampret
{
241 1508 nogj
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
242
         cpu_state.sprs[SPR_UPR]);
243
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
244
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
245
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
246
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
247
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
248
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
249
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
250
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
251
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
252
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
253
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
254
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
255
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
256
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
257
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
258 133 markom
}

powered by: WebSVN 2.1.0

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