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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [or1k/] [sprs.c] - Blame information for rev 167

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
#include "arch.h"
26
#include "sprs.h"
27 167 markom
#include "abstract.h"
28 23 lampret
 
29 133 markom
extern int cont_run;   /* defined in toplevel.c */
30
extern int tt_stopped; /* defined in tick.c */
31 167 markom
extern int flag;
32 23 lampret
 
33 167 markom
sprword sprs[MAX_SPRS];
34 23 lampret
 
35 123 markom
int temp_disable_except = 0;
36 133 markom
int audio_cnt = 0;
37 123 markom
 
38 133 markom
static FILE *fo = 0;
39 23 lampret
/* Set a specific SPR with a value. */
40 167 markom
inline void
41
mtspr(const int regno, const sprword value)
42 30 lampret
{
43 133 markom
  int ofs = regno % MAX_SPRS_PER_GRP;
44
 
45
  /* MM: Register hooks.  */
46
  switch (regno) {
47
  case 0xFFFD:
48
    fo = fopen ("audiosim.pcm", "wb+");
49
    if (!fo) printf("Cannot open audiosim.pcm\n");
50
    printf("Audio opened.\n");
51
    return;
52
  case 0xFFFE:
53
    if (!fo) printf("audiosim.pcm not opened\n");
54
    fputc (value & 0xFF, fo);
55
    if ((audio_cnt % 1024) == 0)
56
      printf("%i\n", audio_cnt);
57
    audio_cnt++;
58
    return;
59
  case 0xFFFF:
60
    fclose(fo);
61
    printf("Audio closed.\n");
62
    cont_run = 0;
63
    return;
64
  case SPR_TTMR:
65 167 markom
    if (value & SPR_TTMR_M == 0x80000000) break;
66 133 markom
  case SPR_TTCR:
67
    tt_stopped = 0;
68
    break;
69
  case 0x1234:
70
    printf("MTSPR(0x1234, %x);\n", value);
71
    break;
72 167 markom
  case 0x1235:
73
    {
74
      FILE *f;
75
      if (!(f = fopen("stdout.txt", "a+")))
76
        {
77
          perror(strerror(errno));
78
          return;
79
        }
80
      fprintf(f, "%c", value);
81
      if (fclose(f))
82
        perror(strerror(errno));
83
    }
84
    break;
85
  case SPR_SR:
86
    if(value & SPR_SR_F)
87
      flag = 1;
88
    else
89
      flag = 0;
90
    break;
91
  case SPR_EPCR_BASE:
92
    if((value & 0xffffff00) == 0x00020600)
93
      {
94
        printf("SIMON: EPCR = ext_int\n");
95
        cont_run = 0;
96
      }
97
    break;
98 133 markom
  }
99 139 chris
 
100
  /* What the hell is happening here? This looks like a bug
101
     waiting to happen. Assume regno = 2*MAX_SPRS_PER_GRP+3,
102
     which presumably means I want to set register 3 in
103
     group 2. Instead, I calculate ofs as 3, and regno as
104
     2, and get a final value of 5??? Is this correct?
105
     Oh well...I didn't write this. Who knows what it is
106
     actually supposed to do. It doesn't matter if regno
107
     is less than MAX_SPRS_PER_GRP, which is the only
108
     way I use it.  CZ - 21/06/01
109
  */
110
 
111 167 markom
  //regno /= MAX_SPRS_PER_GRP;
112
  //regno += ofs;
113 133 markom
 
114 139 chris
  /* CZ 21/06/01 ... the debugger wants to do this! */
115
  if(GlobalMode)
116
    {
117
      extern unsigned long pc;
118 153 chris
      extern unsigned long pcnext;
119
      extern int delay_insn;
120
      extern unsigned long pcdelay;
121 139 chris
 
122
      if(regno == SPR_PC)
123
        {
124
          sprs[SPR_PC] = value;
125 153 chris
 
126
          /* The debugger has redirected us to a new address */
127
          /* This is usually done to reissue an instruction
128
             which just caused a breakpoint exception. */
129
          pcnext = value;
130
 
131
          if(!value)
132
            {
133
              printf("WARNING: Debugger just set us to 0!\n");
134
            }
135
 
136
          /* Clear any pending delay slot jumps also */
137
          delay_insn = 0;
138
          pcdelay = value+4;
139
 
140 139 chris
          return;
141
        }
142
    }
143
 
144 133 markom
  /*    printf("mtspr(%x, %x)\n", regno, value);
145
   */   if (regno < MAX_SPRS)
146
     sprs[regno] = value;
147
   else {
148 167 markom
     printf("\nABORT: write out of SPR range %08X\n", regno);
149 133 markom
     cont_run = 0;
150
   }
151 23 lampret
}
152
 
