isa.cc (12620:fe5cdc0293dd) isa.cc (13583:f7482392b097)
1/*
2 * Copyright (c) 2009 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 */
30
31#include "arch/sparc/isa.hh"
32
33#include "arch/sparc/asi.hh"
34#include "arch/sparc/decoder.hh"
35#include "base/bitfield.hh"
36#include "base/trace.hh"
37#include "cpu/base.hh"
38#include "cpu/thread_context.hh"
39#include "debug/MiscRegs.hh"
40#include "debug/Timer.hh"
41#include "params/SparcISA.hh"
42
43namespace SparcISA
44{
45
46static PSTATE
47buildPstateMask()
48{
49 PSTATE mask = 0;
50 mask.ie = 1;
51 mask.priv = 1;
52 mask.am = 1;
53 mask.pef = 1;
54 mask.mm = 3;
55 mask.tle = 1;
56 mask.cle = 1;
57 mask.pid1 = 1;
58 return mask;
59}
60
61static const PSTATE PstateMask = buildPstateMask();
62
63ISA::ISA(Params *p)
64 : SimObject(p)
65{
66 tickCompare = NULL;
67 sTickCompare = NULL;
68 hSTickCompare = NULL;
69
70 clear();
71}
72
73const SparcISAParams *
74ISA::params() const
75{
76 return dynamic_cast<const Params *>(_params);
77}
78
79void
80ISA::reloadRegMap()
81{
82 installGlobals(gl, CurrentGlobalsOffset);
83 installWindow(cwp, CurrentWindowOffset);
84 // Microcode registers.
85 for (int i = 0; i < NumMicroIntRegs; i++)
86 intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
87 installGlobals(gl, NextGlobalsOffset);
88 installWindow(cwp - 1, NextWindowOffset);
89 installGlobals(gl, PreviousGlobalsOffset);
90 installWindow(cwp + 1, PreviousWindowOffset);
91}
92
93void
94ISA::installWindow(int cwp, int offset)
95{
96 assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
97 RegIndex *mapChunk = intRegMap + offset;
98 for (int i = 0; i < NumWindowedRegs; i++)
99 mapChunk[i] = TotalGlobals +
100 ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
101}
102
103void
104ISA::installGlobals(int gl, int offset)
105{
106 assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
107 RegIndex *mapChunk = intRegMap + offset;
108 mapChunk[0] = 0;
109 for (int i = 1; i < NumGlobalRegs; i++)
110 mapChunk[i] = i + gl * NumGlobalRegs;
111}
112
113void
114ISA::clear()
115{
116 cwp = 0;
117 gl = 0;
118 reloadRegMap();
119
120 // y = 0;
121 // ccr = 0;
122 asi = 0;
123 tick = ULL(1) << 63;
124 fprs = 0;
125 gsr = 0;
126 softint = 0;
127 tick_cmpr = 0;
128 stick = 0;
129 stick_cmpr = 0;
130 memset(tpc, 0, sizeof(tpc));
131 memset(tnpc, 0, sizeof(tnpc));
132 memset(tstate, 0, sizeof(tstate));
133 memset(tt, 0, sizeof(tt));
134 tba = 0;
135 pstate = 0;
136 tl = 0;
137 pil = 0;
138 // cansave = 0;
139 // canrestore = 0;
140 // cleanwin = 0;
141 // otherwin = 0;
142 // wstate = 0;
143 // In a T1, bit 11 is apparently always 1
144 hpstate = 0;
145 hpstate.id = 1;
146 memset(htstate, 0, sizeof(htstate));
147 hintp = 0;
148 htba = 0;
149 hstick_cmpr = 0;
150 // This is set this way in Legion for some reason
151 strandStatusReg = 0x50000;
152 fsr = 0;
153
154 priContext = 0;
155 secContext = 0;
156 partId = 0;
157 lsuCtrlReg = 0;
158
159 memset(scratchPad, 0, sizeof(scratchPad));
160
161 cpu_mondo_head = 0;
162 cpu_mondo_tail = 0;
163 dev_mondo_head = 0;
164 dev_mondo_tail = 0;
165 res_error_head = 0;
166 res_error_tail = 0;
167 nres_error_head = 0;
168 nres_error_tail = 0;
169
170 // If one of these events is active, it's not obvious to me how to get
171 // rid of it cleanly. For now we'll just assert that they're not.
172 if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL)
173 panic("Tick comparison event active when clearing the ISA object.\n");
174}
175
1/*
2 * Copyright (c) 2009 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 */
30
31#include "arch/sparc/isa.hh"
32
33#include "arch/sparc/asi.hh"
34#include "arch/sparc/decoder.hh"
35#include "base/bitfield.hh"
36#include "base/trace.hh"
37#include "cpu/base.hh"
38#include "cpu/thread_context.hh"
39#include "debug/MiscRegs.hh"
40#include "debug/Timer.hh"
41#include "params/SparcISA.hh"
42
43namespace SparcISA
44{
45
46static PSTATE
47buildPstateMask()
48{
49 PSTATE mask = 0;
50 mask.ie = 1;
51 mask.priv = 1;
52 mask.am = 1;
53 mask.pef = 1;
54 mask.mm = 3;
55 mask.tle = 1;
56 mask.cle = 1;
57 mask.pid1 = 1;
58 return mask;
59}
60
61static const PSTATE PstateMask = buildPstateMask();
62
63ISA::ISA(Params *p)
64 : SimObject(p)
65{
66 tickCompare = NULL;
67 sTickCompare = NULL;
68 hSTickCompare = NULL;
69
70 clear();
71}
72
73const SparcISAParams *
74ISA::params() const
75{
76 return dynamic_cast<const Params *>(_params);
77}
78
79void
80ISA::reloadRegMap()
81{
82 installGlobals(gl, CurrentGlobalsOffset);
83 installWindow(cwp, CurrentWindowOffset);
84 // Microcode registers.
85 for (int i = 0; i < NumMicroIntRegs; i++)
86 intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
87 installGlobals(gl, NextGlobalsOffset);
88 installWindow(cwp - 1, NextWindowOffset);
89 installGlobals(gl, PreviousGlobalsOffset);
90 installWindow(cwp + 1, PreviousWindowOffset);
91}
92
93void
94ISA::installWindow(int cwp, int offset)
95{
96 assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
97 RegIndex *mapChunk = intRegMap + offset;
98 for (int i = 0; i < NumWindowedRegs; i++)
99 mapChunk[i] = TotalGlobals +
100 ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
101}
102
103void
104ISA::installGlobals(int gl, int offset)
105{
106 assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
107 RegIndex *mapChunk = intRegMap + offset;
108 mapChunk[0] = 0;
109 for (int i = 1; i < NumGlobalRegs; i++)
110 mapChunk[i] = i + gl * NumGlobalRegs;
111}
112
113void
114ISA::clear()
115{
116 cwp = 0;
117 gl = 0;
118 reloadRegMap();
119
120 // y = 0;
121 // ccr = 0;
122 asi = 0;
123 tick = ULL(1) << 63;
124 fprs = 0;
125 gsr = 0;
126 softint = 0;
127 tick_cmpr = 0;
128 stick = 0;
129 stick_cmpr = 0;
130 memset(tpc, 0, sizeof(tpc));
131 memset(tnpc, 0, sizeof(tnpc));
132 memset(tstate, 0, sizeof(tstate));
133 memset(tt, 0, sizeof(tt));
134 tba = 0;
135 pstate = 0;
136 tl = 0;
137 pil = 0;
138 // cansave = 0;
139 // canrestore = 0;
140 // cleanwin = 0;
141 // otherwin = 0;
142 // wstate = 0;
143 // In a T1, bit 11 is apparently always 1
144 hpstate = 0;
145 hpstate.id = 1;
146 memset(htstate, 0, sizeof(htstate));
147 hintp = 0;
148 htba = 0;
149 hstick_cmpr = 0;
150 // This is set this way in Legion for some reason
151 strandStatusReg = 0x50000;
152 fsr = 0;
153
154 priContext = 0;
155 secContext = 0;
156 partId = 0;
157 lsuCtrlReg = 0;
158
159 memset(scratchPad, 0, sizeof(scratchPad));
160
161 cpu_mondo_head = 0;
162 cpu_mondo_tail = 0;
163 dev_mondo_head = 0;
164 dev_mondo_tail = 0;
165 res_error_head = 0;
166 res_error_tail = 0;
167 nres_error_head = 0;
168 nres_error_tail = 0;
169
170 // If one of these events is active, it's not obvious to me how to get
171 // rid of it cleanly. For now we'll just assert that they're not.
172 if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL)
173 panic("Tick comparison event active when clearing the ISA object.\n");
174}
175
176MiscReg
176RegVal
177ISA::readMiscRegNoEffect(int miscReg) const
178{
179
180 // The three miscRegs are moved up from the switch statement
181 // due to more frequent calls.
182
183 if (miscReg == MISCREG_GL)
184 return gl;
185 if (miscReg == MISCREG_CWP)
186 return cwp;
187 if (miscReg == MISCREG_TLB_DATA) {
188 /* Package up all the data for the tlb:
189 * 6666555555555544444444443333333333222222222211111111110000000000
190 * 3210987654321098765432109876543210987654321098765432109876543210
191 * secContext | priContext | |tl|partid| |||||^hpriv
192 * ||||^red
193 * |||^priv
194 * ||^am
195 * |^lsuim
196 * ^lsudm
197 */
198 return (uint64_t)hpstate.hpriv |
199 (uint64_t)hpstate.red << 1 |
200 (uint64_t)pstate.priv << 2 |
201 (uint64_t)pstate.am << 3 |
202 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
203 bits((uint64_t)partId,7,0) << 8 |
204 bits((uint64_t)tl,2,0) << 16 |
205 (uint64_t)priContext << 32 |
206 (uint64_t)secContext << 48;
207 }
208
209 switch (miscReg) {
210 // case MISCREG_TLB_DATA:
211 // [original contents see above]
212 // case MISCREG_Y:
213 // return y;
214 // case MISCREG_CCR:
215 // return ccr;
216 case MISCREG_ASI:
217 return asi;
218 case MISCREG_FPRS:
219 return fprs;
220 case MISCREG_TICK:
221 return tick;
222 case MISCREG_PCR:
223 panic("PCR not implemented\n");
224 case MISCREG_PIC:
225 panic("PIC not implemented\n");
226 case MISCREG_GSR:
227 return gsr;
228 case MISCREG_SOFTINT:
229 return softint;
230 case MISCREG_TICK_CMPR:
231 return tick_cmpr;
232 case MISCREG_STICK:
233 return stick;
234 case MISCREG_STICK_CMPR:
235 return stick_cmpr;
236
237 /** Privilged Registers */
238 case MISCREG_TPC:
239 return tpc[tl-1];
240 case MISCREG_TNPC:
241 return tnpc[tl-1];
242 case MISCREG_TSTATE:
243 return tstate[tl-1];
244 case MISCREG_TT:
245 return tt[tl-1];
246 case MISCREG_PRIVTICK:
247 panic("Priviliged access to tick registers not implemented\n");
248 case MISCREG_TBA:
249 return tba;
250 case MISCREG_PSTATE:
177ISA::readMiscRegNoEffect(int miscReg) const
178{
179
180 // The three miscRegs are moved up from the switch statement
181 // due to more frequent calls.
182
183 if (miscReg == MISCREG_GL)
184 return gl;
185 if (miscReg == MISCREG_CWP)
186 return cwp;
187 if (miscReg == MISCREG_TLB_DATA) {
188 /* Package up all the data for the tlb:
189 * 6666555555555544444444443333333333222222222211111111110000000000
190 * 3210987654321098765432109876543210987654321098765432109876543210
191 * secContext | priContext | |tl|partid| |||||^hpriv
192 * ||||^red
193 * |||^priv
194 * ||^am
195 * |^lsuim
196 * ^lsudm
197 */
198 return (uint64_t)hpstate.hpriv |
199 (uint64_t)hpstate.red << 1 |
200 (uint64_t)pstate.priv << 2 |
201 (uint64_t)pstate.am << 3 |
202 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
203 bits((uint64_t)partId,7,0) << 8 |
204 bits((uint64_t)tl,2,0) << 16 |
205 (uint64_t)priContext << 32 |
206 (uint64_t)secContext << 48;
207 }
208
209 switch (miscReg) {
210 // case MISCREG_TLB_DATA:
211 // [original contents see above]
212 // case MISCREG_Y:
213 // return y;
214 // case MISCREG_CCR:
215 // return ccr;
216 case MISCREG_ASI:
217 return asi;
218 case MISCREG_FPRS:
219 return fprs;
220 case MISCREG_TICK:
221 return tick;
222 case MISCREG_PCR:
223 panic("PCR not implemented\n");
224 case MISCREG_PIC:
225 panic("PIC not implemented\n");
226 case MISCREG_GSR:
227 return gsr;
228 case MISCREG_SOFTINT:
229 return softint;
230 case MISCREG_TICK_CMPR:
231 return tick_cmpr;
232 case MISCREG_STICK:
233 return stick;
234 case MISCREG_STICK_CMPR:
235 return stick_cmpr;
236
237 /** Privilged Registers */
238 case MISCREG_TPC:
239 return tpc[tl-1];
240 case MISCREG_TNPC:
241 return tnpc[tl-1];
242 case MISCREG_TSTATE:
243 return tstate[tl-1];
244 case MISCREG_TT:
245 return tt[tl-1];
246 case MISCREG_PRIVTICK:
247 panic("Priviliged access to tick registers not implemented\n");
248 case MISCREG_TBA:
249 return tba;
250 case MISCREG_PSTATE:
251 return (MiscReg)pstate;
251 return (RegVal)pstate;
252 case MISCREG_TL:
253 return tl;
254 case MISCREG_PIL:
255 return pil;
256 // CWP, GL moved
257 // case MISCREG_CWP:
258 // return cwp;
259 // case MISCREG_CANSAVE:
260 // return cansave;
261 // case MISCREG_CANRESTORE:
262 // return canrestore;
263 // case MISCREG_CLEANWIN:
264 // return cleanwin;
265 // case MISCREG_OTHERWIN:
266 // return otherwin;
267 // case MISCREG_WSTATE:
268 // return wstate;
269 // case MISCREG_GL:
270 // return gl;
271
272 /** Hyper privileged registers */
273 case MISCREG_HPSTATE:
252 case MISCREG_TL:
253 return tl;
254 case MISCREG_PIL:
255 return pil;
256 // CWP, GL moved
257 // case MISCREG_CWP:
258 // return cwp;
259 // case MISCREG_CANSAVE:
260 // return cansave;
261 // case MISCREG_CANRESTORE:
262 // return canrestore;
263 // case MISCREG_CLEANWIN:
264 // return cleanwin;
265 // case MISCREG_OTHERWIN:
266 // return otherwin;
267 // case MISCREG_WSTATE:
268 // return wstate;
269 // case MISCREG_GL:
270 // return gl;
271
272 /** Hyper privileged registers */
273 case MISCREG_HPSTATE:
274 return (MiscReg)hpstate;
274 return (RegVal)hpstate;
275 case MISCREG_HTSTATE:
276 return htstate[tl-1];
277 case MISCREG_HINTP:
278 return hintp;
279 case MISCREG_HTBA:
280 return htba;
281 case MISCREG_STRAND_STS_REG:
282 return strandStatusReg;
283 case MISCREG_HSTICK_CMPR:
284 return hstick_cmpr;
285
286 /** Floating Point Status Register */
287 case MISCREG_FSR:
288 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
289 return fsr;
290
291 case MISCREG_MMU_P_CONTEXT:
292 return priContext;
293 case MISCREG_MMU_S_CONTEXT:
294 return secContext;
295 case MISCREG_MMU_PART_ID:
296 return partId;
297 case MISCREG_MMU_LSU_CTRL:
298 return lsuCtrlReg;
299
300 case MISCREG_SCRATCHPAD_R0:
301 return scratchPad[0];
302 case MISCREG_SCRATCHPAD_R1:
303 return scratchPad[1];
304 case MISCREG_SCRATCHPAD_R2:
305 return scratchPad[2];
306 case MISCREG_SCRATCHPAD_R3:
307 return scratchPad[3];
308 case MISCREG_SCRATCHPAD_R4:
309 return scratchPad[4];
310 case MISCREG_SCRATCHPAD_R5:
311 return scratchPad[5];
312 case MISCREG_SCRATCHPAD_R6:
313 return scratchPad[6];
314 case MISCREG_SCRATCHPAD_R7:
315 return scratchPad[7];
316 case MISCREG_QUEUE_CPU_MONDO_HEAD:
317 return cpu_mondo_head;
318 case MISCREG_QUEUE_CPU_MONDO_TAIL:
319 return cpu_mondo_tail;
320 case MISCREG_QUEUE_DEV_MONDO_HEAD:
321 return dev_mondo_head;
322 case MISCREG_QUEUE_DEV_MONDO_TAIL:
323 return dev_mondo_tail;
324 case MISCREG_QUEUE_RES_ERROR_HEAD:
325 return res_error_head;
326 case MISCREG_QUEUE_RES_ERROR_TAIL:
327 return res_error_tail;
328 case MISCREG_QUEUE_NRES_ERROR_HEAD:
329 return nres_error_head;
330 case MISCREG_QUEUE_NRES_ERROR_TAIL:
331 return nres_error_tail;
332 default:
333 panic("Miscellaneous register %d not implemented\n", miscReg);
334 }
335}
336
275 case MISCREG_HTSTATE:
276 return htstate[tl-1];
277 case MISCREG_HINTP:
278 return hintp;
279 case MISCREG_HTBA:
280 return htba;
281 case MISCREG_STRAND_STS_REG:
282 return strandStatusReg;
283 case MISCREG_HSTICK_CMPR:
284 return hstick_cmpr;
285
286 /** Floating Point Status Register */
287 case MISCREG_FSR:
288 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
289 return fsr;
290
291 case MISCREG_MMU_P_CONTEXT:
292 return priContext;
293 case MISCREG_MMU_S_CONTEXT:
294 return secContext;
295 case MISCREG_MMU_PART_ID:
296 return partId;
297 case MISCREG_MMU_LSU_CTRL:
298 return lsuCtrlReg;
299
300 case MISCREG_SCRATCHPAD_R0:
301 return scratchPad[0];
302 case MISCREG_SCRATCHPAD_R1:
303 return scratchPad[1];
304 case MISCREG_SCRATCHPAD_R2:
305 return scratchPad[2];
306 case MISCREG_SCRATCHPAD_R3:
307 return scratchPad[3];
308 case MISCREG_SCRATCHPAD_R4:
309 return scratchPad[4];
310 case MISCREG_SCRATCHPAD_R5:
311 return scratchPad[5];
312 case MISCREG_SCRATCHPAD_R6:
313 return scratchPad[6];
314 case MISCREG_SCRATCHPAD_R7:
315 return scratchPad[7];
316 case MISCREG_QUEUE_CPU_MONDO_HEAD:
317 return cpu_mondo_head;
318 case MISCREG_QUEUE_CPU_MONDO_TAIL:
319 return cpu_mondo_tail;
320 case MISCREG_QUEUE_DEV_MONDO_HEAD:
321 return dev_mondo_head;
322 case MISCREG_QUEUE_DEV_MONDO_TAIL:
323 return dev_mondo_tail;
324 case MISCREG_QUEUE_RES_ERROR_HEAD:
325 return res_error_head;
326 case MISCREG_QUEUE_RES_ERROR_TAIL:
327 return res_error_tail;
328 case MISCREG_QUEUE_NRES_ERROR_HEAD:
329 return nres_error_head;
330 case MISCREG_QUEUE_NRES_ERROR_TAIL:
331 return nres_error_tail;
332 default:
333 panic("Miscellaneous register %d not implemented\n", miscReg);
334 }
335}
336
337MiscReg
337RegVal
338ISA::readMiscReg(int miscReg, ThreadContext * tc)
339{
340 switch (miscReg) {
341 // tick and stick are aliased to each other in niagra
342 // well store the tick data in stick and the interrupt bit in tick
343 case MISCREG_STICK:
344 case MISCREG_TICK:
345 case MISCREG_PRIVTICK:
346 // I'm not sure why legion ignores the lowest two bits, but we'll go
347 // with it
348 // change from curCycle() to instCount() until we're done with legion
349 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
350 tc->getCpuPtr()->instCount(), stick);
351 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
352 mbits(tick,63,63);
353 case MISCREG_FPRS:
354 // in legion if fp is enabled du and dl are set
355 return fprs | 0x3;
356 case MISCREG_PCR:
357 case MISCREG_PIC:
358 panic("Performance Instrumentation not impl\n");
359 case MISCREG_SOFTINT_CLR:
360 case MISCREG_SOFTINT_SET:
361 panic("Can read from softint clr/set\n");
362 case MISCREG_SOFTINT:
363 case MISCREG_TICK_CMPR:
364 case MISCREG_STICK_CMPR:
365 case MISCREG_HINTP:
366 case MISCREG_HTSTATE:
367 case MISCREG_HTBA:
368 case MISCREG_HVER:
369 case MISCREG_STRAND_STS_REG:
370 case MISCREG_HSTICK_CMPR:
371 case MISCREG_QUEUE_CPU_MONDO_HEAD:
372 case MISCREG_QUEUE_CPU_MONDO_TAIL:
373 case MISCREG_QUEUE_DEV_MONDO_HEAD:
374 case MISCREG_QUEUE_DEV_MONDO_TAIL:
375 case MISCREG_QUEUE_RES_ERROR_HEAD:
376 case MISCREG_QUEUE_RES_ERROR_TAIL:
377 case MISCREG_QUEUE_NRES_ERROR_HEAD:
378 case MISCREG_QUEUE_NRES_ERROR_TAIL:
379 case MISCREG_HPSTATE:
380 return readFSReg(miscReg, tc);
381 }
382 return readMiscRegNoEffect(miscReg);
383}
384
385void
338ISA::readMiscReg(int miscReg, ThreadContext * tc)
339{
340 switch (miscReg) {
341 // tick and stick are aliased to each other in niagra
342 // well store the tick data in stick and the interrupt bit in tick
343 case MISCREG_STICK:
344 case MISCREG_TICK:
345 case MISCREG_PRIVTICK:
346 // I'm not sure why legion ignores the lowest two bits, but we'll go
347 // with it
348 // change from curCycle() to instCount() until we're done with legion
349 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
350 tc->getCpuPtr()->instCount(), stick);
351 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
352 mbits(tick,63,63);
353 case MISCREG_FPRS:
354 // in legion if fp is enabled du and dl are set
355 return fprs | 0x3;
356 case MISCREG_PCR:
357 case MISCREG_PIC:
358 panic("Performance Instrumentation not impl\n");
359 case MISCREG_SOFTINT_CLR:
360 case MISCREG_SOFTINT_SET:
361 panic("Can read from softint clr/set\n");
362 case MISCREG_SOFTINT:
363 case MISCREG_TICK_CMPR:
364 case MISCREG_STICK_CMPR:
365 case MISCREG_HINTP:
366 case MISCREG_HTSTATE:
367 case MISCREG_HTBA:
368 case MISCREG_HVER:
369 case MISCREG_STRAND_STS_REG:
370 case MISCREG_HSTICK_CMPR:
371 case MISCREG_QUEUE_CPU_MONDO_HEAD:
372 case MISCREG_QUEUE_CPU_MONDO_TAIL:
373 case MISCREG_QUEUE_DEV_MONDO_HEAD:
374 case MISCREG_QUEUE_DEV_MONDO_TAIL:
375 case MISCREG_QUEUE_RES_ERROR_HEAD:
376 case MISCREG_QUEUE_RES_ERROR_TAIL:
377 case MISCREG_QUEUE_NRES_ERROR_HEAD:
378 case MISCREG_QUEUE_NRES_ERROR_TAIL:
379 case MISCREG_HPSTATE:
380 return readFSReg(miscReg, tc);
381 }
382 return readMiscRegNoEffect(miscReg);
383}
384
385void
386ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
386ISA::setMiscRegNoEffect(int miscReg, RegVal val)
387{
388 switch (miscReg) {
389// case MISCREG_Y:
390// y = val;
391// break;
392// case MISCREG_CCR:
393// ccr = val;
394// break;
395 case MISCREG_ASI:
396 asi = val;
397 break;
398 case MISCREG_FPRS:
399 fprs = val;
400 break;
401 case MISCREG_TICK:
402 tick = val;
403 break;
404 case MISCREG_PCR:
405 panic("PCR not implemented\n");
406 case MISCREG_PIC:
407 panic("PIC not implemented\n");
408 case MISCREG_GSR:
409 gsr = val;
410 break;
411 case MISCREG_SOFTINT:
412 softint = val;
413 break;
414 case MISCREG_TICK_CMPR:
415 tick_cmpr = val;
416 break;
417 case MISCREG_STICK:
418 stick = val;
419 break;
420 case MISCREG_STICK_CMPR:
421 stick_cmpr = val;
422 break;
423
424 /** Privilged Registers */
425 case MISCREG_TPC:
426 tpc[tl-1] = val;
427 break;
428 case MISCREG_TNPC:
429 tnpc[tl-1] = val;
430 break;
431 case MISCREG_TSTATE:
432 tstate[tl-1] = val;
433 break;
434 case MISCREG_TT:
435 tt[tl-1] = val;
436 break;
437 case MISCREG_PRIVTICK:
438 panic("Priviliged access to tick regesiters not implemented\n");
439 case MISCREG_TBA:
440 // clear lower 7 bits on writes.
441 tba = val & ULL(~0x7FFF);
442 break;
443 case MISCREG_PSTATE:
444 pstate = (val & PstateMask);
445 break;
446 case MISCREG_TL:
447 tl = val;
448 break;
449 case MISCREG_PIL:
450 pil = val;
451 break;
452 case MISCREG_CWP:
453 cwp = val;
454 break;
455// case MISCREG_CANSAVE:
456// cansave = val;
457// break;
458// case MISCREG_CANRESTORE:
459// canrestore = val;
460// break;
461// case MISCREG_CLEANWIN:
462// cleanwin = val;
463// break;
464// case MISCREG_OTHERWIN:
465// otherwin = val;
466// break;
467// case MISCREG_WSTATE:
468// wstate = val;
469// break;
470 case MISCREG_GL:
471 gl = val;
472 break;
473
474 /** Hyper privileged registers */
475 case MISCREG_HPSTATE:
476 hpstate = val;
477 break;
478 case MISCREG_HTSTATE:
479 htstate[tl-1] = val;
480 break;
481 case MISCREG_HINTP:
482 hintp = val;
483 break;
484 case MISCREG_HTBA:
485 htba = val;
486 break;
487 case MISCREG_STRAND_STS_REG:
488 strandStatusReg = val;
489 break;
490 case MISCREG_HSTICK_CMPR:
491 hstick_cmpr = val;
492 break;
493
494 /** Floating Point Status Register */
495 case MISCREG_FSR:
496 fsr = val;
497 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
498 break;
499
500 case MISCREG_MMU_P_CONTEXT:
501 priContext = val;
502 break;
503 case MISCREG_MMU_S_CONTEXT:
504 secContext = val;
505 break;
506 case MISCREG_MMU_PART_ID:
507 partId = val;
508 break;
509 case MISCREG_MMU_LSU_CTRL:
510 lsuCtrlReg = val;
511 break;
512
513 case MISCREG_SCRATCHPAD_R0:
514 scratchPad[0] = val;
515 break;
516 case MISCREG_SCRATCHPAD_R1:
517 scratchPad[1] = val;
518 break;
519 case MISCREG_SCRATCHPAD_R2:
520 scratchPad[2] = val;
521 break;
522 case MISCREG_SCRATCHPAD_R3:
523 scratchPad[3] = val;
524 break;
525 case MISCREG_SCRATCHPAD_R4:
526 scratchPad[4] = val;
527 break;
528 case MISCREG_SCRATCHPAD_R5:
529 scratchPad[5] = val;
530 break;
531 case MISCREG_SCRATCHPAD_R6:
532 scratchPad[6] = val;
533 break;
534 case MISCREG_SCRATCHPAD_R7:
535 scratchPad[7] = val;
536 break;
537 case MISCREG_QUEUE_CPU_MONDO_HEAD:
538 cpu_mondo_head = val;
539 break;
540 case MISCREG_QUEUE_CPU_MONDO_TAIL:
541 cpu_mondo_tail = val;
542 break;
543 case MISCREG_QUEUE_DEV_MONDO_HEAD:
544 dev_mondo_head = val;
545 break;
546 case MISCREG_QUEUE_DEV_MONDO_TAIL:
547 dev_mondo_tail = val;
548 break;
549 case MISCREG_QUEUE_RES_ERROR_HEAD:
550 res_error_head = val;
551 break;
552 case MISCREG_QUEUE_RES_ERROR_TAIL:
553 res_error_tail = val;
554 break;
555 case MISCREG_QUEUE_NRES_ERROR_HEAD:
556 nres_error_head = val;
557 break;
558 case MISCREG_QUEUE_NRES_ERROR_TAIL:
559 nres_error_tail = val;
560 break;
561 default:
562 panic("Miscellaneous register %d not implemented\n", miscReg);
563 }
564}
565
566void
387{
388 switch (miscReg) {
389// case MISCREG_Y:
390// y = val;
391// break;
392// case MISCREG_CCR:
393// ccr = val;
394// break;
395 case MISCREG_ASI:
396 asi = val;
397 break;
398 case MISCREG_FPRS:
399 fprs = val;
400 break;
401 case MISCREG_TICK:
402 tick = val;
403 break;
404 case MISCREG_PCR:
405 panic("PCR not implemented\n");
406 case MISCREG_PIC:
407 panic("PIC not implemented\n");
408 case MISCREG_GSR:
409 gsr = val;
410 break;
411 case MISCREG_SOFTINT:
412 softint = val;
413 break;
414 case MISCREG_TICK_CMPR:
415 tick_cmpr = val;
416 break;
417 case MISCREG_STICK:
418 stick = val;
419 break;
420 case MISCREG_STICK_CMPR:
421 stick_cmpr = val;
422 break;
423
424 /** Privilged Registers */
425 case MISCREG_TPC:
426 tpc[tl-1] = val;
427 break;
428 case MISCREG_TNPC:
429 tnpc[tl-1] = val;
430 break;
431 case MISCREG_TSTATE:
432 tstate[tl-1] = val;
433 break;
434 case MISCREG_TT:
435 tt[tl-1] = val;
436 break;
437 case MISCREG_PRIVTICK:
438 panic("Priviliged access to tick regesiters not implemented\n");
439 case MISCREG_TBA:
440 // clear lower 7 bits on writes.
441 tba = val & ULL(~0x7FFF);
442 break;
443 case MISCREG_PSTATE:
444 pstate = (val & PstateMask);
445 break;
446 case MISCREG_TL:
447 tl = val;
448 break;
449 case MISCREG_PIL:
450 pil = val;
451 break;
452 case MISCREG_CWP:
453 cwp = val;
454 break;
455// case MISCREG_CANSAVE:
456// cansave = val;
457// break;
458// case MISCREG_CANRESTORE:
459// canrestore = val;
460// break;
461// case MISCREG_CLEANWIN:
462// cleanwin = val;
463// break;
464// case MISCREG_OTHERWIN:
465// otherwin = val;
466// break;
467// case MISCREG_WSTATE:
468// wstate = val;
469// break;
470 case MISCREG_GL:
471 gl = val;
472 break;
473
474 /** Hyper privileged registers */
475 case MISCREG_HPSTATE:
476 hpstate = val;
477 break;
478 case MISCREG_HTSTATE:
479 htstate[tl-1] = val;
480 break;
481 case MISCREG_HINTP:
482 hintp = val;
483 break;
484 case MISCREG_HTBA:
485 htba = val;
486 break;
487 case MISCREG_STRAND_STS_REG:
488 strandStatusReg = val;
489 break;
490 case MISCREG_HSTICK_CMPR:
491 hstick_cmpr = val;
492 break;
493
494 /** Floating Point Status Register */
495 case MISCREG_FSR:
496 fsr = val;
497 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
498 break;
499
500 case MISCREG_MMU_P_CONTEXT:
501 priContext = val;
502 break;
503 case MISCREG_MMU_S_CONTEXT:
504 secContext = val;
505 break;
506 case MISCREG_MMU_PART_ID:
507 partId = val;
508 break;
509 case MISCREG_MMU_LSU_CTRL:
510 lsuCtrlReg = val;
511 break;
512
513 case MISCREG_SCRATCHPAD_R0:
514 scratchPad[0] = val;
515 break;
516 case MISCREG_SCRATCHPAD_R1:
517 scratchPad[1] = val;
518 break;
519 case MISCREG_SCRATCHPAD_R2:
520 scratchPad[2] = val;
521 break;
522 case MISCREG_SCRATCHPAD_R3:
523 scratchPad[3] = val;
524 break;
525 case MISCREG_SCRATCHPAD_R4:
526 scratchPad[4] = val;
527 break;
528 case MISCREG_SCRATCHPAD_R5:
529 scratchPad[5] = val;
530 break;
531 case MISCREG_SCRATCHPAD_R6:
532 scratchPad[6] = val;
533 break;
534 case MISCREG_SCRATCHPAD_R7:
535 scratchPad[7] = val;
536 break;
537 case MISCREG_QUEUE_CPU_MONDO_HEAD:
538 cpu_mondo_head = val;
539 break;
540 case MISCREG_QUEUE_CPU_MONDO_TAIL:
541 cpu_mondo_tail = val;
542 break;
543 case MISCREG_QUEUE_DEV_MONDO_HEAD:
544 dev_mondo_head = val;
545 break;
546 case MISCREG_QUEUE_DEV_MONDO_TAIL:
547 dev_mondo_tail = val;
548 break;
549 case MISCREG_QUEUE_RES_ERROR_HEAD:
550 res_error_head = val;
551 break;
552 case MISCREG_QUEUE_RES_ERROR_TAIL:
553 res_error_tail = val;
554 break;
555 case MISCREG_QUEUE_NRES_ERROR_HEAD:
556 nres_error_head = val;
557 break;
558 case MISCREG_QUEUE_NRES_ERROR_TAIL:
559 nres_error_tail = val;
560 break;
561 default:
562 panic("Miscellaneous register %d not implemented\n", miscReg);
563 }
564}
565
566void
567ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
567ISA::setMiscReg(int miscReg, RegVal val, ThreadContext * tc)
568{
568{
569 MiscReg new_val = val;
569 RegVal new_val = val;
570
571 switch (miscReg) {
572 case MISCREG_ASI:
573 tc->getDecoderPtr()->setContext(val);
574 break;
575 case MISCREG_STICK:
576 case MISCREG_TICK:
577 // stick and tick are same thing on niagra
578 // use stick for offset and tick for holding intrrupt bit
579 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
580 tick = mbits(val,63,63);
581 DPRINTF(Timer, "Writing TICK=%#X\n", val);
582 break;
583 case MISCREG_FPRS:
584 // Configure the fpu based on the fprs
585 break;
586 case MISCREG_PCR:
587 // Set up performance counting based on pcr value
588 break;
589 case MISCREG_PSTATE:
590 pstate = val & PstateMask;
591 return;
592 case MISCREG_TL:
593 {
594 tl = val;
595 if (hpstate.tlz && tl == 0 && !hpstate.hpriv)
596 tc->getCpuPtr()->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
597 else
598 tc->getCpuPtr()->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
599 return;
600 }
601 case MISCREG_CWP:
602 new_val = val >= NWindows ? NWindows - 1 : val;
603 if (val >= NWindows)
604 new_val = NWindows - 1;
605
606 installWindow(new_val, CurrentWindowOffset);
607 installWindow(new_val - 1, NextWindowOffset);
608 installWindow(new_val + 1, PreviousWindowOffset);
609 break;
610 case MISCREG_GL:
611 installGlobals(val, CurrentGlobalsOffset);
612 installGlobals(val, NextGlobalsOffset);
613 installGlobals(val, PreviousGlobalsOffset);
614 break;
615 case MISCREG_PIL:
616 case MISCREG_SOFTINT:
617 case MISCREG_SOFTINT_SET:
618 case MISCREG_SOFTINT_CLR:
619 case MISCREG_TICK_CMPR:
620 case MISCREG_STICK_CMPR:
621 case MISCREG_HINTP:
622 case MISCREG_HTSTATE:
623 case MISCREG_HTBA:
624 case MISCREG_HVER:
625 case MISCREG_STRAND_STS_REG:
626 case MISCREG_HSTICK_CMPR:
627 case MISCREG_QUEUE_CPU_MONDO_HEAD:
628 case MISCREG_QUEUE_CPU_MONDO_TAIL:
629 case MISCREG_QUEUE_DEV_MONDO_HEAD:
630 case MISCREG_QUEUE_DEV_MONDO_TAIL:
631 case MISCREG_QUEUE_RES_ERROR_HEAD:
632 case MISCREG_QUEUE_RES_ERROR_TAIL:
633 case MISCREG_QUEUE_NRES_ERROR_HEAD:
634 case MISCREG_QUEUE_NRES_ERROR_TAIL:
635 case MISCREG_HPSTATE:
636 setFSReg(miscReg, val, tc);
637 return;
638 }
639 setMiscRegNoEffect(miscReg, new_val);
640}
641
642void
643ISA::serialize(CheckpointOut &cp) const
644{
645 SERIALIZE_SCALAR(asi);
646 SERIALIZE_SCALAR(tick);
647 SERIALIZE_SCALAR(fprs);
648 SERIALIZE_SCALAR(gsr);
649 SERIALIZE_SCALAR(softint);
650 SERIALIZE_SCALAR(tick_cmpr);
651 SERIALIZE_SCALAR(stick);
652 SERIALIZE_SCALAR(stick_cmpr);
653 SERIALIZE_ARRAY(tpc,MaxTL);
654 SERIALIZE_ARRAY(tnpc,MaxTL);
655 SERIALIZE_ARRAY(tstate,MaxTL);
656 SERIALIZE_ARRAY(tt,MaxTL);
657 SERIALIZE_SCALAR(tba);
658 SERIALIZE_SCALAR(pstate);
659 SERIALIZE_SCALAR(tl);
660 SERIALIZE_SCALAR(pil);
661 SERIALIZE_SCALAR(cwp);
662 SERIALIZE_SCALAR(gl);
663 SERIALIZE_SCALAR(hpstate);
664 SERIALIZE_ARRAY(htstate,MaxTL);
665 SERIALIZE_SCALAR(hintp);
666 SERIALIZE_SCALAR(htba);
667 SERIALIZE_SCALAR(hstick_cmpr);
668 SERIALIZE_SCALAR(strandStatusReg);
669 SERIALIZE_SCALAR(fsr);
670 SERIALIZE_SCALAR(priContext);
671 SERIALIZE_SCALAR(secContext);
672 SERIALIZE_SCALAR(partId);
673 SERIALIZE_SCALAR(lsuCtrlReg);
674 SERIALIZE_ARRAY(scratchPad,8);
675 SERIALIZE_SCALAR(cpu_mondo_head);
676 SERIALIZE_SCALAR(cpu_mondo_tail);
677 SERIALIZE_SCALAR(dev_mondo_head);
678 SERIALIZE_SCALAR(dev_mondo_tail);
679 SERIALIZE_SCALAR(res_error_head);
680 SERIALIZE_SCALAR(res_error_tail);
681 SERIALIZE_SCALAR(nres_error_head);
682 SERIALIZE_SCALAR(nres_error_tail);
683 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
684 ThreadContext *tc = NULL;
685 BaseCPU *cpu = NULL;
686 int tc_num = 0;
687 bool tick_intr_sched = true;
688
689 if (tickCompare)
690 tc = tickCompare->getTC();
691 else if (sTickCompare)
692 tc = sTickCompare->getTC();
693 else if (hSTickCompare)
694 tc = hSTickCompare->getTC();
695 else
696 tick_intr_sched = false;
697
698 SERIALIZE_SCALAR(tick_intr_sched);
699
700 if (tc) {
701 cpu = tc->getCpuPtr();
702 tc_num = cpu->findContext(tc);
703 if (tickCompare && tickCompare->scheduled())
704 tick_cmp = tickCompare->when();
705 if (sTickCompare && sTickCompare->scheduled())
706 stick_cmp = sTickCompare->when();
707 if (hSTickCompare && hSTickCompare->scheduled())
708 hstick_cmp = hSTickCompare->when();
709
710 SERIALIZE_OBJPTR(cpu);
711 SERIALIZE_SCALAR(tc_num);
712 SERIALIZE_SCALAR(tick_cmp);
713 SERIALIZE_SCALAR(stick_cmp);
714 SERIALIZE_SCALAR(hstick_cmp);
715 }
716}
717
718void
719ISA::unserialize(CheckpointIn &cp)
720{
721 UNSERIALIZE_SCALAR(asi);
722 UNSERIALIZE_SCALAR(tick);
723 UNSERIALIZE_SCALAR(fprs);
724 UNSERIALIZE_SCALAR(gsr);
725 UNSERIALIZE_SCALAR(softint);
726 UNSERIALIZE_SCALAR(tick_cmpr);
727 UNSERIALIZE_SCALAR(stick);
728 UNSERIALIZE_SCALAR(stick_cmpr);
729 UNSERIALIZE_ARRAY(tpc,MaxTL);
730 UNSERIALIZE_ARRAY(tnpc,MaxTL);
731 UNSERIALIZE_ARRAY(tstate,MaxTL);
732 UNSERIALIZE_ARRAY(tt,MaxTL);
733 UNSERIALIZE_SCALAR(tba);
734 {
735 uint16_t pstate;
736 UNSERIALIZE_SCALAR(pstate);
737 this->pstate = pstate;
738 }
739 UNSERIALIZE_SCALAR(tl);
740 UNSERIALIZE_SCALAR(pil);
741 UNSERIALIZE_SCALAR(cwp);
742 UNSERIALIZE_SCALAR(gl);
743 reloadRegMap();
744 {
745 uint64_t hpstate;
746 UNSERIALIZE_SCALAR(hpstate);
747 this->hpstate = hpstate;
748 }
749 UNSERIALIZE_ARRAY(htstate,MaxTL);
750 UNSERIALIZE_SCALAR(hintp);
751 UNSERIALIZE_SCALAR(htba);
752 UNSERIALIZE_SCALAR(hstick_cmpr);
753 UNSERIALIZE_SCALAR(strandStatusReg);
754 UNSERIALIZE_SCALAR(fsr);
755 UNSERIALIZE_SCALAR(priContext);
756 UNSERIALIZE_SCALAR(secContext);
757 UNSERIALIZE_SCALAR(partId);
758 UNSERIALIZE_SCALAR(lsuCtrlReg);
759 UNSERIALIZE_ARRAY(scratchPad,8);
760 UNSERIALIZE_SCALAR(cpu_mondo_head);
761 UNSERIALIZE_SCALAR(cpu_mondo_tail);
762 UNSERIALIZE_SCALAR(dev_mondo_head);
763 UNSERIALIZE_SCALAR(dev_mondo_tail);
764 UNSERIALIZE_SCALAR(res_error_head);
765 UNSERIALIZE_SCALAR(res_error_tail);
766 UNSERIALIZE_SCALAR(nres_error_head);
767 UNSERIALIZE_SCALAR(nres_error_tail);
768
769 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
770 ThreadContext *tc = NULL;
771 BaseCPU *cpu = NULL;
772 int tc_num;
773 bool tick_intr_sched;
774 UNSERIALIZE_SCALAR(tick_intr_sched);
775 if (tick_intr_sched) {
776 UNSERIALIZE_OBJPTR(cpu);
777 if (cpu) {
778 UNSERIALIZE_SCALAR(tc_num);
779 UNSERIALIZE_SCALAR(tick_cmp);
780 UNSERIALIZE_SCALAR(stick_cmp);
781 UNSERIALIZE_SCALAR(hstick_cmp);
782 tc = cpu->getContext(tc_num);
783
784 if (tick_cmp) {
785 tickCompare = new TickCompareEvent(this, tc);
786 schedule(tickCompare, tick_cmp);
787 }
788 if (stick_cmp) {
789 sTickCompare = new STickCompareEvent(this, tc);
790 schedule(sTickCompare, stick_cmp);
791 }
792 if (hstick_cmp) {
793 hSTickCompare = new HSTickCompareEvent(this, tc);
794 schedule(hSTickCompare, hstick_cmp);
795 }
796 }
797 }
798
799}
800
801}
802
803SparcISA::ISA *
804SparcISAParams::create()
805{
806 return new SparcISA::ISA(this);
807}
570
571 switch (miscReg) {
572 case MISCREG_ASI:
573 tc->getDecoderPtr()->setContext(val);
574 break;
575 case MISCREG_STICK:
576 case MISCREG_TICK:
577 // stick and tick are same thing on niagra
578 // use stick for offset and tick for holding intrrupt bit
579 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
580 tick = mbits(val,63,63);
581 DPRINTF(Timer, "Writing TICK=%#X\n", val);
582 break;
583 case MISCREG_FPRS:
584 // Configure the fpu based on the fprs
585 break;
586 case MISCREG_PCR:
587 // Set up performance counting based on pcr value
588 break;
589 case MISCREG_PSTATE:
590 pstate = val & PstateMask;
591 return;
592 case MISCREG_TL:
593 {
594 tl = val;
595 if (hpstate.tlz && tl == 0 && !hpstate.hpriv)
596 tc->getCpuPtr()->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
597 else
598 tc->getCpuPtr()->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
599 return;
600 }
601 case MISCREG_CWP:
602 new_val = val >= NWindows ? NWindows - 1 : val;
603 if (val >= NWindows)
604 new_val = NWindows - 1;
605
606 installWindow(new_val, CurrentWindowOffset);
607 installWindow(new_val - 1, NextWindowOffset);
608 installWindow(new_val + 1, PreviousWindowOffset);
609 break;
610 case MISCREG_GL:
611 installGlobals(val, CurrentGlobalsOffset);
612 installGlobals(val, NextGlobalsOffset);
613 installGlobals(val, PreviousGlobalsOffset);
614 break;
615 case MISCREG_PIL:
616 case MISCREG_SOFTINT:
617 case MISCREG_SOFTINT_SET:
618 case MISCREG_SOFTINT_CLR:
619 case MISCREG_TICK_CMPR:
620 case MISCREG_STICK_CMPR:
621 case MISCREG_HINTP:
622 case MISCREG_HTSTATE:
623 case MISCREG_HTBA:
624 case MISCREG_HVER:
625 case MISCREG_STRAND_STS_REG:
626 case MISCREG_HSTICK_CMPR:
627 case MISCREG_QUEUE_CPU_MONDO_HEAD:
628 case MISCREG_QUEUE_CPU_MONDO_TAIL:
629 case MISCREG_QUEUE_DEV_MONDO_HEAD:
630 case MISCREG_QUEUE_DEV_MONDO_TAIL:
631 case MISCREG_QUEUE_RES_ERROR_HEAD:
632 case MISCREG_QUEUE_RES_ERROR_TAIL:
633 case MISCREG_QUEUE_NRES_ERROR_HEAD:
634 case MISCREG_QUEUE_NRES_ERROR_TAIL:
635 case MISCREG_HPSTATE:
636 setFSReg(miscReg, val, tc);
637 return;
638 }
639 setMiscRegNoEffect(miscReg, new_val);
640}
641
642void
643ISA::serialize(CheckpointOut &cp) const
644{
645 SERIALIZE_SCALAR(asi);
646 SERIALIZE_SCALAR(tick);
647 SERIALIZE_SCALAR(fprs);
648 SERIALIZE_SCALAR(gsr);
649 SERIALIZE_SCALAR(softint);
650 SERIALIZE_SCALAR(tick_cmpr);
651 SERIALIZE_SCALAR(stick);
652 SERIALIZE_SCALAR(stick_cmpr);
653 SERIALIZE_ARRAY(tpc,MaxTL);
654 SERIALIZE_ARRAY(tnpc,MaxTL);
655 SERIALIZE_ARRAY(tstate,MaxTL);
656 SERIALIZE_ARRAY(tt,MaxTL);
657 SERIALIZE_SCALAR(tba);
658 SERIALIZE_SCALAR(pstate);
659 SERIALIZE_SCALAR(tl);
660 SERIALIZE_SCALAR(pil);
661 SERIALIZE_SCALAR(cwp);
662 SERIALIZE_SCALAR(gl);
663 SERIALIZE_SCALAR(hpstate);
664 SERIALIZE_ARRAY(htstate,MaxTL);
665 SERIALIZE_SCALAR(hintp);
666 SERIALIZE_SCALAR(htba);
667 SERIALIZE_SCALAR(hstick_cmpr);
668 SERIALIZE_SCALAR(strandStatusReg);
669 SERIALIZE_SCALAR(fsr);
670 SERIALIZE_SCALAR(priContext);
671 SERIALIZE_SCALAR(secContext);
672 SERIALIZE_SCALAR(partId);
673 SERIALIZE_SCALAR(lsuCtrlReg);
674 SERIALIZE_ARRAY(scratchPad,8);
675 SERIALIZE_SCALAR(cpu_mondo_head);
676 SERIALIZE_SCALAR(cpu_mondo_tail);
677 SERIALIZE_SCALAR(dev_mondo_head);
678 SERIALIZE_SCALAR(dev_mondo_tail);
679 SERIALIZE_SCALAR(res_error_head);
680 SERIALIZE_SCALAR(res_error_tail);
681 SERIALIZE_SCALAR(nres_error_head);
682 SERIALIZE_SCALAR(nres_error_tail);
683 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
684 ThreadContext *tc = NULL;
685 BaseCPU *cpu = NULL;
686 int tc_num = 0;
687 bool tick_intr_sched = true;
688
689 if (tickCompare)
690 tc = tickCompare->getTC();
691 else if (sTickCompare)
692 tc = sTickCompare->getTC();
693 else if (hSTickCompare)
694 tc = hSTickCompare->getTC();
695 else
696 tick_intr_sched = false;
697
698 SERIALIZE_SCALAR(tick_intr_sched);
699
700 if (tc) {
701 cpu = tc->getCpuPtr();
702 tc_num = cpu->findContext(tc);
703 if (tickCompare && tickCompare->scheduled())
704 tick_cmp = tickCompare->when();
705 if (sTickCompare && sTickCompare->scheduled())
706 stick_cmp = sTickCompare->when();
707 if (hSTickCompare && hSTickCompare->scheduled())
708 hstick_cmp = hSTickCompare->when();
709
710 SERIALIZE_OBJPTR(cpu);
711 SERIALIZE_SCALAR(tc_num);
712 SERIALIZE_SCALAR(tick_cmp);
713 SERIALIZE_SCALAR(stick_cmp);
714 SERIALIZE_SCALAR(hstick_cmp);
715 }
716}
717
718void
719ISA::unserialize(CheckpointIn &cp)
720{
721 UNSERIALIZE_SCALAR(asi);
722 UNSERIALIZE_SCALAR(tick);
723 UNSERIALIZE_SCALAR(fprs);
724 UNSERIALIZE_SCALAR(gsr);
725 UNSERIALIZE_SCALAR(softint);
726 UNSERIALIZE_SCALAR(tick_cmpr);
727 UNSERIALIZE_SCALAR(stick);
728 UNSERIALIZE_SCALAR(stick_cmpr);
729 UNSERIALIZE_ARRAY(tpc,MaxTL);
730 UNSERIALIZE_ARRAY(tnpc,MaxTL);
731 UNSERIALIZE_ARRAY(tstate,MaxTL);
732 UNSERIALIZE_ARRAY(tt,MaxTL);
733 UNSERIALIZE_SCALAR(tba);
734 {
735 uint16_t pstate;
736 UNSERIALIZE_SCALAR(pstate);
737 this->pstate = pstate;
738 }
739 UNSERIALIZE_SCALAR(tl);
740 UNSERIALIZE_SCALAR(pil);
741 UNSERIALIZE_SCALAR(cwp);
742 UNSERIALIZE_SCALAR(gl);
743 reloadRegMap();
744 {
745 uint64_t hpstate;
746 UNSERIALIZE_SCALAR(hpstate);
747 this->hpstate = hpstate;
748 }
749 UNSERIALIZE_ARRAY(htstate,MaxTL);
750 UNSERIALIZE_SCALAR(hintp);
751 UNSERIALIZE_SCALAR(htba);
752 UNSERIALIZE_SCALAR(hstick_cmpr);
753 UNSERIALIZE_SCALAR(strandStatusReg);
754 UNSERIALIZE_SCALAR(fsr);
755 UNSERIALIZE_SCALAR(priContext);
756 UNSERIALIZE_SCALAR(secContext);
757 UNSERIALIZE_SCALAR(partId);
758 UNSERIALIZE_SCALAR(lsuCtrlReg);
759 UNSERIALIZE_ARRAY(scratchPad,8);
760 UNSERIALIZE_SCALAR(cpu_mondo_head);
761 UNSERIALIZE_SCALAR(cpu_mondo_tail);
762 UNSERIALIZE_SCALAR(dev_mondo_head);
763 UNSERIALIZE_SCALAR(dev_mondo_tail);
764 UNSERIALIZE_SCALAR(res_error_head);
765 UNSERIALIZE_SCALAR(res_error_tail);
766 UNSERIALIZE_SCALAR(nres_error_head);
767 UNSERIALIZE_SCALAR(nres_error_tail);
768
769 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
770 ThreadContext *tc = NULL;
771 BaseCPU *cpu = NULL;
772 int tc_num;
773 bool tick_intr_sched;
774 UNSERIALIZE_SCALAR(tick_intr_sched);
775 if (tick_intr_sched) {
776 UNSERIALIZE_OBJPTR(cpu);
777 if (cpu) {
778 UNSERIALIZE_SCALAR(tc_num);
779 UNSERIALIZE_SCALAR(tick_cmp);
780 UNSERIALIZE_SCALAR(stick_cmp);
781 UNSERIALIZE_SCALAR(hstick_cmp);
782 tc = cpu->getContext(tc_num);
783
784 if (tick_cmp) {
785 tickCompare = new TickCompareEvent(this, tc);
786 schedule(tickCompare, tick_cmp);
787 }
788 if (stick_cmp) {
789 sTickCompare = new STickCompareEvent(this, tc);
790 schedule(sTickCompare, stick_cmp);
791 }
792 if (hstick_cmp) {
793 hSTickCompare = new HSTickCompareEvent(this, tc);
794 schedule(hSTickCompare, hstick_cmp);
795 }
796 }
797 }
798
799}
800
801}
802
803SparcISA::ISA *
804SparcISAParams::create()
805{
806 return new SparcISA::ISA(this);
807}