Revision d12d51d5 hw/ppc.c
b/hw/ppc.c | ||
---|---|---|
31 | 31 |
//#define PPC_DEBUG_IRQ |
32 | 32 |
//#define PPC_DEBUG_TB |
33 | 33 |
|
34 |
#ifdef PPC_DEBUG_IRQ |
|
35 |
# define LOG_IRQ(...) do { \ |
|
36 |
if (loglevel & CPU_LOG_INT) \ |
|
37 |
fprintf(logfile, ## __VA_ARGS__); \ |
|
38 |
} while (0) |
|
39 |
#else |
|
40 |
# define LOG_IRQ(...) do { } while (0) |
|
41 |
#endif |
|
42 |
|
|
43 |
|
|
44 |
#ifdef PPC_DEBUG_TB |
|
45 |
# define LOG_TB(...) do { \ |
|
46 |
if (loglevel) \ |
|
47 |
fprintf(logfile, ## __VA_ARGS__); \ |
|
48 |
} while (0) |
|
49 |
#else |
|
50 |
# define LOG_TB(...) do { } while (0) |
|
51 |
#endif |
|
52 |
|
|
34 | 53 |
static void cpu_ppc_tb_stop (CPUState *env); |
35 | 54 |
static void cpu_ppc_tb_start (CPUState *env); |
36 | 55 |
|
... | ... | |
44 | 63 |
if (env->pending_interrupts == 0) |
45 | 64 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
46 | 65 |
} |
47 |
#if defined(PPC_DEBUG_IRQ) |
|
48 |
if (loglevel & CPU_LOG_INT) { |
|
49 |
fprintf(logfile, "%s: %p n_IRQ %d level %d => pending %08" PRIx32 |
|
66 |
LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32 |
|
50 | 67 |
"req %08x\n", __func__, env, n_IRQ, level, |
51 | 68 |
env->pending_interrupts, env->interrupt_request); |
52 |
} |
|
53 |
#endif |
|
54 | 69 |
} |
55 | 70 |
|
56 | 71 |
/* PowerPC 6xx / 7xx internal IRQ controller */ |
... | ... | |
59 | 74 |
CPUState *env = opaque; |
60 | 75 |
int cur_level; |
61 | 76 |
|
62 |
#if defined(PPC_DEBUG_IRQ) |
|
63 |
if (loglevel & CPU_LOG_INT) { |
|
64 |
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__, |
|
77 |
LOG_IRQ("%s: env %p pin %d level %d\n", __func__, |
|
65 | 78 |
env, pin, level); |
66 |
} |
|
67 |
#endif |
|
68 | 79 |
cur_level = (env->irq_input_state >> pin) & 1; |
69 | 80 |
/* Don't generate spurious events */ |
70 | 81 |
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
71 | 82 |
switch (pin) { |
72 | 83 |
case PPC6xx_INPUT_TBEN: |
73 | 84 |
/* Level sensitive - active high */ |
74 |
#if defined(PPC_DEBUG_IRQ) |
|
75 |
if (loglevel & CPU_LOG_INT) { |
|
76 |
fprintf(logfile, "%s: %s the time base\n", |
|
85 |
LOG_IRQ("%s: %s the time base\n", |
|
77 | 86 |
__func__, level ? "start" : "stop"); |
78 |
} |
|
79 |
#endif |
|
80 | 87 |
if (level) { |
81 | 88 |
cpu_ppc_tb_start(env); |
82 | 89 |
} else { |
... | ... | |
84 | 91 |
} |
85 | 92 |
case PPC6xx_INPUT_INT: |
86 | 93 |
/* Level sensitive - active high */ |
87 |
#if defined(PPC_DEBUG_IRQ) |
|
88 |
if (loglevel & CPU_LOG_INT) { |
|
89 |
fprintf(logfile, "%s: set the external IRQ state to %d\n", |
|
94 |
LOG_IRQ("%s: set the external IRQ state to %d\n", |
|
90 | 95 |
__func__, level); |
91 |
} |
|
92 |
#endif |
|
93 | 96 |
ppc_set_irq(env, PPC_INTERRUPT_EXT, level); |
94 | 97 |
break; |
95 | 98 |
case PPC6xx_INPUT_SMI: |
96 | 99 |
/* Level sensitive - active high */ |
97 |
#if defined(PPC_DEBUG_IRQ) |
|
98 |
if (loglevel & CPU_LOG_INT) { |
|
99 |
fprintf(logfile, "%s: set the SMI IRQ state to %d\n", |
|
100 |
LOG_IRQ("%s: set the SMI IRQ state to %d\n", |
|
100 | 101 |
__func__, level); |
101 |
} |
|
102 |
#endif |
|
103 | 102 |
ppc_set_irq(env, PPC_INTERRUPT_SMI, level); |
104 | 103 |
break; |
105 | 104 |
case PPC6xx_INPUT_MCP: |
... | ... | |
108 | 107 |
* 603/604/740/750: check HID0[EMCP] |
109 | 108 |
*/ |
110 | 109 |
if (cur_level == 1 && level == 0) { |
111 |
#if defined(PPC_DEBUG_IRQ) |
|
112 |
if (loglevel & CPU_LOG_INT) { |
|
113 |
fprintf(logfile, "%s: raise machine check state\n", |
|
110 |
LOG_IRQ("%s: raise machine check state\n", |
|
114 | 111 |
__func__); |
115 |
} |
|
116 |
#endif |
|
117 | 112 |
ppc_set_irq(env, PPC_INTERRUPT_MCK, 1); |
118 | 113 |
} |
119 | 114 |
break; |
... | ... | |
122 | 117 |
/* XXX: TODO: relay the signal to CKSTP_OUT pin */ |
123 | 118 |
/* XXX: Note that the only way to restart the CPU is to reset it */ |
124 | 119 |
if (level) { |
125 |
#if defined(PPC_DEBUG_IRQ) |
|
126 |
if (loglevel & CPU_LOG_INT) { |
|
127 |
fprintf(logfile, "%s: stop the CPU\n", __func__); |
|
128 |
} |
|
129 |
#endif |
|
120 |
LOG_IRQ("%s: stop the CPU\n", __func__); |
|
130 | 121 |
env->halted = 1; |
131 | 122 |
} |
132 | 123 |
break; |
133 | 124 |
case PPC6xx_INPUT_HRESET: |
134 | 125 |
/* Level sensitive - active low */ |
135 | 126 |
if (level) { |
136 |
#if defined(PPC_DEBUG_IRQ) |
|
137 |
if (loglevel & CPU_LOG_INT) { |
|
138 |
fprintf(logfile, "%s: reset the CPU\n", __func__); |
|
139 |
} |
|
140 |
#endif |
|
127 |
LOG_IRQ("%s: reset the CPU\n", __func__); |
|
141 | 128 |
env->interrupt_request |= CPU_INTERRUPT_EXITTB; |
142 | 129 |
/* XXX: TOFIX */ |
143 | 130 |
#if 0 |
... | ... | |
148 | 135 |
} |
149 | 136 |
break; |
150 | 137 |
case PPC6xx_INPUT_SRESET: |
151 |
#if defined(PPC_DEBUG_IRQ) |
|
152 |
if (loglevel & CPU_LOG_INT) { |
|
153 |
fprintf(logfile, "%s: set the RESET IRQ state to %d\n", |
|
138 |
LOG_IRQ("%s: set the RESET IRQ state to %d\n", |
|
154 | 139 |
__func__, level); |
155 |
} |
|
156 |
#endif |
|
157 | 140 |
ppc_set_irq(env, PPC_INTERRUPT_RESET, level); |
158 | 141 |
break; |
159 | 142 |
default: |
160 | 143 |
/* Unknown pin - do nothing */ |
161 |
#if defined(PPC_DEBUG_IRQ) |
|
162 |
if (loglevel & CPU_LOG_INT) { |
|
163 |
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin); |
|
164 |
} |
|
165 |
#endif |
|
144 |
LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); |
|
166 | 145 |
return; |
167 | 146 |
} |
168 | 147 |
if (level) |
... | ... | |
185 | 164 |
CPUState *env = opaque; |
186 | 165 |
int cur_level; |
187 | 166 |
|
188 |
#if defined(PPC_DEBUG_IRQ) |
|
189 |
if (loglevel & CPU_LOG_INT) { |
|
190 |
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__, |
|
167 |
LOG_IRQ("%s: env %p pin %d level %d\n", __func__, |
|
191 | 168 |
env, pin, level); |
192 |
} |
|
193 |
#endif |
|
194 | 169 |
cur_level = (env->irq_input_state >> pin) & 1; |
195 | 170 |
/* Don't generate spurious events */ |
196 | 171 |
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
197 | 172 |
switch (pin) { |
198 | 173 |
case PPC970_INPUT_INT: |
199 | 174 |
/* Level sensitive - active high */ |
200 |
#if defined(PPC_DEBUG_IRQ) |
|
201 |
if (loglevel & CPU_LOG_INT) { |
|
202 |
fprintf(logfile, "%s: set the external IRQ state to %d\n", |
|
175 |
LOG_IRQ("%s: set the external IRQ state to %d\n", |
|
203 | 176 |
__func__, level); |
204 |
} |
|
205 |
#endif |
|
206 | 177 |
ppc_set_irq(env, PPC_INTERRUPT_EXT, level); |
207 | 178 |
break; |
208 | 179 |
case PPC970_INPUT_THINT: |
209 | 180 |
/* Level sensitive - active high */ |
210 |
#if defined(PPC_DEBUG_IRQ) |
|
211 |
if (loglevel & CPU_LOG_INT) { |
|
212 |
fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__, |
|
181 |
LOG_IRQ("%s: set the SMI IRQ state to %d\n", __func__, |
|
213 | 182 |
level); |
214 |
} |
|
215 |
#endif |
|
216 | 183 |
ppc_set_irq(env, PPC_INTERRUPT_THERM, level); |
217 | 184 |
break; |
218 | 185 |
case PPC970_INPUT_MCP: |
... | ... | |
221 | 188 |
* 603/604/740/750: check HID0[EMCP] |
222 | 189 |
*/ |
223 | 190 |
if (cur_level == 1 && level == 0) { |
224 |
#if defined(PPC_DEBUG_IRQ) |
|
225 |
if (loglevel & CPU_LOG_INT) { |
|
226 |
fprintf(logfile, "%s: raise machine check state\n", |
|
191 |
LOG_IRQ("%s: raise machine check state\n", |
|
227 | 192 |
__func__); |
228 |
} |
|
229 |
#endif |
|
230 | 193 |
ppc_set_irq(env, PPC_INTERRUPT_MCK, 1); |
231 | 194 |
} |
232 | 195 |
break; |
... | ... | |
234 | 197 |
/* Level sensitive - active low */ |
235 | 198 |
/* XXX: TODO: relay the signal to CKSTP_OUT pin */ |
236 | 199 |
if (level) { |
237 |
#if defined(PPC_DEBUG_IRQ) |
|
238 |
if (loglevel & CPU_LOG_INT) { |
|
239 |
fprintf(logfile, "%s: stop the CPU\n", __func__); |
|
240 |
} |
|
241 |
#endif |
|
200 |
LOG_IRQ("%s: stop the CPU\n", __func__); |
|
242 | 201 |
env->halted = 1; |
243 | 202 |
} else { |
244 |
#if defined(PPC_DEBUG_IRQ) |
|
245 |
if (loglevel & CPU_LOG_INT) { |
|
246 |
fprintf(logfile, "%s: restart the CPU\n", __func__); |
|
247 |
} |
|
248 |
#endif |
|
203 |
LOG_IRQ("%s: restart the CPU\n", __func__); |
|
249 | 204 |
env->halted = 0; |
250 | 205 |
} |
251 | 206 |
break; |
... | ... | |
253 | 208 |
/* Level sensitive - active low */ |
254 | 209 |
if (level) { |
255 | 210 |
#if 0 // XXX: TOFIX |
256 |
#if defined(PPC_DEBUG_IRQ) |
|
257 |
if (loglevel & CPU_LOG_INT) { |
|
258 |
fprintf(logfile, "%s: reset the CPU\n", __func__); |
|
259 |
} |
|
260 |
#endif |
|
211 |
LOG_IRQ("%s: reset the CPU\n", __func__); |
|
261 | 212 |
cpu_reset(env); |
262 | 213 |
#endif |
263 | 214 |
} |
264 | 215 |
break; |
265 | 216 |
case PPC970_INPUT_SRESET: |
266 |
#if defined(PPC_DEBUG_IRQ) |
|
267 |
if (loglevel & CPU_LOG_INT) { |
|
268 |
fprintf(logfile, "%s: set the RESET IRQ state to %d\n", |
|
217 |
LOG_IRQ("%s: set the RESET IRQ state to %d\n", |
|
269 | 218 |
__func__, level); |
270 |
} |
|
271 |
#endif |
|
272 | 219 |
ppc_set_irq(env, PPC_INTERRUPT_RESET, level); |
273 | 220 |
break; |
274 | 221 |
case PPC970_INPUT_TBEN: |
275 |
#if defined(PPC_DEBUG_IRQ) |
|
276 |
if (loglevel & CPU_LOG_INT) { |
|
277 |
fprintf(logfile, "%s: set the TBEN state to %d\n", __func__, |
|
222 |
LOG_IRQ("%s: set the TBEN state to %d\n", __func__, |
|
278 | 223 |
level); |
279 |
} |
|
280 |
#endif |
|
281 | 224 |
/* XXX: TODO */ |
282 | 225 |
break; |
283 | 226 |
default: |
284 | 227 |
/* Unknown pin - do nothing */ |
285 |
#if defined(PPC_DEBUG_IRQ) |
|
286 |
if (loglevel & CPU_LOG_INT) { |
|
287 |
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin); |
|
288 |
} |
|
289 |
#endif |
|
228 |
LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); |
|
290 | 229 |
return; |
291 | 230 |
} |
292 | 231 |
if (level) |
... | ... | |
309 | 248 |
CPUState *env = opaque; |
310 | 249 |
int cur_level; |
311 | 250 |
|
312 |
#if defined(PPC_DEBUG_IRQ) |
|
313 |
if (loglevel & CPU_LOG_INT) { |
|
314 |
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__, |
|
251 |
LOG_IRQ("%s: env %p pin %d level %d\n", __func__, |
|
315 | 252 |
env, pin, level); |
316 |
} |
|
317 |
#endif |
|
318 | 253 |
cur_level = (env->irq_input_state >> pin) & 1; |
319 | 254 |
/* Don't generate spurious events */ |
320 | 255 |
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
321 | 256 |
switch (pin) { |
322 | 257 |
case PPC40x_INPUT_RESET_SYS: |
323 | 258 |
if (level) { |
324 |
#if defined(PPC_DEBUG_IRQ) |
|
325 |
if (loglevel & CPU_LOG_INT) { |
|
326 |
fprintf(logfile, "%s: reset the PowerPC system\n", |
|
259 |
LOG_IRQ("%s: reset the PowerPC system\n", |
|
327 | 260 |
__func__); |
328 |
} |
|
329 |
#endif |
|
330 | 261 |
ppc40x_system_reset(env); |
331 | 262 |
} |
332 | 263 |
break; |
333 | 264 |
case PPC40x_INPUT_RESET_CHIP: |
334 | 265 |
if (level) { |
335 |
#if defined(PPC_DEBUG_IRQ) |
|
336 |
if (loglevel & CPU_LOG_INT) { |
|
337 |
fprintf(logfile, "%s: reset the PowerPC chip\n", __func__); |
|
338 |
} |
|
339 |
#endif |
|
266 |
LOG_IRQ("%s: reset the PowerPC chip\n", __func__); |
|
340 | 267 |
ppc40x_chip_reset(env); |
341 | 268 |
} |
342 | 269 |
break; |
343 | 270 |
case PPC40x_INPUT_RESET_CORE: |
344 | 271 |
/* XXX: TODO: update DBSR[MRR] */ |
345 | 272 |
if (level) { |
346 |
#if defined(PPC_DEBUG_IRQ) |
|
347 |
if (loglevel & CPU_LOG_INT) { |
|
348 |
fprintf(logfile, "%s: reset the PowerPC core\n", __func__); |
|
349 |
} |
|
350 |
#endif |
|
273 |
LOG_IRQ("%s: reset the PowerPC core\n", __func__); |
|
351 | 274 |
ppc40x_core_reset(env); |
352 | 275 |
} |
353 | 276 |
break; |
354 | 277 |
case PPC40x_INPUT_CINT: |
355 | 278 |
/* Level sensitive - active high */ |
356 |
#if defined(PPC_DEBUG_IRQ) |
|
357 |
if (loglevel & CPU_LOG_INT) { |
|
358 |
fprintf(logfile, "%s: set the critical IRQ state to %d\n", |
|
279 |
LOG_IRQ("%s: set the critical IRQ state to %d\n", |
|
359 | 280 |
__func__, level); |
360 |
} |
|
361 |
#endif |
|
362 | 281 |
ppc_set_irq(env, PPC_INTERRUPT_CEXT, level); |
363 | 282 |
break; |
364 | 283 |
case PPC40x_INPUT_INT: |
365 | 284 |
/* Level sensitive - active high */ |
366 |
#if defined(PPC_DEBUG_IRQ) |
|
367 |
if (loglevel & CPU_LOG_INT) { |
|
368 |
fprintf(logfile, "%s: set the external IRQ state to %d\n", |
|
285 |
LOG_IRQ("%s: set the external IRQ state to %d\n", |
|
369 | 286 |
__func__, level); |
370 |
} |
|
371 |
#endif |
|
372 | 287 |
ppc_set_irq(env, PPC_INTERRUPT_EXT, level); |
373 | 288 |
break; |
374 | 289 |
case PPC40x_INPUT_HALT: |
375 | 290 |
/* Level sensitive - active low */ |
376 | 291 |
if (level) { |
377 |
#if defined(PPC_DEBUG_IRQ) |
|
378 |
if (loglevel & CPU_LOG_INT) { |
|
379 |
fprintf(logfile, "%s: stop the CPU\n", __func__); |
|
380 |
} |
|
381 |
#endif |
|
292 |
LOG_IRQ("%s: stop the CPU\n", __func__); |
|
382 | 293 |
env->halted = 1; |
383 | 294 |
} else { |
384 |
#if defined(PPC_DEBUG_IRQ) |
|
385 |
if (loglevel & CPU_LOG_INT) { |
|
386 |
fprintf(logfile, "%s: restart the CPU\n", __func__); |
|
387 |
} |
|
388 |
#endif |
|
295 |
LOG_IRQ("%s: restart the CPU\n", __func__); |
|
389 | 296 |
env->halted = 0; |
390 | 297 |
} |
391 | 298 |
break; |
392 | 299 |
case PPC40x_INPUT_DEBUG: |
393 | 300 |
/* Level sensitive - active high */ |
394 |
#if defined(PPC_DEBUG_IRQ) |
|
395 |
if (loglevel & CPU_LOG_INT) { |
|
396 |
fprintf(logfile, "%s: set the debug pin state to %d\n", |
|
301 |
LOG_IRQ("%s: set the debug pin state to %d\n", |
|
397 | 302 |
__func__, level); |
398 |
} |
|
399 |
#endif |
|
400 | 303 |
ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level); |
401 | 304 |
break; |
402 | 305 |
default: |
403 | 306 |
/* Unknown pin - do nothing */ |
404 |
#if defined(PPC_DEBUG_IRQ) |
|
405 |
if (loglevel & CPU_LOG_INT) { |
|
406 |
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin); |
|
407 |
} |
|
408 |
#endif |
|
307 |
LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); |
|
409 | 308 |
return; |
410 | 309 |
} |
411 | 310 |
if (level) |
... | ... | |
453 | 352 |
uint64_t tb; |
454 | 353 |
|
455 | 354 |
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); |
456 |
#if defined(PPC_DEBUG_TB) |
|
457 |
if (loglevel != 0) { |
|
458 |
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb); |
|
459 |
} |
|
460 |
#endif |
|
355 |
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); |
|
461 | 356 |
|
462 | 357 |
return tb & 0xFFFFFFFF; |
463 | 358 |
} |
... | ... | |
468 | 363 |
uint64_t tb; |
469 | 364 |
|
470 | 365 |
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); |
471 |
#if defined(PPC_DEBUG_TB) |
|
472 |
if (loglevel != 0) { |
|
473 |
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb); |
|
474 |
} |
|
475 |
#endif |
|
366 |
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); |
|
476 | 367 |
|
477 | 368 |
return tb >> 32; |
478 | 369 |
} |
... | ... | |
487 | 378 |
uint64_t value) |
488 | 379 |
{ |
489 | 380 |
*tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec); |
490 |
#ifdef PPC_DEBUG_TB |
|
491 |
if (loglevel != 0) { |
|
492 |
fprintf(logfile, "%s: tb %016" PRIx64 " offset %08" PRIx64 "\n", |
|
381 |
LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n", |
|
493 | 382 |
__func__, value, *tb_offsetp); |
494 |
} |
|
495 |
#endif |
|
496 | 383 |
} |
497 | 384 |
|
498 | 385 |
void cpu_ppc_store_tbl (CPUState *env, uint32_t value) |
... | ... | |
528 | 415 |
uint64_t tb; |
529 | 416 |
|
530 | 417 |
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); |
531 |
#if defined(PPC_DEBUG_TB) |
|
532 |
if (loglevel != 0) { |
|
533 |
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb); |
|
534 |
} |
|
535 |
#endif |
|
418 |
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); |
|
536 | 419 |
|
537 | 420 |
return tb & 0xFFFFFFFF; |
538 | 421 |
} |
... | ... | |
543 | 426 |
uint64_t tb; |
544 | 427 |
|
545 | 428 |
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); |
546 |
#if defined(PPC_DEBUG_TB) |
|
547 |
if (loglevel != 0) { |
|
548 |
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb); |
|
549 |
} |
|
550 |
#endif |
|
429 |
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); |
|
551 | 430 |
|
552 | 431 |
return tb >> 32; |
553 | 432 |
} |
... | ... | |
629 | 508 |
decr = muldiv64(diff, tb_env->decr_freq, ticks_per_sec); |
630 | 509 |
else |
631 | 510 |
decr = -muldiv64(-diff, tb_env->decr_freq, ticks_per_sec); |
632 |
#if defined(PPC_DEBUG_TB) |
|
633 |
if (loglevel != 0) { |
|
634 |
fprintf(logfile, "%s: %08" PRIx32 "\n", __func__, decr); |
|
635 |
} |
|
636 |
#endif |
|
511 |
LOG_TB("%s: %08" PRIx32 "\n", __func__, decr); |
|
637 | 512 |
|
638 | 513 |
return decr; |
639 | 514 |
} |
... | ... | |
668 | 543 |
static always_inline void cpu_ppc_decr_excp (CPUState *env) |
669 | 544 |
{ |
670 | 545 |
/* Raise it */ |
671 |
#ifdef PPC_DEBUG_TB |
|
672 |
if (loglevel != 0) { |
|
673 |
fprintf(logfile, "raise decrementer exception\n"); |
|
674 |
} |
|
675 |
#endif |
|
546 |
LOG_TB("raise decrementer exception\n"); |
|
676 | 547 |
ppc_set_irq(env, PPC_INTERRUPT_DECR, 1); |
677 | 548 |
} |
678 | 549 |
|
679 | 550 |
static always_inline void cpu_ppc_hdecr_excp (CPUState *env) |
680 | 551 |
{ |
681 | 552 |
/* Raise it */ |
682 |
#ifdef PPC_DEBUG_TB |
|
683 |
if (loglevel != 0) { |
|
684 |
fprintf(logfile, "raise decrementer exception\n"); |
|
685 |
} |
|
686 |
#endif |
|
553 |
LOG_TB("raise decrementer exception\n"); |
|
687 | 554 |
ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1); |
688 | 555 |
} |
689 | 556 |
|
... | ... | |
696 | 563 |
ppc_tb_t *tb_env = env->tb_env; |
697 | 564 |
uint64_t now, next; |
698 | 565 |
|
699 |
#ifdef PPC_DEBUG_TB |
|
700 |
if (loglevel != 0) { |
|
701 |
fprintf(logfile, "%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__, |
|
566 |
LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__, |
|
702 | 567 |
decr, value); |
703 |
} |
|
704 |
#endif |
|
705 | 568 |
now = qemu_get_clock(vm_clock); |
706 | 569 |
next = now + muldiv64(value, ticks_per_sec, tb_env->decr_freq); |
707 | 570 |
if (is_excp) |
... | ... | |
882 | 745 |
env->spr[SPR_40x_TSR] |= 1 << 26; |
883 | 746 |
if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) |
884 | 747 |
ppc_set_irq(env, PPC_INTERRUPT_FIT, 1); |
885 |
#ifdef PPC_DEBUG_TB |
|
886 |
if (loglevel != 0) { |
|
887 |
fprintf(logfile, "%s: ir %d TCR " ADDRX " TSR " ADDRX "\n", __func__, |
|
748 |
LOG_TB("%s: ir %d TCR " ADDRX " TSR " ADDRX "\n", __func__, |
|
888 | 749 |
(int)((env->spr[SPR_40x_TCR] >> 23) & 0x1), |
889 | 750 |
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); |
890 |
} |
|
891 |
#endif |
|
892 | 751 |
} |
893 | 752 |
|
894 | 753 |
/* Programmable interval timer */ |
... | ... | |
902 | 761 |
!((env->spr[SPR_40x_TCR] >> 26) & 0x1) || |
903 | 762 |
(is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) { |
904 | 763 |
/* Stop PIT */ |
905 |
#ifdef PPC_DEBUG_TB |
|
906 |
if (loglevel != 0) { |
|
907 |
fprintf(logfile, "%s: stop PIT\n", __func__); |
|
908 |
} |
|
909 |
#endif |
|
764 |
LOG_TB("%s: stop PIT\n", __func__); |
|
910 | 765 |
qemu_del_timer(tb_env->decr_timer); |
911 | 766 |
} else { |
912 |
#ifdef PPC_DEBUG_TB |
|
913 |
if (loglevel != 0) { |
|
914 |
fprintf(logfile, "%s: start PIT %016" PRIx64 "\n", |
|
767 |
LOG_TB("%s: start PIT %016" PRIx64 "\n", |
|
915 | 768 |
__func__, ppcemb_timer->pit_reload); |
916 |
} |
|
917 |
#endif |
|
918 | 769 |
now = qemu_get_clock(vm_clock); |
919 | 770 |
next = now + muldiv64(ppcemb_timer->pit_reload, |
920 | 771 |
ticks_per_sec, tb_env->decr_freq); |
... | ... | |
940 | 791 |
if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) |
941 | 792 |
ppc_set_irq(env, PPC_INTERRUPT_PIT, 1); |
942 | 793 |
start_stop_pit(env, tb_env, 1); |
943 |
#ifdef PPC_DEBUG_TB |
|
944 |
if (loglevel != 0) { |
|
945 |
fprintf(logfile, "%s: ar %d ir %d TCR " ADDRX " TSR " ADDRX " " |
|
794 |
LOG_TB("%s: ar %d ir %d TCR " ADDRX " TSR " ADDRX " " |
|
946 | 795 |
"%016" PRIx64 "\n", __func__, |
947 | 796 |
(int)((env->spr[SPR_40x_TCR] >> 22) & 0x1), |
948 | 797 |
(int)((env->spr[SPR_40x_TCR] >> 26) & 0x1), |
949 | 798 |
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR], |
950 | 799 |
ppcemb_timer->pit_reload); |
951 |
} |
|
952 |
#endif |
|
953 | 800 |
} |
954 | 801 |
|
955 | 802 |
/* Watchdog timer */ |
... | ... | |
984 | 831 |
next = now + muldiv64(next, ticks_per_sec, tb_env->decr_freq); |
985 | 832 |
if (next == now) |
986 | 833 |
next++; |
987 |
#ifdef PPC_DEBUG_TB |
|
988 |
if (loglevel != 0) { |
|
989 |
fprintf(logfile, "%s: TCR " ADDRX " TSR " ADDRX "\n", __func__, |
|
834 |
LOG_TB("%s: TCR " ADDRX " TSR " ADDRX "\n", __func__, |
|
990 | 835 |
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); |
991 |
} |
|
992 |
#endif |
|
993 | 836 |
switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) { |
994 | 837 |
case 0x0: |
995 | 838 |
case 0x1: |
... | ... | |
1031 | 874 |
|
1032 | 875 |
tb_env = env->tb_env; |
1033 | 876 |
ppcemb_timer = tb_env->opaque; |
1034 |
#ifdef PPC_DEBUG_TB |
|
1035 |
if (loglevel != 0) { |
|
1036 |
fprintf(logfile, "%s val" ADDRX "\n", __func__, val); |
|
1037 |
} |
|
1038 |
#endif |
|
877 |
LOG_TB("%s val" ADDRX "\n", __func__, val); |
|
1039 | 878 |
ppcemb_timer->pit_reload = val; |
1040 | 879 |
start_stop_pit(env, tb_env, 0); |
1041 | 880 |
} |
... | ... | |
1047 | 886 |
|
1048 | 887 |
void store_booke_tsr (CPUState *env, target_ulong val) |
1049 | 888 |
{ |
1050 |
#ifdef PPC_DEBUG_TB |
|
1051 |
if (loglevel != 0) { |
|
1052 |
fprintf(logfile, "%s: val " ADDRX "\n", __func__, val); |
|
1053 |
} |
|
1054 |
#endif |
|
889 |
LOG_TB("%s: val " ADDRX "\n", __func__, val); |
|
1055 | 890 |
env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000); |
1056 | 891 |
if (val & 0x80000000) |
1057 | 892 |
ppc_set_irq(env, PPC_INTERRUPT_PIT, 0); |
... | ... | |
1062 | 897 |
ppc_tb_t *tb_env; |
1063 | 898 |
|
1064 | 899 |
tb_env = env->tb_env; |
1065 |
#ifdef PPC_DEBUG_TB |
|
1066 |
if (loglevel != 0) { |
|
1067 |
fprintf(logfile, "%s: val " ADDRX "\n", __func__, val); |
|
1068 |
} |
|
1069 |
#endif |
|
900 |
LOG_TB("%s: val " ADDRX "\n", __func__, val); |
|
1070 | 901 |
env->spr[SPR_40x_TCR] = val & 0xFFC00000; |
1071 | 902 |
start_stop_pit(env, tb_env, 1); |
1072 | 903 |
cpu_4xx_wdt_cb(env); |
... | ... | |
1077 | 908 |
CPUState *env = opaque; |
1078 | 909 |
ppc_tb_t *tb_env = env->tb_env; |
1079 | 910 |
|
1080 |
#ifdef PPC_DEBUG_TB |
|
1081 |
if (loglevel != 0) { |
|
1082 |
fprintf(logfile, "%s set new frequency to %" PRIu32 "\n", __func__, |
|
911 |
LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__, |
|
1083 | 912 |
freq); |
1084 |
} |
|
1085 |
#endif |
|
1086 | 913 |
tb_env->tb_freq = freq; |
1087 | 914 |
tb_env->decr_freq = freq; |
1088 | 915 |
/* XXX: we should also update all timers */ |
... | ... | |
1102 | 929 |
tb_env->tb_freq = freq; |
1103 | 930 |
tb_env->decr_freq = freq; |
1104 | 931 |
tb_env->opaque = ppcemb_timer; |
1105 |
#ifdef PPC_DEBUG_TB |
|
1106 |
if (loglevel != 0) { |
|
1107 |
fprintf(logfile, "%s freq %" PRIu32 "\n", __func__, freq); |
|
1108 |
} |
|
1109 |
#endif |
|
932 |
LOG_TB("%s freq %" PRIu32 "\n", __func__, freq); |
|
1110 | 933 |
if (ppcemb_timer != NULL) { |
1111 | 934 |
/* We use decr timer for PIT */ |
1112 | 935 |
tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env); |
Also available in: Unified diff