ev5.cc (8794:e2ac2b7164dd) ev5.cc (8795:0909f8ed7aa0)
1/*
2 * Copyright (c) 2002-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: Steve Reinhardt
29 * Nathan Binkert
30 */
31
32#include "arch/alpha/faults.hh"
33#include "arch/alpha/isa_traits.hh"
34#include "arch/alpha/kernel_stats.hh"
35#include "arch/alpha/osfpal.hh"
36#include "arch/alpha/tlb.hh"
37#include "base/cp_annotate.hh"
38#include "base/debug.hh"
39#include "cpu/base.hh"
40#include "cpu/simple_thread.hh"
41#include "cpu/thread_context.hh"
42#include "sim/sim_exit.hh"
43
44namespace AlphaISA {
45
46////////////////////////////////////////////////////////////////////////
47//
48// Machine dependent functions
49//
50void
51initCPU(ThreadContext *tc, int cpuId)
52{
53 initIPRs(tc, cpuId);
54
55 tc->setIntReg(16, cpuId);
56 tc->setIntReg(0, cpuId);
57
58 AlphaFault *reset = new ResetFault;
59
60 tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
61
62 delete reset;
63}
64
65template <class CPU>
66void
67zeroRegisters(CPU *cpu)
68{
69 // Insure ISA semantics
70 // (no longer very clean due to the change in setIntReg() in the
71 // cpu model. Consider changing later.)
72 cpu->thread->setIntReg(ZeroReg, 0);
73 cpu->thread->setFloatReg(ZeroReg, 0.0);
74}
75
76////////////////////////////////////////////////////////////////////////
77//
78//
79//
80void
81initIPRs(ThreadContext *tc, int cpuId)
82{
83 for (int i = 0; i < NumInternalProcRegs; ++i) {
84 tc->setMiscRegNoEffect(i, 0);
85 }
86
87 tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
88 tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
89 tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
90}
91
92MiscReg
93ISA::readIpr(int idx, ThreadContext *tc)
94{
95 uint64_t retval = 0; // return value, default 0
96
97 switch (idx) {
98 case IPR_PALtemp0:
99 case IPR_PALtemp1:
100 case IPR_PALtemp2:
101 case IPR_PALtemp3:
102 case IPR_PALtemp4:
103 case IPR_PALtemp5:
104 case IPR_PALtemp6:
105 case IPR_PALtemp7:
106 case IPR_PALtemp8:
107 case IPR_PALtemp9:
108 case IPR_PALtemp10:
109 case IPR_PALtemp11:
110 case IPR_PALtemp12:
111 case IPR_PALtemp13:
112 case IPR_PALtemp14:
113 case IPR_PALtemp15:
114 case IPR_PALtemp16:
115 case IPR_PALtemp17:
116 case IPR_PALtemp18:
117 case IPR_PALtemp19:
118 case IPR_PALtemp20:
119 case IPR_PALtemp21:
120 case IPR_PALtemp22:
121 case IPR_PALtemp23:
122 case IPR_PAL_BASE:
123
124 case IPR_IVPTBR:
125 case IPR_DC_MODE:
126 case IPR_MAF_MODE:
127 case IPR_ISR:
128 case IPR_EXC_ADDR:
129 case IPR_IC_PERR_STAT:
130 case IPR_DC_PERR_STAT:
131 case IPR_MCSR:
132 case IPR_ASTRR:
133 case IPR_ASTER:
134 case IPR_SIRR:
135 case IPR_ICSR:
136 case IPR_ICM:
137 case IPR_DTB_CM:
138 case IPR_IPLR:
139 case IPR_INTID:
140 case IPR_PMCTR:
141 // no side-effect
142 retval = ipr[idx];
143 break;
144
145 case IPR_CC:
146 retval |= ipr[idx] & ULL(0xffffffff00000000);
147 retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
148 break;
149
150 case IPR_VA:
151 retval = ipr[idx];
152 break;
153
154 case IPR_VA_FORM:
155 case IPR_MM_STAT:
156 case IPR_IFAULT_VA_FORM:
157 case IPR_EXC_MASK:
158 case IPR_EXC_SUM:
159 retval = ipr[idx];
160 break;
161
162 case IPR_DTB_PTE:
163 {
164 TlbEntry &entry
165 = tc->getDTBPtr()->index(!tc->misspeculating());
166
167 retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
168 retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
169 retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12;
170 retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1;
171 retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2;
172 retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4;
173 retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57;
174 }
175 break;
176
177 // write only registers
178 case IPR_HWINT_CLR:
179 case IPR_SL_XMIT:
180 case IPR_DC_FLUSH:
181 case IPR_IC_FLUSH:
182 case IPR_ALT_MODE:
183 case IPR_DTB_IA:
184 case IPR_DTB_IAP:
185 case IPR_ITB_IA:
186 case IPR_ITB_IAP:
187 panic("Tried to read write only register %d\n", idx);
188 break;
189
190 default:
191 // invalid IPR
192 panic("Tried to read from invalid ipr %d\n", idx);
193 break;
194 }
195
196 return retval;
197}
198
199// Cause the simulator to break when changing to the following IPL
200int break_ipl = -1;
201
202void
203ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
204{
1/*
2 * Copyright (c) 2002-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: Steve Reinhardt
29 * Nathan Binkert
30 */
31
32#include "arch/alpha/faults.hh"
33#include "arch/alpha/isa_traits.hh"
34#include "arch/alpha/kernel_stats.hh"
35#include "arch/alpha/osfpal.hh"
36#include "arch/alpha/tlb.hh"
37#include "base/cp_annotate.hh"
38#include "base/debug.hh"
39#include "cpu/base.hh"
40#include "cpu/simple_thread.hh"
41#include "cpu/thread_context.hh"
42#include "sim/sim_exit.hh"
43
44namespace AlphaISA {
45
46////////////////////////////////////////////////////////////////////////
47//
48// Machine dependent functions
49//
50void
51initCPU(ThreadContext *tc, int cpuId)
52{
53 initIPRs(tc, cpuId);
54
55 tc->setIntReg(16, cpuId);
56 tc->setIntReg(0, cpuId);
57
58 AlphaFault *reset = new ResetFault;
59
60 tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
61
62 delete reset;
63}
64
65template <class CPU>
66void
67zeroRegisters(CPU *cpu)
68{
69 // Insure ISA semantics
70 // (no longer very clean due to the change in setIntReg() in the
71 // cpu model. Consider changing later.)
72 cpu->thread->setIntReg(ZeroReg, 0);
73 cpu->thread->setFloatReg(ZeroReg, 0.0);
74}
75
76////////////////////////////////////////////////////////////////////////
77//
78//
79//
80void
81initIPRs(ThreadContext *tc, int cpuId)
82{
83 for (int i = 0; i < NumInternalProcRegs; ++i) {
84 tc->setMiscRegNoEffect(i, 0);
85 }
86
87 tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
88 tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
89 tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
90}
91
92MiscReg
93ISA::readIpr(int idx, ThreadContext *tc)
94{
95 uint64_t retval = 0; // return value, default 0
96
97 switch (idx) {
98 case IPR_PALtemp0:
99 case IPR_PALtemp1:
100 case IPR_PALtemp2:
101 case IPR_PALtemp3:
102 case IPR_PALtemp4:
103 case IPR_PALtemp5:
104 case IPR_PALtemp6:
105 case IPR_PALtemp7:
106 case IPR_PALtemp8:
107 case IPR_PALtemp9:
108 case IPR_PALtemp10:
109 case IPR_PALtemp11:
110 case IPR_PALtemp12:
111 case IPR_PALtemp13:
112 case IPR_PALtemp14:
113 case IPR_PALtemp15:
114 case IPR_PALtemp16:
115 case IPR_PALtemp17:
116 case IPR_PALtemp18:
117 case IPR_PALtemp19:
118 case IPR_PALtemp20:
119 case IPR_PALtemp21:
120 case IPR_PALtemp22:
121 case IPR_PALtemp23:
122 case IPR_PAL_BASE:
123
124 case IPR_IVPTBR:
125 case IPR_DC_MODE:
126 case IPR_MAF_MODE:
127 case IPR_ISR:
128 case IPR_EXC_ADDR:
129 case IPR_IC_PERR_STAT:
130 case IPR_DC_PERR_STAT:
131 case IPR_MCSR:
132 case IPR_ASTRR:
133 case IPR_ASTER:
134 case IPR_SIRR:
135 case IPR_ICSR:
136 case IPR_ICM:
137 case IPR_DTB_CM:
138 case IPR_IPLR:
139 case IPR_INTID:
140 case IPR_PMCTR:
141 // no side-effect
142 retval = ipr[idx];
143 break;
144
145 case IPR_CC:
146 retval |= ipr[idx] & ULL(0xffffffff00000000);
147 retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
148 break;
149
150 case IPR_VA:
151 retval = ipr[idx];
152 break;
153
154 case IPR_VA_FORM:
155 case IPR_MM_STAT:
156 case IPR_IFAULT_VA_FORM:
157 case IPR_EXC_MASK:
158 case IPR_EXC_SUM:
159 retval = ipr[idx];
160 break;
161
162 case IPR_DTB_PTE:
163 {
164 TlbEntry &entry
165 = tc->getDTBPtr()->index(!tc->misspeculating());
166
167 retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
168 retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
169 retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12;
170 retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1;
171 retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2;
172 retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4;
173 retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57;
174 }
175 break;
176
177 // write only registers
178 case IPR_HWINT_CLR:
179 case IPR_SL_XMIT:
180 case IPR_DC_FLUSH:
181 case IPR_IC_FLUSH:
182 case IPR_ALT_MODE:
183 case IPR_DTB_IA:
184 case IPR_DTB_IAP:
185 case IPR_ITB_IA:
186 case IPR_ITB_IAP:
187 panic("Tried to read write only register %d\n", idx);
188 break;
189
190 default:
191 // invalid IPR
192 panic("Tried to read from invalid ipr %d\n", idx);
193 break;
194 }
195
196 return retval;
197}
198
199// Cause the simulator to break when changing to the following IPL
200int break_ipl = -1;
201
202void
203ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
204{
205 uint64_t old;
206
207 if (tc->misspeculating())
208 return;
209
210 switch (idx) {
211 case IPR_PALtemp0:
212 case IPR_PALtemp1:
213 case IPR_PALtemp2:
214 case IPR_PALtemp3:
215 case IPR_PALtemp4:
216 case IPR_PALtemp5:
217 case IPR_PALtemp6:
218 case IPR_PALtemp7:
219 case IPR_PALtemp8:
220 case IPR_PALtemp9:
221 case IPR_PALtemp10:
222 case IPR_PALtemp11:
223 case IPR_PALtemp12:
224 case IPR_PALtemp13:
225 case IPR_PALtemp14:
226 case IPR_PALtemp15:
227 case IPR_PALtemp16:
228 case IPR_PALtemp17:
229 case IPR_PALtemp18:
230 case IPR_PALtemp19:
231 case IPR_PALtemp20:
232 case IPR_PALtemp21:
233 case IPR_PALtemp22:
234 case IPR_PAL_BASE:
235 case IPR_IC_PERR_STAT:
236 case IPR_DC_PERR_STAT:
237 case IPR_PMCTR:
238 // write entire quad w/ no side-effect
239 ipr[idx] = val;
240 break;
241
242 case IPR_CC_CTL:
243 // This IPR resets the cycle counter. We assume this only
244 // happens once... let's verify that.
245 assert(ipr[idx] == 0);
246 ipr[idx] = 1;
247 break;
248
249 case IPR_CC:
250 // This IPR only writes the upper 64 bits. It's ok to write
251 // all 64 here since we mask out the lower 32 in rpcc (see
252 // isa_desc).
253 ipr[idx] = val;
254 break;
255
256 case IPR_PALtemp23:
257 // write entire quad w/ no side-effect
205 if (tc->misspeculating())
206 return;
207
208 switch (idx) {
209 case IPR_PALtemp0:
210 case IPR_PALtemp1:
211 case IPR_PALtemp2:
212 case IPR_PALtemp3:
213 case IPR_PALtemp4:
214 case IPR_PALtemp5:
215 case IPR_PALtemp6:
216 case IPR_PALtemp7:
217 case IPR_PALtemp8:
218 case IPR_PALtemp9:
219 case IPR_PALtemp10:
220 case IPR_PALtemp11:
221 case IPR_PALtemp12:
222 case IPR_PALtemp13:
223 case IPR_PALtemp14:
224 case IPR_PALtemp15:
225 case IPR_PALtemp16:
226 case IPR_PALtemp17:
227 case IPR_PALtemp18:
228 case IPR_PALtemp19:
229 case IPR_PALtemp20:
230 case IPR_PALtemp21:
231 case IPR_PALtemp22:
232 case IPR_PAL_BASE:
233 case IPR_IC_PERR_STAT:
234 case IPR_DC_PERR_STAT:
235 case IPR_PMCTR:
236 // write entire quad w/ no side-effect
237 ipr[idx] = val;
238 break;
239
240 case IPR_CC_CTL:
241 // This IPR resets the cycle counter. We assume this only
242 // happens once... let's verify that.
243 assert(ipr[idx] == 0);
244 ipr[idx] = 1;
245 break;
246
247 case IPR_CC:
248 // This IPR only writes the upper 64 bits. It's ok to write
249 // all 64 here since we mask out the lower 32 in rpcc (see
250 // isa_desc).
251 ipr[idx] = val;
252 break;
253
254 case IPR_PALtemp23:
255 // write entire quad w/ no side-effect
258 old = ipr[idx];
259 ipr[idx] = val;
260 if (tc->getKernelStats())
256 if (tc->getKernelStats())
261 tc->getKernelStats()->context(old, val, tc);
257 tc->getKernelStats()->context(ipr[idx], val, tc);
258 ipr[idx] = val;
262 break;
263
264 case IPR_DTB_PTE:
265 // write entire quad w/ no side-effect, tag is forthcoming
266 ipr[idx] = val;
267 break;
268
269 case IPR_EXC_ADDR:
270 // second least significant bit in PC is always zero
271 ipr[idx] = val & ~2;
272 break;
273
274 case IPR_ASTRR:
275 case IPR_ASTER:
276 // only write least significant four bits - privilege mask
277 ipr[idx] = val & 0xf;
278 break;
279
280 case IPR_IPLR:
281#ifdef DEBUG
282 if (break_ipl != -1 && break_ipl == (int)(val & 0x1f))
283 Debug::breakpoint();
284#endif
285
286 // only write least significant five bits - interrupt level
287 ipr[idx] = val & 0x1f;
288 if (tc->getKernelStats())
289 tc->getKernelStats()->swpipl(ipr[idx]);
290 break;
291
292 case IPR_DTB_CM:
293 if (val & 0x18) {
294 if (tc->getKernelStats())
295 tc->getKernelStats()->mode(Kernel::user, tc);
296 } else {
297 if (tc->getKernelStats())
298 tc->getKernelStats()->mode(Kernel::kernel, tc);
299 }
300
301 case IPR_ICM:
302 // only write two mode bits - processor mode
303 ipr[idx] = val & 0x18;
304 break;
305
306 case IPR_ALT_MODE:
307 // only write two mode bits - processor mode
308 ipr[idx] = val & 0x18;
309 break;
310
311 case IPR_MCSR:
312 // more here after optimization...
313 ipr[idx] = val;
314 break;
315
316 case IPR_SIRR:
317 // only write software interrupt mask
318 ipr[idx] = val & 0x7fff0;
319 break;
320
321 case IPR_ICSR:
322 ipr[idx] = val & ULL(0xffffff0300);
323 break;
324
325 case IPR_IVPTBR:
326 case IPR_MVPTBR:
327 ipr[idx] = val & ULL(0xffffffffc0000000);
328 break;
329
330 case IPR_DC_TEST_CTL:
331 ipr[idx] = val & 0x1ffb;
332 break;
333
334 case IPR_DC_MODE:
335 case IPR_MAF_MODE:
336 ipr[idx] = val & 0x3f;
337 break;
338
339 case IPR_ITB_ASN:
340 ipr[idx] = val & 0x7f0;
341 break;
342
343 case IPR_DTB_ASN:
344 ipr[idx] = val & ULL(0xfe00000000000000);
345 break;
346
347 case IPR_EXC_SUM:
348 case IPR_EXC_MASK:
349 // any write to this register clears it
350 ipr[idx] = 0;
351 break;
352
353 case IPR_INTID:
354 case IPR_SL_RCV:
355 case IPR_MM_STAT:
356 case IPR_ITB_PTE_TEMP:
357 case IPR_DTB_PTE_TEMP:
358 // read-only registers
359 panic("Tried to write read only ipr %d\n", idx);
360
361 case IPR_HWINT_CLR:
362 case IPR_SL_XMIT:
363 case IPR_DC_FLUSH:
364 case IPR_IC_FLUSH:
365 // the following are write only
366 ipr[idx] = val;
367 break;
368
369 case IPR_DTB_IA:
370 // really a control write
371 ipr[idx] = 0;
372
373 tc->getDTBPtr()->flushAll();
374 break;
375
376 case IPR_DTB_IAP:
377 // really a control write
378 ipr[idx] = 0;
379
380 tc->getDTBPtr()->flushProcesses();
381 break;
382
383 case IPR_DTB_IS:
384 // really a control write
385 ipr[idx] = val;
386
387 tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
388 break;
389
390 case IPR_DTB_TAG: {
391 struct TlbEntry entry;
392
393 // FIXME: granularity hints NYI...
394 if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
395 panic("PTE GH field != 0");
396
397 // write entire quad
398 ipr[idx] = val;
399
400 // construct PTE for new entry
401 entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
402 entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
403 entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
404 entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
405 entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
406 entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
407 entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
408
409 // insert new TAG/PTE value into data TLB
410 tc->getDTBPtr()->insert(val, entry);
411 }
412 break;
413
414 case IPR_ITB_PTE: {
415 struct TlbEntry entry;
416
417 // FIXME: granularity hints NYI...
418 if (ITB_PTE_GH(val) != 0)
419 panic("PTE GH field != 0");
420
421 // write entire quad
422 ipr[idx] = val;
423
424 // construct PTE for new entry
425 entry.ppn = ITB_PTE_PPN(val);
426 entry.xre = ITB_PTE_XRE(val);
427 entry.xwe = 0;
428 entry.fonr = ITB_PTE_FONR(val);
429 entry.fonw = ITB_PTE_FONW(val);
430 entry.asma = ITB_PTE_ASMA(val);
431 entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
432
433 // insert new TAG/PTE value into data TLB
434 tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
435 }
436 break;
437
438 case IPR_ITB_IA:
439 // really a control write
440 ipr[idx] = 0;
441
442 tc->getITBPtr()->flushAll();
443 break;
444
445 case IPR_ITB_IAP:
446 // really a control write
447 ipr[idx] = 0;
448
449 tc->getITBPtr()->flushProcesses();
450 break;
451
452 case IPR_ITB_IS:
453 // really a control write
454 ipr[idx] = val;
455
456 tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
457 break;
458
459 default:
460 // invalid IPR
461 panic("Tried to write to invalid ipr %d\n", idx);
462 }
463
464 // no error...
465}
466
467void
468copyIprs(ThreadContext *src, ThreadContext *dest)
469{
470 for (int i = 0; i < NumInternalProcRegs; ++i)
471 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
472}
473
474} // namespace AlphaISA
475
476using namespace AlphaISA;
477
478Fault
479SimpleThread::hwrei()
480{
481 PCState pc = pcState();
482 if (!(pc.pc() & 0x3))
483 return new UnimplementedOpcodeFault;
484
485 pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR));
486 pcState(pc);
487
488 CPA::cpa()->swAutoBegin(tc, pc.npc());
489
490 if (!misspeculating()) {
491 if (kernelStats)
492 kernelStats->hwrei();
493 }
494
495 // FIXME: XXX check for interrupts? XXX
496 return NoFault;
497}
498
499/**
500 * Check for special simulator handling of specific PAL calls.
501 * If return value is false, actual PAL call will be suppressed.
502 */
503bool
504SimpleThread::simPalCheck(int palFunc)
505{
506 if (kernelStats)
507 kernelStats->callpal(palFunc, tc);
508
509 switch (palFunc) {
510 case PAL::halt:
511 halt();
512 if (--System::numSystemsRunning == 0)
513 exitSimLoop("all cpus halted");
514 break;
515
516 case PAL::bpt:
517 case PAL::bugchk:
518 if (system->breakpoint())
519 return false;
520 break;
521 }
522
523 return true;
524}
259 break;
260
261 case IPR_DTB_PTE:
262 // write entire quad w/ no side-effect, tag is forthcoming
263 ipr[idx] = val;
264 break;
265
266 case IPR_EXC_ADDR:
267 // second least significant bit in PC is always zero
268 ipr[idx] = val & ~2;
269 break;
270
271 case IPR_ASTRR:
272 case IPR_ASTER:
273 // only write least significant four bits - privilege mask
274 ipr[idx] = val & 0xf;
275 break;
276
277 case IPR_IPLR:
278#ifdef DEBUG
279 if (break_ipl != -1 && break_ipl == (int)(val & 0x1f))
280 Debug::breakpoint();
281#endif
282
283 // only write least significant five bits - interrupt level
284 ipr[idx] = val & 0x1f;
285 if (tc->getKernelStats())
286 tc->getKernelStats()->swpipl(ipr[idx]);
287 break;
288
289 case IPR_DTB_CM:
290 if (val & 0x18) {
291 if (tc->getKernelStats())
292 tc->getKernelStats()->mode(Kernel::user, tc);
293 } else {
294 if (tc->getKernelStats())
295 tc->getKernelStats()->mode(Kernel::kernel, tc);
296 }
297
298 case IPR_ICM:
299 // only write two mode bits - processor mode
300 ipr[idx] = val & 0x18;
301 break;
302
303 case IPR_ALT_MODE:
304 // only write two mode bits - processor mode
305 ipr[idx] = val & 0x18;
306 break;
307
308 case IPR_MCSR:
309 // more here after optimization...
310 ipr[idx] = val;
311 break;
312
313 case IPR_SIRR:
314 // only write software interrupt mask
315 ipr[idx] = val & 0x7fff0;
316 break;
317
318 case IPR_ICSR:
319 ipr[idx] = val & ULL(0xffffff0300);
320 break;
321
322 case IPR_IVPTBR:
323 case IPR_MVPTBR:
324 ipr[idx] = val & ULL(0xffffffffc0000000);
325 break;
326
327 case IPR_DC_TEST_CTL:
328 ipr[idx] = val & 0x1ffb;
329 break;
330
331 case IPR_DC_MODE:
332 case IPR_MAF_MODE:
333 ipr[idx] = val & 0x3f;
334 break;
335
336 case IPR_ITB_ASN:
337 ipr[idx] = val & 0x7f0;
338 break;
339
340 case IPR_DTB_ASN:
341 ipr[idx] = val & ULL(0xfe00000000000000);
342 break;
343
344 case IPR_EXC_SUM:
345 case IPR_EXC_MASK:
346 // any write to this register clears it
347 ipr[idx] = 0;
348 break;
349
350 case IPR_INTID:
351 case IPR_SL_RCV:
352 case IPR_MM_STAT:
353 case IPR_ITB_PTE_TEMP:
354 case IPR_DTB_PTE_TEMP:
355 // read-only registers
356 panic("Tried to write read only ipr %d\n", idx);
357
358 case IPR_HWINT_CLR:
359 case IPR_SL_XMIT:
360 case IPR_DC_FLUSH:
361 case IPR_IC_FLUSH:
362 // the following are write only
363 ipr[idx] = val;
364 break;
365
366 case IPR_DTB_IA:
367 // really a control write
368 ipr[idx] = 0;
369
370 tc->getDTBPtr()->flushAll();
371 break;
372
373 case IPR_DTB_IAP:
374 // really a control write
375 ipr[idx] = 0;
376
377 tc->getDTBPtr()->flushProcesses();
378 break;
379
380 case IPR_DTB_IS:
381 // really a control write
382 ipr[idx] = val;
383
384 tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
385 break;
386
387 case IPR_DTB_TAG: {
388 struct TlbEntry entry;
389
390 // FIXME: granularity hints NYI...
391 if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
392 panic("PTE GH field != 0");
393
394 // write entire quad
395 ipr[idx] = val;
396
397 // construct PTE for new entry
398 entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
399 entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
400 entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
401 entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
402 entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
403 entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
404 entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
405
406 // insert new TAG/PTE value into data TLB
407 tc->getDTBPtr()->insert(val, entry);
408 }
409 break;
410
411 case IPR_ITB_PTE: {
412 struct TlbEntry entry;
413
414 // FIXME: granularity hints NYI...
415 if (ITB_PTE_GH(val) != 0)
416 panic("PTE GH field != 0");
417
418 // write entire quad
419 ipr[idx] = val;
420
421 // construct PTE for new entry
422 entry.ppn = ITB_PTE_PPN(val);
423 entry.xre = ITB_PTE_XRE(val);
424 entry.xwe = 0;
425 entry.fonr = ITB_PTE_FONR(val);
426 entry.fonw = ITB_PTE_FONW(val);
427 entry.asma = ITB_PTE_ASMA(val);
428 entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
429
430 // insert new TAG/PTE value into data TLB
431 tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
432 }
433 break;
434
435 case IPR_ITB_IA:
436 // really a control write
437 ipr[idx] = 0;
438
439 tc->getITBPtr()->flushAll();
440 break;
441
442 case IPR_ITB_IAP:
443 // really a control write
444 ipr[idx] = 0;
445
446 tc->getITBPtr()->flushProcesses();
447 break;
448
449 case IPR_ITB_IS:
450 // really a control write
451 ipr[idx] = val;
452
453 tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
454 break;
455
456 default:
457 // invalid IPR
458 panic("Tried to write to invalid ipr %d\n", idx);
459 }
460
461 // no error...
462}
463
464void
465copyIprs(ThreadContext *src, ThreadContext *dest)
466{
467 for (int i = 0; i < NumInternalProcRegs; ++i)
468 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
469}
470
471} // namespace AlphaISA
472
473using namespace AlphaISA;
474
475Fault
476SimpleThread::hwrei()
477{
478 PCState pc = pcState();
479 if (!(pc.pc() & 0x3))
480 return new UnimplementedOpcodeFault;
481
482 pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR));
483 pcState(pc);
484
485 CPA::cpa()->swAutoBegin(tc, pc.npc());
486
487 if (!misspeculating()) {
488 if (kernelStats)
489 kernelStats->hwrei();
490 }
491
492 // FIXME: XXX check for interrupts? XXX
493 return NoFault;
494}
495
496/**
497 * Check for special simulator handling of specific PAL calls.
498 * If return value is false, actual PAL call will be suppressed.
499 */
500bool
501SimpleThread::simPalCheck(int palFunc)
502{
503 if (kernelStats)
504 kernelStats->callpal(palFunc, tc);
505
506 switch (palFunc) {
507 case PAL::halt:
508 halt();
509 if (--System::numSystemsRunning == 0)
510 exitSimLoop("all cpus halted");
511 break;
512
513 case PAL::bpt:
514 case PAL::bugchk:
515 if (system->breakpoint())
516 return false;
517 break;
518 }
519
520 return true;
521}