ua2005.cc (4103:785279436bdd) ua2005.cc (4172:141705d83494)
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;

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

61void
62MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
63 ThreadContext *tc)
64{
65 int64_t time;
66 switch (miscReg) {
67 /* Full system only ASRs */
68 case MISCREG_SOFTINT:
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;

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

61void
62MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
63 ThreadContext *tc)
64{
65 int64_t time;
66 switch (miscReg) {
67 /* Full system only ASRs */
68 case MISCREG_SOFTINT:
69 setReg(miscReg, val);;
69 setRegNoEffect(miscReg, val);;
70 checkSoftInt(tc);
71 break;
72 case MISCREG_SOFTINT_CLR:
70 checkSoftInt(tc);
71 break;
72 case MISCREG_SOFTINT_CLR:
73 return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc);
73 return setReg(MISCREG_SOFTINT, ~val & softint, tc);
74 case MISCREG_SOFTINT_SET:
74 case MISCREG_SOFTINT_SET:
75 return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc);
75 return setReg(MISCREG_SOFTINT, val | softint, tc);
76
77 case MISCREG_TICK_CMPR:
78 if (tickCompare == NULL)
79 tickCompare = new TickCompareEvent(this, tc);
76
77 case MISCREG_TICK_CMPR:
78 if (tickCompare == NULL)
79 tickCompare = new TickCompareEvent(this, tc);
80 setReg(miscReg, val);
80 setRegNoEffect(miscReg, val);
81 if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
82 tickCompare->deschedule();
83 time = (tick_cmpr & mask(63)) - (tick & mask(63));
84 if (!(tick_cmpr & ~mask(63)) && time > 0) {
85 if (tickCompare->scheduled())
86 tickCompare->deschedule();
87 tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
88 }
89 panic("writing to TICK compare register %#X\n", val);
90 break;
91
92 case MISCREG_STICK_CMPR:
93 if (sTickCompare == NULL)
94 sTickCompare = new STickCompareEvent(this, tc);
81 if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
82 tickCompare->deschedule();
83 time = (tick_cmpr & mask(63)) - (tick & mask(63));
84 if (!(tick_cmpr & ~mask(63)) && time > 0) {
85 if (tickCompare->scheduled())
86 tickCompare->deschedule();
87 tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
88 }
89 panic("writing to TICK compare register %#X\n", val);
90 break;
91
92 case MISCREG_STICK_CMPR:
93 if (sTickCompare == NULL)
94 sTickCompare = new STickCompareEvent(this, tc);
95 setReg(miscReg, val);
95 setRegNoEffect(miscReg, val);
96 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
97 sTickCompare->deschedule();
98 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
99 tc->getCpuPtr()->instCount();
100 if (!(stick_cmpr & ~mask(63)) && time > 0) {
101 if (sTickCompare->scheduled())
102 sTickCompare->deschedule();
103 sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
104 }
105 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
106 break;
107
108 case MISCREG_PSTATE:
96 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
97 sTickCompare->deschedule();
98 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
99 tc->getCpuPtr()->instCount();
100 if (!(stick_cmpr & ~mask(63)) && time > 0) {
101 if (sTickCompare->scheduled())
102 sTickCompare->deschedule();
103 sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
104 }
105 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
106 break;
107
108 case MISCREG_PSTATE:
109 setReg(miscReg, val);
109 setRegNoEffect(miscReg, val);
110
111 case MISCREG_PIL:
110
111 case MISCREG_PIL:
112 setReg(miscReg, val);
112 setRegNoEffect(miscReg, val);
113 checkSoftInt(tc);
114 break;
115
116 case MISCREG_HVER:
117 panic("Shouldn't be writing HVER\n");
118
119 case MISCREG_HINTP:
113 checkSoftInt(tc);
114 break;
115
116 case MISCREG_HVER:
117 panic("Shouldn't be writing HVER\n");
118
119 case MISCREG_HINTP:
120 setReg(miscReg, val);
120 setRegNoEffect(miscReg, val);
121 if (hintp)
122 tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
123 else
124 tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
125 break;
126
127 case MISCREG_HTBA:
128 // clear lower 7 bits on writes.
121 if (hintp)
122 tc->getCpuPtr()->post_interrupt(IT_HINTP,0);
123 else
124 tc->getCpuPtr()->clear_interrupt(IT_HINTP,0);
125 break;
126
127 case MISCREG_HTBA:
128 // clear lower 7 bits on writes.
129 setReg(miscReg, val & ULL(~0x7FFF));
129 setRegNoEffect(miscReg, val & ULL(~0x7FFF));
130 break;
131
132 case MISCREG_QUEUE_CPU_MONDO_HEAD:
133 case MISCREG_QUEUE_CPU_MONDO_TAIL:
130 break;
131
132 case MISCREG_QUEUE_CPU_MONDO_HEAD:
133 case MISCREG_QUEUE_CPU_MONDO_TAIL:
134 setReg(miscReg, val);
134 setRegNoEffect(miscReg, val);
135 if (cpu_mondo_head != cpu_mondo_tail)
136 tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
137 else
138 tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
139 break;
140 case MISCREG_QUEUE_DEV_MONDO_HEAD:
141 case MISCREG_QUEUE_DEV_MONDO_TAIL:
135 if (cpu_mondo_head != cpu_mondo_tail)
136 tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0);
137 else
138 tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0);
139 break;
140 case MISCREG_QUEUE_DEV_MONDO_HEAD:
141 case MISCREG_QUEUE_DEV_MONDO_TAIL:
142 setReg(miscReg, val);
142 setRegNoEffect(miscReg, val);
143 if (dev_mondo_head != dev_mondo_tail)
144 tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
145 else
146 tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
147 break;
148 case MISCREG_QUEUE_RES_ERROR_HEAD:
149 case MISCREG_QUEUE_RES_ERROR_TAIL:
143 if (dev_mondo_head != dev_mondo_tail)
144 tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0);
145 else
146 tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0);
147 break;
148 case MISCREG_QUEUE_RES_ERROR_HEAD:
149 case MISCREG_QUEUE_RES_ERROR_TAIL:
150 setReg(miscReg, val);
150 setRegNoEffect(miscReg, val);
151 if (res_error_head != res_error_tail)
152 tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
153 else
154 tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
155 break;
156 case MISCREG_QUEUE_NRES_ERROR_HEAD:
157 case MISCREG_QUEUE_NRES_ERROR_TAIL:
151 if (res_error_head != res_error_tail)
152 tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0);
153 else
154 tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0);
155 break;
156 case MISCREG_QUEUE_NRES_ERROR_HEAD:
157 case MISCREG_QUEUE_NRES_ERROR_TAIL:
158 setReg(miscReg, val);
158 setRegNoEffect(miscReg, val);
159 // This one doesn't have an interrupt to report to the guest OS
160 break;
161
162 case MISCREG_HSTICK_CMPR:
163 if (hSTickCompare == NULL)
164 hSTickCompare = new HSTickCompareEvent(this, tc);
159 // This one doesn't have an interrupt to report to the guest OS
160 break;
161
162 case MISCREG_HSTICK_CMPR:
163 if (hSTickCompare == NULL)
164 hSTickCompare = new HSTickCompareEvent(this, tc);
165 setReg(miscReg, val);
165 setRegNoEffect(miscReg, val);
166 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
167 hSTickCompare->deschedule();
168 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
169 tc->getCpuPtr()->instCount();
170 if (!(hstick_cmpr & ~mask(63)) && time > 0) {
171 if (hSTickCompare->scheduled())
172 hSTickCompare->deschedule();
173 hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1));
174 }
175 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
176 break;
177
178 case MISCREG_HPSTATE:
179 // T1000 spec says impl. dependent val must always be 1
166 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
167 hSTickCompare->deschedule();
168 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
169 tc->getCpuPtr()->instCount();
170 if (!(hstick_cmpr & ~mask(63)) && time > 0) {
171 if (hSTickCompare->scheduled())
172 hSTickCompare->deschedule();
173 hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1));
174 }
175 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
176 break;
177
178 case MISCREG_HPSTATE:
179 // T1000 spec says impl. dependent val must always be 1
180 setReg(miscReg, val | HPSTATE::id);
180 setRegNoEffect(miscReg, val | HPSTATE::id);
181#if FULL_SYSTEM
182 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
183 tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
184 else
185 tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
186#endif
187 break;
188 case MISCREG_HTSTATE:
189 case MISCREG_STRAND_STS_REG:
181#if FULL_SYSTEM
182 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
183 tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
184 else
185 tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
186#endif
187 break;
188 case MISCREG_HTSTATE:
189 case MISCREG_STRAND_STS_REG:
190 setReg(miscReg, val);
190 setRegNoEffect(miscReg, val);
191 break;
192
193 default:
194 panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
195 }
196}
197
198MiscReg

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

