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

Subversion Repositories or1k

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

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 23 lampret
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23 167 markom
#include <errno.h>
24 23 lampret
 
25 1350 nogj
#include "config.h"
26
 
27
#ifdef HAVE_INTTYPES_H
28
#include <inttypes.h>
29
#endif
30
 
31
#include "port.h"
32 23 lampret
#include "arch.h"
33 1350 nogj
#include "abstract.h"
34 479 markom
#include "sim-config.h"
35 1308 phoenix
#include "except.h"
36 1432 nogj
#include "opcode/or32.h"
37
#include "spr_defs.h"
38 1350 nogj
#include "execute.h"
39 1432 nogj
#include "sprs.h"
40 1402 nogj
#include "dcache_model.h"
41 1404 nogj
#include "icache_model.h"
42 1557 nogj
#include "tick.h"
43
#include "dmmu.h"
44
#include "immu.h"
45 1452 nogj
#include "debug.h"
46 23 lampret
 
47 1532 nogj
DEFAULT_DEBUG_CHANNEL(spr);
48 1452 nogj
DECLARE_DEBUG_CHANNEL(immu);
49 1432 nogj
 
50 1550 nogj
static int audio_cnt = 0;
51 123 markom
 
52 133 markom
static FILE *fo = 0;
53 1532 nogj
 
