ua2005.cc (5100:7a0180040755) ua2005.cc (5531:a5ff5e57fafd)
1/*
2 * Copyright (c) 2006 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;

--- 26 unchanged lines hidden (view full) ---

35#include "sim/system.hh"
36
37using namespace SparcISA;
38
39
40void
41MiscRegFile::checkSoftInt(ThreadContext *tc)
42{
1/*
2 * Copyright (c) 2006 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;

--- 26 unchanged lines hidden (view full) ---

35#include "sim/system.hh"
36
37using namespace SparcISA;
38
39
40void
41MiscRegFile::checkSoftInt(ThreadContext *tc)
42{
43 BaseCPU *cpu = tc->getCpuPtr();
44
43 // If PIL < 14, copy over the tm and sm bits
44 if (pil < 14 && softint & 0x10000)
45 // If PIL < 14, copy over the tm and sm bits
46 if (pil < 14 && softint & 0x10000)
45 tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16);
47 cpu->post_interrupt(IT_SOFT_INT, 16);
46 else
48 else
47 tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16);
49 cpu->clear_interrupt(IT_SOFT_INT, 16);
48 if (pil < 14 && softint & 0x1)
50 if (pil < 14 && softint & 0x1)
49 tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0);
51 cpu->post_interrupt(IT_SOFT_INT, 0);
50 else
52 else
51 tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0);
53 cpu->clear_interrupt(IT_SOFT_INT, 0);
52
53 // Copy over any of the other bits that are set
54 for (int bit = 15; bit > 0; --bit) {
55 if (1 << bit & softint && bit > pil)
54
55 // Copy over any of the other bits that are set
56 for (int bit = 15; bit > 0; --bit) {
57 if (1 << bit & softint && bit > pil)
56 tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit);
58 cpu->post_interrupt(IT_SOFT_INT, bit);
57 else
59 else
58 tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit);
60 cpu->clear_interrupt(IT_SOFT_INT, bit);
59 }
60}
61
62
63void
64MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
65{
61 }
62}
63
64
65void
66MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
67{
68 BaseCPU *cpu = tc->getCpuPtr();
69
66 int64_t time;
67 switch (miscReg) {
68 /* Full system only ASRs */
69 case MISCREG_SOFTINT:
70 setRegNoEffect(miscReg, val);;
71 checkSoftInt(tc);
72 break;
73 case MISCREG_SOFTINT_CLR:

--- 6 unchanged lines hidden (view full) ---