212 case MISCREG_TICK_CMPR:
213 case MISCREG_STICK_CMPR:
214 case MISCREG_PIL:
215 case MISCREG_HPSTATE:
216 case MISCREG_HINTP:
217 case MISCREG_HTSTATE:
218 case MISCREG_STRAND_STS_REG:
219 case MISCREG_HSTICK_CMPR:
191 break;
192
193 default:
194 panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
195 }
196}
197
198MiscReg

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

212 case MISCREG_TICK_CMPR:
213 case MISCREG_STICK_CMPR:
214 case MISCREG_PIL:
215 case MISCREG_HPSTATE:
216 case MISCREG_HINTP:
217 case MISCREG_HTSTATE:
218 case MISCREG_STRAND_STS_REG:
219 case MISCREG_HSTICK_CMPR:
220 return readReg(miscReg) ;
220 return readRegNoEffect(miscReg) ;
221
222 case MISCREG_HTBA:
221
222 case MISCREG_HTBA:
223 return readReg(miscReg) & ULL(~0x7FFF);
223 return readRegNoEffect(miscReg) & ULL(~0x7FFF);
224 case MISCREG_HVER:
225 return NWindows | MaxTL << 8 | MaxGL << 16;
226
227 default:
228 panic("Invalid read to FS misc register\n");
229 }
230}
231/*

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

254 int ticks;
255 ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
256 tc->getCpuPtr()->instCount();
257 assert(ticks >= 0 && "stick compare missed interrupt cycle");
258
259 if (ticks == 0) {
260 DPRINTF(Timer, "STick compare cycle reached at %#x\n",
261 (stick_cmpr & mask(63)));
224 case MISCREG_HVER:
225 return NWindows | MaxTL << 8 | MaxGL << 16;
226
227 default:
228 panic("Invalid read to FS misc register\n");
229 }
230}
231/*

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

254 int ticks;
255 ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
256 tc->getCpuPtr()->instCount();
257 assert(ticks >= 0 && "stick compare missed interrupt cycle");
258
259 if (ticks == 0) {
260 DPRINTF(Timer, "STick compare cycle reached at %#x\n",
261 (stick_cmpr & mask(63)));
262 if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
263 setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
262 if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
263 setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
264 }
265 } else
266 sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
267}
268
269void
270MiscRegFile::processHSTickCompare(ThreadContext *tc)
271{
272 // since our microcode instructions take two cycles we need to check if
273 // we're actually at the correct cycle or we need to wait a little while
274 // more
275 int ticks;
276 ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
277 tc->getCpuPtr()->instCount();
278 assert(ticks >= 0 && "hstick compare missed interrupt cycle");
279
280 if (ticks == 0) {
281 DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
282 (stick_cmpr & mask(63)));
264 }
265 } else
266 sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
267}
268
269void
270MiscRegFile::processHSTickCompare(ThreadContext *tc)
271{
272 // since our microcode instructions take two cycles we need to check if
273 // we're actually at the correct cycle or we need to wait a little while
274 // more
275 int ticks;
276 ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
277 tc->getCpuPtr()->instCount();
278 assert(ticks >= 0 && "hstick compare missed interrupt cycle");
279
280 if (ticks == 0) {
281 DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
282 (stick_cmpr & mask(63)));
283 if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
284 setRegWithEffect(MISCREG_HINTP, 1, tc);
283 if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
284 setReg(MISCREG_HINTP, 1, tc);
285 }
286 // Need to do something to cause interrupt to happen here !!! @todo
287 } else
288 hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
289}
290
285 }
286 // Need to do something to cause interrupt to happen here !!! @todo
287 } else
288 hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
289}
290