153
/* Get a specific SPR. */
154 167 markom
inline sprword
155
mfspr_(const int regno)
156 30 lampret
{
157 139 chris
  /* CZ 21/06/01 ... the debugger wants to do this! */
158 167 markom
  {
159
    extern unsigned long pc;
160
 
161
    if(regno == SPR_PC)
162
      return pc;
163
  }
164 139 chris
 
165 133 markom
  /* MM: l.rfe, for example, temporarly disables
166
     exceptions.  We will make it appear as SR bit
167
     is set.  */
168
  if (regno == SPR_SR && temp_disable_except > 0)
169 167 markom
    return sprs[regno] & ~SPR_SR_EXR;
170 133 markom
  /*  printf("mfspr(%x)%x\n", regno, sprs[regno]); */
171 23 lampret
 
172 133 markom
  if (regno < MAX_SPRS)
173
    return sprs[regno];
174
  else {
175 167 markom
    printf("\nABORT: read out of SPR range %08X\n", regno);
176 133 markom
    cont_run = 0;
177 167 markom
  }
178 133 markom
  return 0;
179 23 lampret
}
180
 
181
/* Set a specific bit from SPR. LSB in a word is numbered zero. */
182 167 markom
inline void
183
setsprbit(const int regno, const int bitnum, const unsigned long bitvalue)
184 23 lampret
{
185 133 markom
  sprword mask;
186
  sprword regvalue = mfspr(regno);
187
 
188
  mask = ~(1 << bitnum);
189
 
190
  mtspr(regno, (regvalue & mask) | ((bitvalue & 0x1) << bitnum));
191
 
192
  return;
193 23 lampret
}
194
 
195
/* Get a specific bit from SPR. */
196 167 markom
inline int
197
getsprbit(const int regno, const int bitnum)
198 23 lampret
{
199 133 markom
  sprword regvalue = mfspr(regno);
200 23 lampret
 
201 133 markom
  return (regvalue >> bitnum) & 0x1;
202 23 lampret
}
203 30 lampret
 
204 63 lampret
/* Set specific SPR bit(s) identified by mask. */
205 167 markom
inline void
206
setsprbits(const int regno, const unsigned long mask, const unsigned long value)
207 63 lampret
{
208 133 markom
  sprword regvalue = mfspr(regno);
209
  sprword shifted = 0x0;
210
  int m, v = 0;
211
 
212
  /* m counts bits in valuemask */
213
  /* v counts bits in value */
214
  for (m = 0; m < 32; m++)
215
    if ((mask >> m) & 0x1) {
216
      shifted |= ((value >> v) & 0x1) << m;
217
      v++;
218
    }
219
 
220
  /* printf("oldvalue %x setsprbits(%x, %x, %x)  shifted %x", regvalue, regno, mask, value, shifted); */
221
  mtspr(regno, (regvalue & ~mask) | shifted);
222
 
223
  return;
224 63 lampret
}
225
 
226
/* Get specific SPR bit(s) identified by mask. */
227 167 markom
inline unsigned long
228
getsprbits(const int regno, const unsigned long mask)
229 63 lampret
{
230 133 markom
  sprword regvalue = mfspr(regno);
231
  sprword shifted = 0x0;
232
  int m, v = 0;
233
 
234
  /* m counts bits in valuemask */
235
  /* v counts bits in regvalue */
236
  for (m = 0; m < 32; m++)
237
    if ((mask >> m) & 0x1) {
238
      shifted |= ((regvalue >> m) & 0x1) << v;
239
      v++;
240
    }
241
 
242
  return shifted;
243 63 lampret
}
244
 
245 167 markom
/* Get specific SPR bit(s) identified by mask. */
246
inline unsigned long
247
testsprbits(const int regno, const unsigned long mask)
248
{
249
  sprword regvalue = mfspr(regno);
250
  return regvalue & mask;
251
}
252
 
253 30 lampret
/* Show status of important SPRs. */
254
void sprs_status()
255
{
256 133 markom
  printf("VR   : 0x%.8x  UPR  : 0x%.8x\n", mfspr(SPR_VR), mfspr(SPR_UPR));
257
  printf("SR   : 0x%.8x\n", mfspr(SPR_SR));
258
  printf("MACLO: 0x%.8x  MACHI: 0x%.8x\n", mfspr(SPR_MACLO), mfspr(SPR_MACHI));
259
  printf("EPCR0: 0x%.8x  EPCR1: 0x%.8x\n", mfspr(SPR_EPCR_BASE), mfspr(SPR_EPCR_BASE+1));
260
  printf("EEAR0: 0x%.8x  EEAR1: 0x%.8x\n", mfspr(SPR_EEAR_BASE), mfspr(SPR_EEAR_BASE+1));
261
  printf("ESR0 : 0x%.8x  ESR1 : 0x%.8x\n", mfspr(SPR_ESR_BASE), mfspr(SPR_ESR_BASE+1));
262
}

powered by: WebSVN 2.1.0

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