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 153

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

powered by: WebSVN 2.1.0

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