Merge zizzer:/bk/newmem
[gem5.git] / src / arch / sparc / regfile.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 * Ali Saidi
30 */
31
32 #include "arch/sparc/regfile.hh"
33 #include "cpu/thread_context.hh"
34
35 class Checkpoint;
36
37 using namespace SparcISA;
38 using namespace std;
39
40 //RegFile class methods
41 Addr RegFile::readPC()
42 {
43 return pc;
44 }
45
46 void RegFile::setPC(Addr val)
47 {
48 pc = val;
49 }
50
51 Addr RegFile::readNextPC()
52 {
53 return npc;
54 }
55
56 void RegFile::setNextPC(Addr val)
57 {
58 npc = val;
59 }
60
61 Addr RegFile::readNextNPC()
62 {
63 return nnpc;
64 }
65
66 void RegFile::setNextNPC(Addr val)
67 {
68 nnpc = val;
69 }
70
71 void RegFile::clear()
72 {
73 intRegFile.clear();
74 floatRegFile.clear();
75 }
76
77 MiscReg RegFile::readMiscReg(int miscReg)
78 {
79 return miscRegFile.readReg(miscReg);
80 }
81
82 MiscReg RegFile::readMiscRegWithEffect(int miscReg,
83 Fault &fault, ThreadContext *tc)
84 {
85 fault = NoFault;
86 return miscRegFile.readRegWithEffect(miscReg, tc);
87 }
88
89 Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
90 {
91 miscRegFile.setReg(miscReg, val);
92 return NoFault;
93 }
94
95 Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
96 ThreadContext * tc)
97 {
98 miscRegFile.setRegWithEffect(miscReg, val, tc);
99 return NoFault;
100 }
101
102 FloatReg RegFile::readFloatReg(int floatReg, int width)
103 {
104 return floatRegFile.readReg(floatReg, width);
105 }
106
107 FloatReg RegFile::readFloatReg(int floatReg)
108 {
109 //Use the "natural" width of a single float
110 return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
111 }
112
113 FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
114 {
115 return floatRegFile.readRegBits(floatReg, width);
116 }
117
118 FloatRegBits RegFile::readFloatRegBits(int floatReg)
119 {
120 //Use the "natural" width of a single float
121 return floatRegFile.readRegBits(floatReg,
122 FloatRegFile::SingleWidth);
123 }
124
125 Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
126 {
127 return floatRegFile.setReg(floatReg, val, width);
128 }
129
130 Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
131 {
132 //Use the "natural" width of a single float
133 return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
134 }
135
136 Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
137 {
138 return floatRegFile.setRegBits(floatReg, val, width);
139 }
140
141 Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
142 {
143 //Use the "natural" width of a single float
144 return floatRegFile.setRegBits(floatReg, val,
145 FloatRegFile::SingleWidth);
146 }
147
148 IntReg RegFile::readIntReg(int intReg)
149 {
150 return intRegFile.readReg(intReg);
151 }
152
153 Fault RegFile::setIntReg(int intReg, const IntReg &val)
154 {
155 return intRegFile.setReg(intReg, val);
156 }
157
158 void RegFile::serialize(std::ostream &os)
159 {
160 intRegFile.serialize(os);
161 floatRegFile.serialize(os);
162 miscRegFile.serialize(os);
163 SERIALIZE_SCALAR(pc);
164 SERIALIZE_SCALAR(npc);
165 }
166
167 void RegFile::unserialize(Checkpoint *cp, const std::string &section)
168 {
169 intRegFile.unserialize(cp, section);
170 floatRegFile.unserialize(cp, section);
171 miscRegFile.unserialize(cp, section);
172 UNSERIALIZE_SCALAR(pc);
173 UNSERIALIZE_SCALAR(npc);
174 }
175
176 void RegFile::changeContext(RegContextParam param, RegContextVal val)
177 {
178 switch(param)
179 {
180 case CONTEXT_CWP:
181 intRegFile.setCWP(val);
182 break;
183 case CONTEXT_GLOBALS:
184 intRegFile.setGlobals(val);
185 break;
186 default:
187 panic("Tried to set illegal context parameter in the SPARC regfile.\n");
188 }
189 }
190
191 int SparcISA::InterruptLevel(uint64_t softint)
192 {
193 if (softint & 0x10000 || softint & 0x1)
194 return 14;
195
196 int level = 14;
197 while (level >= 0 && !(1 << (level + 1) & softint))
198 level--;
199 if (1 << (level + 1) & softint)
200 return level;
201 return 0;
202 }
203
204 void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
205 {
206
207 uint8_t tl = src->readMiscReg(MISCREG_TL);
208
209 // Read all the trap level dependent registers and save them off
210 for(int i = 1; i <= MaxTL; i++)
211 {
212 src->setMiscReg(MISCREG_TL, i);
213 dest->setMiscReg(MISCREG_TL, i);
214
215 dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
216 dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
217 dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
218 dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
219 }
220
221 // Save off the traplevel
222 dest->setMiscReg(MISCREG_TL, tl);
223 src->setMiscReg(MISCREG_TL, tl);
224
225
226 // ASRs
227 dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
228 dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
229 dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
230 dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
231 dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
232 dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
233 dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
234 dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
235 dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
236
237 // Priv Registers
238 dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
239 dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
240 dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
241 dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
242 dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
243 dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
244 dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
245 dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
246 dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
247 dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
248 dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
249
250 // Hyperprivilged registers
251 dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
252 dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
253 dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
254 dest->setMiscReg(MISCREG_STRAND_STS_REG,
255 src->readMiscReg(MISCREG_STRAND_STS_REG));
256 dest->setMiscReg(MISCREG_HSTICK_CMPR,
257 src->readMiscReg(MISCREG_HSTICK_CMPR));
258
259 // FSR
260 dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
261 }
262
263 void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
264 {
265 // First loop through the integer registers.
266 for (int i = 0; i < TheISA::NumIntRegs; ++i) {
267 dest->setIntReg(i, src->readIntReg(i));
268 }
269
270 // Then loop through the floating point registers.
271 for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
272 dest->setFloatRegBits(i, src->readFloatRegBits(i));
273 }
274
275 // Copy misc. registers
276 copyMiscRegs(src, dest);
277
278 // Lastly copy PC/NPC
279 dest->setPC(src->readPC());
280 dest->setNextPC(src->readNextPC());
281 dest->setNextNPC(src->readNextNPC());
282 }