54 23 lampret
/* Set a specific SPR with a value. */
55 1532 nogj
void mtspr(uint16_t regno, const uorreg_t value)
56 30 lampret
{
57 1508 nogj
  uorreg_t prev_val;
58 1452 nogj
 
59
  prev_val = cpu_state.sprs[regno];
60 1432 nogj
  cpu_state.sprs[regno] = value;
61 1532 nogj
 
62
  TRACE("%s\n", dump_spr(regno, value));
63 133 markom
 
64
  /* MM: Register hooks.  */
65
  switch (regno) {
66
  case SPR_TTCR:
67 728 markom
    spr_write_ttcr (value);
68 133 markom
    break;
69 728 markom
  case SPR_TTMR:
70 1540 nogj
    spr_write_ttmr (prev_val);
71 728 markom
    break;
72 1402 nogj
  /* Data cache simulateing stuff */
73
  case SPR_DCBPR:
74 1529 nogj
    /* FIXME: This is not correct.  The arch. manual states: "Memory accesses
75
     * are not recorded (Unlike load or store instructions) and cannot invoke
76
     * any exception".  If the physical address is invalid a bus error will be
77
     * generated.  Also if the effective address is not resident in the mmu
78
     * the read will happen from address 0, which is naturally not correct. */
79
    dc_simulate_read(peek_into_dtlb(value, 0, 1), value, 4);
80
    cpu_state.sprs[SPR_DCBPR] = 0;
81 1402 nogj
    break;
82
  case SPR_DCBFR:
83 1529 nogj
    dc_inv(value);
84
    cpu_state.sprs[SPR_DCBFR] = -1;
85 1402 nogj
    break;
86
  case SPR_DCBIR:
87 1529 nogj
    dc_inv(value);
88
    cpu_state.sprs[SPR_DCBIR] = 0;
89 1402 nogj
    break;
90
  case SPR_DCBWR:
91 1432 nogj
    cpu_state.sprs[SPR_DCBWR] = 0;
92 1402 nogj
    break;
93
  case SPR_DCBLR:
94 1432 nogj
    cpu_state.sprs[SPR_DCBLR] = 0;
95 1402 nogj
    break;
96 1404 nogj
  /* Instruction cache simulateing stuff */
97
  case SPR_ICBPR:
98 1529 nogj
    /* FIXME: The arch manual does not say what happens when an invalid memory
99
     * location is specified.  I guess the same as for the DCBPR register */
100 1557 nogj
    ic_simulate_fetch(peek_into_itlb(value), value);
101 1529 nogj
    cpu_state.sprs[SPR_ICBPR] = 0;
102 1404 nogj
    break;
103
  case SPR_ICBIR:
104 1529 nogj
    ic_inv(value);
105
    cpu_state.sprs[SPR_ICBIR] = 0;
106 1404 nogj
    break;
107
  case SPR_ICBLR:
108 1432 nogj
    cpu_state.sprs[SPR_ICBLR] = 0;
109 1404 nogj
    break;
110 167 markom
  case SPR_SR:
111 1432 nogj
    cpu_state.sprs[regno] |= SPR_SR_FO;
112 1452 nogj
#if DYNAMIC_EXECUTION
113
    if((value & SPR_SR_IME) && !(prev_val & SPR_SR_IME)) {
114
      TRACE_(immu)("IMMU just became enabled (%lli).\n", runtime.sim.cycles);
115
      recheck_immu(IMMU_GOT_ENABLED);
116
    } else if(!(value & SPR_SR_IME) && (prev_val & SPR_SR_IME)) {
117
      TRACE_(immu)("Remove counting of mmu hit delay with cycles (%lli)\n",
118
                   runtime.sim.cycles);
119
      recheck_immu(IMMU_GOT_DISABLED);
120
    }
121
#endif
122 167 markom
    break;
123 378 markom
  case SPR_NPC:
124 139 chris
    {
125 242 markom
      /* The debugger has redirected us to a new address */
126
      /* This is usually done to reissue an instruction
127
         which just caused a breakpoint exception. */
128 1432 nogj
      cpu_state.pc = value;
129 242 markom
 
130 479 markom
      if(!value && config.sim.verbose)
131 997 markom
        PRINTF("WARNING: PC just set to 0!\n");
132 242 markom
 
133
      /* Clear any pending delay slot jumps also */
134 1432 nogj
      cpu_state.delay_insn = 0;
135 479 markom
      pcnext = value + 4;
136 139 chris
    }
137 242 markom
    break;
138 728 markom
  case 0xFFFD:
139
    fo = fopen ("audiosim.pcm", "wb+");
140 997 markom
    if (!fo) PRINTF("Cannot open audiosim.pcm\n");
141
    PRINTF("Audio opened.\n");
142 728 markom
    break;
143
  case 0xFFFE:
144 997 markom
    if (!fo) PRINTF("audiosim.pcm not opened\n");
145 728 markom
    fputc (value & 0xFF, fo);
146
    if ((audio_cnt % 1024) == 0)
147 997 markom
      PRINTF("%i\n", audio_cnt);
148 728 markom
    audio_cnt++;
149
    break;
150
  case 0xFFFF:
151
    fclose(fo);
152 997 markom
    PRINTF("Audio closed.\n");
153 1471 nogj
    sim_done();
154 728 markom
    break;
155 1446 nogj
  case SPR_PMR:
156
    /* PMR[SDF] and PMR[DCGE] are ignored completely. */
157
    if (value & SPR_PMR_SUME) {
158
      PRINTF ("SUSPEND: PMR[SUME] bit was set.\n");
159 1471 nogj
      sim_done();
160 1446 nogj
    }
161
    break;
162 479 markom
  default:
163 1549 nogj
    /* Mask reserved bits in DTLBMR and DTLBMR registers */
164 886 simons
    if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
165
      if((regno & 0xff) < 0x80)
166 1432 nogj
        cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
167 886 simons
                              (value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
168
      else
169 1432 nogj
        cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
170 886 simons
                              (value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
171
                              SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
172
                              SPR_DTLBTR_SWE));
173
    }
174
 
175
    /* Mask reseved bits in ITLBMR and ITLBMR registers */
176
    if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
177 1452 nogj
      TRACE_(immu)("Writting to an mmu way (reg: %"PRIx16", value: %"PRIx32")\n",
178
                   regno, value);
179 886 simons
      if((regno & 0xff) < 0x80)
180 1432 nogj
        cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
181 886 simons
                              (value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
182
      else
183 1432 nogj
        cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
184 886 simons
                              (value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
185
                              SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
186 1452 nogj
 
187
#if DYNAMIC_EXECUTION
188
      if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
189
        /* The immu got reconfigured.  Recheck if the current page in execution
190
         * is resident in the immu ways.  This check would be done during the
191
         * instruction fetch but since the dynamic execution model does not do
192
         * instruction fetchs, do it now. */
193
        recheck_immu(0);
194
      }
195
#endif
196 886 simons
    }
197 1432 nogj
 
198 479 markom
    /* Links to GPRS */
199 728 markom
    if(regno >= 0x0400 && regno < 0x0420) {
200 1432 nogj
      cpu_state.reg[regno - 0x0400] = value;
201 728 markom
    }
202 479 markom
    break;
203 378 markom
  }