80 tickCompare = new TickCompareEvent(this, tc);
81 setRegNoEffect(miscReg, val);
82 if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
83 tickCompare->deschedule();
84 time = (tick_cmpr & mask(63)) - (tick & mask(63));
85 if (!(tick_cmpr & ~mask(63)) && time > 0) {
86 if (tickCompare->scheduled())
87 tickCompare->deschedule();
70 int64_t time;
71 switch (miscReg) {
72 /* Full system only ASRs */
73 case MISCREG_SOFTINT:
74 setRegNoEffect(miscReg, val);;
75 checkSoftInt(tc);
76 break;
77 case MISCREG_SOFTINT_CLR:

--- 6 unchanged lines hidden (view full) ---

84 tickCompare = new TickCompareEvent(this, tc);
85 setRegNoEffect(miscReg, val);
86 if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
87 tickCompare->deschedule();
88 time = (tick_cmpr & mask(63)) - (tick & mask(63));
89 if (!(tick_cmpr & ~mask(63)) && time > 0) {
90 if (tickCompare->scheduled())
91 tickCompare->deschedule();
88 tickCompare->schedule(time * tc->getCpuPtr()->ticks(1));
92 tickCompare->schedule(time * cpu->ticks(1));
89 }
90 panic("writing to TICK compare register %#X\n", val);
91 break;
92
93 case MISCREG_STICK_CMPR:
94 if (sTickCompare == NULL)
95 sTickCompare = new STickCompareEvent(this, tc);
96 setRegNoEffect(miscReg, val);
97 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
98 sTickCompare->deschedule();
99 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
93 }
94 panic("writing to TICK compare register %#X\n", val);
95 break;
96
97 case MISCREG_STICK_CMPR:
98 if (sTickCompare == NULL)
99 sTickCompare = new STickCompareEvent(this, tc);
100 setRegNoEffect(miscReg, val);
101 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
102 sTickCompare->deschedule();
103 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
100 tc->getCpuPtr()->instCount();
104 cpu->instCount();
101 if (!(stick_cmpr & ~mask(63)) && time > 0) {
102 if (sTickCompare->scheduled())
103 sTickCompare->deschedule();
105 if (!(stick_cmpr & ~mask(63)) && time > 0) {
106 if (sTickCompare->scheduled())
107 sTickCompare->deschedule();
104 sTickCompare->schedule(time * tc->getCpuPtr()->ticks(1) + curTick);
108 sTickCompare->schedule(time * cpu->ticks(1) + curTick);
105 }
106 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
107 break;
108
109 case MISCREG_PSTATE:
110 setRegNoEffect(miscReg, val);
111
112 case MISCREG_PIL:
113 setRegNoEffect(miscReg, val);
114 checkSoftInt(tc);
115 break;
116
117 case MISCREG_HVER:
118 panic("Shouldn't be writing HVER\n");
119
120 case MISCREG_HINTP:
121 setRegNoEffect(miscReg, val);
122 if (hintp)
109 }
110 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
111 break;
112
113 case MISCREG_PSTATE:
114 setRegNoEffect(miscReg, val);
115
116 case MISCREG_PIL:
117 setRegNoEffect(miscReg, val);
118 checkSoftInt(tc);
119 break;
120
121 case MISCREG_HVER:
122 panic("Shouldn't be writing HVER\n");
123
124 case MISCREG_HINTP:
125 setRegNoEffect(miscReg, val);
126 if (hintp)
123 tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
127 cpu->post_interrupt(IT_HINTP, 0);
124 else
128 else
125 tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
129 cpu->clear_interrupt(IT_HINTP, 0);
126 break;
127
128 case MISCREG_HTBA:
129 // clear lower 7 bits on writes.
130 setRegNoEffect(miscReg, val & ULL(~0x7FFF));
131 break;
132
133 case MISCREG_QUEUE_CPU_MONDO_HEAD:
134 case MISCREG_QUEUE_CPU_MONDO_TAIL:
135 setRegNoEffect(miscReg, val);
136 if (cpu_mondo_head != cpu_mondo_tail)
130 break;
131
132 case MISCREG_HTBA:
133 // clear lower 7 bits on writes.
134 setRegNoEffect(miscReg, val & ULL(~0x7FFF));
135 break;
136
137 case MISCREG_QUEUE_CPU_MONDO_HEAD:
138 case MISCREG_QUEUE_CPU_MONDO_TAIL:
139 setRegNoEffect(miscReg, val);
140 if (cpu_mondo_head != cpu_mondo_tail)
137 tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
141 cpu->post_interrupt(IT_CPU_MONDO, 0);
138 else
142 else
139 tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
143 cpu->clear_interrupt(IT_CPU_MONDO, 0);
140 break;
141 case MISCREG_QUEUE_DEV_MONDO_HEAD:
142 case MISCREG_QUEUE_DEV_MONDO_TAIL:
143 setRegNoEffect(miscReg, val);
144 if (dev_mondo_head != dev_mondo_tail)
144 break;
145 case MISCREG_QUEUE_DEV_MONDO_HEAD:
146 case MISCREG_QUEUE_DEV_MONDO_TAIL:
147 setRegNoEffect(miscReg, val);
148 if (dev_mondo_head != dev_mondo_tail)
145 tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
149 cpu->post_interrupt(IT_DEV_MONDO, 0);
146 else
150 else
147 tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
151 cpu->clear_interrupt(IT_DEV_MONDO, 0);
148 break;
149 case MISCREG_QUEUE_RES_ERROR_HEAD:
150 case MISCREG_QUEUE_RES_ERROR_TAIL:
151 setRegNoEffect(miscReg, val);
152 if (res_error_head != res_error_tail)
152 break;
153 case MISCREG_QUEUE_RES_ERROR_HEAD:
154 case MISCREG_QUEUE_RES_ERROR_TAIL:
155 setRegNoEffect(miscReg, val);
156 if (res_error_head != res_error_tail)
153 tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
157 cpu->post_interrupt(IT_RES_ERROR, 0);
154 else
158 else
155 tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
159 cpu->clear_interrupt(IT_RES_ERROR, 0);
156 break;
157 case MISCREG_QUEUE_NRES_ERROR_HEAD:
158 case MISCREG_QUEUE_NRES_ERROR_TAIL:
159 setRegNoEffect(miscReg, val);
160 // This one doesn't have an interrupt to report to the guest OS
161 break;
162
163 case MISCREG_HSTICK_CMPR:
164 if (hSTickCompare == NULL)
165 hSTickCompare = new HSTickCompareEvent(this, tc);
166 setRegNoEffect(miscReg, val);
167 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
168 hSTickCompare->deschedule();
169 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
160 break;
161 case MISCREG_QUEUE_NRES_ERROR_HEAD:
162 case MISCREG_QUEUE_NRES_ERROR_TAIL:
163 setRegNoEffect(miscReg, val);
164 // This one doesn't have an interrupt to report to the guest OS
165 break;
166
167 case MISCREG_HSTICK_CMPR:
168 if (hSTickCompare == NULL)
169 hSTickCompare = new HSTickCompareEvent(this, tc);
170 setRegNoEffect(miscReg, val);
171 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
172 hSTickCompare->deschedule();
173 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
170 tc->getCpuPtr()->instCount();
174 cpu->instCount();
171 if (!(hstick_cmpr & ~mask(63)) && time > 0) {
172 if (hSTickCompare->scheduled())
173 hSTickCompare->deschedule();
175 if (!(hstick_cmpr & ~mask(63)) && time > 0) {
176 if (hSTickCompare->scheduled())
177 hSTickCompare->deschedule();
174 hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->ticks(1));
178 hSTickCompare->schedule(curTick + time * cpu->ticks(1));
175 }
176 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
177 break;
178
179 case MISCREG_HPSTATE:
180 // T1000 spec says impl. dependent val must always be 1
181 setRegNoEffect(miscReg, val | HPSTATE::id);
182#if FULL_SYSTEM
183 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
179 }
180 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
181 break;
182
183 case MISCREG_HPSTATE:
184 // T1000 spec says impl. dependent val must always be 1
185 setRegNoEffect(miscReg, val | HPSTATE::id);
186#if FULL_SYSTEM
187 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
184 tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
188 cpu->post_interrupt(IT_TRAP_LEVEL_ZERO, 0);
185 else
189 else
186 tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
190 cpu->clear_interrupt(IT_TRAP_LEVEL_ZERO, 0);
187#endif
188 break;
189 case MISCREG_HTSTATE:
190 setRegNoEffect(miscReg, val);
191 break;
192
193 case MISCREG_STRAND_STS_REG:
194 if (bits(val,2,2))
195 panic("No support for setting spec_en bit\n");
196 setRegNoEffect(miscReg, bits(val,0,0));
197 if (!bits(val,0,0)) {
198 DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
199 // Time to go to sleep
200 tc->suspend();
201 if (tc->getKernelStats())
202 tc->getKernelStats()->quiesce();
191#endif
192 break;
193 case MISCREG_HTSTATE:
194 setRegNoEffect(miscReg, val);
195 break;
196
197 case MISCREG_STRAND_STS_REG:
198 if (bits(val,2,2))
199 panic("No support for setting spec_en bit\n");
200 setRegNoEffect(miscReg, bits(val,0,0));
201 if (!bits(val,0,0)) {
202 DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
203 // Time to go to sleep
204 tc->suspend();
205 if (tc->getKernelStats())
206 tc->getKernelStats()->quiesce();
203 }
207 }
204 break;
205
206 default:
208 break;
209
210 default:
207 panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
211 panic("Invalid write to FS misc register %s\n",
212 getMiscRegName(miscReg));
208 }
209}
210
211MiscReg
212MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
213{
214 uint64_t temp;
215

--- 29 unchanged lines hidden (view full) ---

245 (NWindows -1) << 0;
246
247 case MISCREG_STRAND_STS_REG:
248 System *sys;
249 int x;
250 sys = tc->getSystemPtr();
251
252 temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
213 }
214}
215
216MiscReg
217MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
218{
219 uint64_t temp;
220

--- 29 unchanged lines hidden (view full) ---

250 (NWindows -1) << 0;
251
252 case MISCREG_STRAND_STS_REG:
253 System *sys;
254 int x;
255 sys = tc->getSystemPtr();
256
257 temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
253 // Check that the CPU array is fully populated (by calling getNumCPus())
258 // Check that the CPU array is fully populated
259 // (by calling getNumCPus())
254 assert(sys->getNumCPUs() > tc->readCpuId());
255
256 temp |= tc->readCpuId() << STS::shft_id;
257
258 for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
259 switch (sys->threadContexts[x]->status()) {
260 case ThreadContext::Active:
261 temp |= STS::st_run << (STS::shft_fsm0 -

--- 13 unchanged lines hidden (view full) ---

275 } // switch
276 } // for
277
278 return temp;
279 default:
280 panic("Invalid read to FS misc register\n");
281 }
282}
260 assert(sys->getNumCPUs() > tc->readCpuId());
261
262 temp |= tc->readCpuId() << STS::shft_id;
263
264 for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
265 switch (sys->threadContexts[x]->status()) {
266 case ThreadContext::Active:
267 temp |= STS::st_run << (STS::shft_fsm0 -

--- 13 unchanged lines hidden (view full) ---

281 } // switch
282 } // for
283
284 return temp;
285 default:
286 panic("Invalid read to FS misc register\n");
287 }
288}
283/*
284 In Niagra STICK==TICK so this isn't needed
285 case MISCREG_STICK:
286 SparcSystem *sys;
287 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
288 assert(sys != NULL);
289 return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
290*/
291
289
292
293
294void
295MiscRegFile::processTickCompare(ThreadContext *tc)
296{
297 panic("tick compare not implemented\n");
298}
299
300void
301MiscRegFile::processSTickCompare(ThreadContext *tc)

--- 45 unchanged lines hidden ---
290void
291MiscRegFile::processTickCompare(ThreadContext *tc)
292{
293 panic("tick compare not implemented\n");
294}
295
296void
297MiscRegFile::processSTickCompare(ThreadContext *tc)

--- 45 unchanged lines hidden ---