204 23 lampret
}
205
 
206 1508 nogj
/* Get a specific SPR. */
207
uorreg_t mfspr(const uint16_t regno)
208
{
209 1531 nogj
  uorreg_t ret;
210 1508 nogj
 
211 1531 nogj
  ret = cpu_state.sprs[regno];
212
 
213 1508 nogj
  switch (regno) {
214
  case SPR_NPC:
215 1531 nogj
    ret = cpu_state.pc;
216 1579 nogj
    break;
217 1508 nogj
  case SPR_TTCR:
218 1531 nogj
    ret = spr_read_ttcr();
219 1579 nogj
    break;
220 1508 nogj
  default:
221
    /* Links to GPRS */
222
    if(regno >= 0x0400 && regno < 0x0420)
223 1531 nogj
      ret = cpu_state.reg[regno - 0x0400];
224 1508 nogj
  }
225 1531 nogj
 
226 1532 nogj
  TRACE("%s\n", dump_spr(regno, ret));
227
 
228 1531 nogj
  return ret;
229 1508 nogj
}
230
 
231 30 lampret
/* Show status of important SPRs. */
232 1508 nogj
void sprs_status(void)
233 30 lampret
{
234 1508 nogj
  PRINTF("VR   : 0x%"PRIxREG"  UPR  : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_VR],
235
         cpu_state.sprs[SPR_UPR]);
236
  PRINTF("SR   : 0x%"PRIxREG"\n", cpu_state.sprs[SPR_SR]);
237
  PRINTF("MACLO: 0x%"PRIxREG"  MACHI: 0x%"PRIxREG"\n",
238
         cpu_state.sprs[SPR_MACLO], cpu_state.sprs[SPR_MACHI]);
239
  PRINTF("EPCR0: 0x%"PRIxADDR"  EPCR1: 0x%"PRIxADDR"\n",
240
         cpu_state.sprs[SPR_EPCR_BASE], cpu_state.sprs[SPR_EPCR_BASE+1]);
241
  PRINTF("EEAR0: 0x%"PRIxADDR"  EEAR1: 0x%"PRIxADDR"\n",
242
         cpu_state.sprs[SPR_EEAR_BASE], cpu_state.sprs[SPR_EEAR_BASE+1]);
243
  PRINTF("ESR0 : 0x%"PRIxREG"  ESR1 : 0x%"PRIxREG"\n",
244
         cpu_state.sprs[SPR_ESR_BASE], cpu_state.sprs[SPR_ESR_BASE+1]);
245
  PRINTF("TTMR : 0x%"PRIxREG"  TTCR : 0x%"PRIxREG"\n",
246
         cpu_state.sprs[SPR_TTMR], cpu_state.sprs[SPR_TTCR]);
247
  PRINTF("PICMR: 0x%"PRIxREG"  PICSR: 0x%"PRIxREG"\n",
248
         cpu_state.sprs[SPR_PICMR], cpu_state.sprs[SPR_PICSR]);
249
  PRINTF("PPC:   0x%"PRIxADDR"  NPC   : 0x%"PRIxADDR"\n",
250
         cpu_state.sprs[SPR_PPC], cpu_state.sprs[SPR_NPC]);
251 133 markom
}

powered by: WebSVN 2.1.0

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