1 | /* |
2 | * QEMU generic PowerPC hardware System Emulator |
3 | * |
4 | * Copyright (c) 2003-2007 Jocelyn Mayer |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | * of this software and associated documentation files (the "Software"), to deal |
8 | * in the Software without restriction, including without limitation the rights |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | * copies of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
22 | * THE SOFTWARE. |
23 | */ |
24 | |
25 | #include "qemu/osdep.h" |
26 | #include "cpu.h" |
27 | #include "hw/irq.h" |
28 | #include "hw/ppc/ppc.h" |
29 | #include "hw/ppc/ppc_e500.h" |
30 | #include "qemu/timer.h" |
31 | #include "sysemu/cpus.h" |
32 | #include "qemu/log.h" |
33 | #include "qemu/main-loop.h" |
34 | #include "qemu/error-report.h" |
35 | #include "sysemu/kvm.h" |
36 | #include "sysemu/runstate.h" |
37 | #include "kvm_ppc.h" |
38 | #include "migration/vmstate.h" |
39 | #include "trace.h" |
40 | |
41 | //#define PPC_DEBUG_IRQ |
42 | //#define PPC_DEBUG_TB |
43 | |
44 | #ifdef PPC_DEBUG_IRQ |
45 | # define LOG_IRQ(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__) |
46 | #else |
47 | # define LOG_IRQ(...) do { } while (0) |
48 | #endif |
49 | |
50 | |
51 | #ifdef PPC_DEBUG_TB |
52 | # define LOG_TB(...) qemu_log(__VA_ARGS__) |
53 | #else |
54 | # define LOG_TB(...) do { } while (0) |
55 | #endif |
56 | |
57 | static void cpu_ppc_tb_stop (CPUPPCState *env); |
58 | static void cpu_ppc_tb_start (CPUPPCState *env); |
59 | |
60 | void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) |
61 | { |
62 | CPUState *cs = CPU(cpu); |
63 | CPUPPCState *env = &cpu->env; |
64 | unsigned int old_pending; |
65 | bool locked = false; |
66 | |
67 | /* We may already have the BQL if coming from the reset path */ |
68 | if (!qemu_mutex_iothread_locked()) { |
69 | locked = true; |
70 | qemu_mutex_lock_iothread(); |
71 | } |
72 | |
73 | old_pending = env->pending_interrupts; |
74 | |
75 | if (level) { |
76 | env->pending_interrupts |= 1 << n_IRQ; |
77 | cpu_interrupt(cs, CPU_INTERRUPT_HARD); |
78 | } else { |
79 | env->pending_interrupts &= ~(1 << n_IRQ); |
80 | if (env->pending_interrupts == 0) { |
81 | cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); |
82 | } |
83 | } |
84 | |
85 | if (old_pending != env->pending_interrupts) { |
86 | kvmppc_set_interrupt(cpu, n_IRQ, level); |
87 | } |
88 | |
89 | |
90 | LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32 |
91 | "req %08x\n" , __func__, env, n_IRQ, level, |
92 | env->pending_interrupts, CPU(cpu)->interrupt_request); |
93 | |
94 | if (locked) { |
95 | qemu_mutex_unlock_iothread(); |
96 | } |
97 | } |
98 | |
99 | /* PowerPC 6xx / 7xx internal IRQ controller */ |
100 | static void ppc6xx_set_irq(void *opaque, int pin, int level) |
101 | { |
102 | PowerPCCPU *cpu = opaque; |
103 | CPUPPCState *env = &cpu->env; |
104 | int cur_level; |
105 | |
106 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
107 | env, pin, level); |
108 | cur_level = (env->irq_input_state >> pin) & 1; |
109 | /* Don't generate spurious events */ |
110 | if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
111 | CPUState *cs = CPU(cpu); |
112 | |
113 | switch (pin) { |
114 | case PPC6xx_INPUT_TBEN: |
115 | /* Level sensitive - active high */ |
116 | LOG_IRQ("%s: %s the time base\n" , |
117 | __func__, level ? "start" : "stop" ); |
118 | if (level) { |
119 | cpu_ppc_tb_start(env); |
120 | } else { |
121 | cpu_ppc_tb_stop(env); |
122 | } |
123 | case PPC6xx_INPUT_INT: |
124 | /* Level sensitive - active high */ |
125 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
126 | __func__, level); |
127 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
128 | break; |
129 | case PPC6xx_INPUT_SMI: |
130 | /* Level sensitive - active high */ |
131 | LOG_IRQ("%s: set the SMI IRQ state to %d\n" , |
132 | __func__, level); |
133 | ppc_set_irq(cpu, PPC_INTERRUPT_SMI, level); |
134 | break; |
135 | case PPC6xx_INPUT_MCP: |
136 | /* Negative edge sensitive */ |
137 | /* XXX: TODO: actual reaction may depends on HID0 status |
138 | * 603/604/740/750: check HID0[EMCP] |
139 | */ |
140 | if (cur_level == 1 && level == 0) { |
141 | LOG_IRQ("%s: raise machine check state\n" , |
142 | __func__); |
143 | ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1); |
144 | } |
145 | break; |
146 | case PPC6xx_INPUT_CKSTP_IN: |
147 | /* Level sensitive - active low */ |
148 | /* XXX: TODO: relay the signal to CKSTP_OUT pin */ |
149 | /* XXX: Note that the only way to restart the CPU is to reset it */ |
150 | if (level) { |
151 | LOG_IRQ("%s: stop the CPU\n" , __func__); |
152 | cs->halted = 1; |
153 | } |
154 | break; |
155 | case PPC6xx_INPUT_HRESET: |
156 | /* Level sensitive - active low */ |
157 | if (level) { |
158 | LOG_IRQ("%s: reset the CPU\n" , __func__); |
159 | cpu_interrupt(cs, CPU_INTERRUPT_RESET); |
160 | } |
161 | break; |
162 | case PPC6xx_INPUT_SRESET: |
163 | LOG_IRQ("%s: set the RESET IRQ state to %d\n" , |
164 | __func__, level); |
165 | ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level); |
166 | break; |
167 | default: |
168 | /* Unknown pin - do nothing */ |
169 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
170 | return; |
171 | } |
172 | if (level) |
173 | env->irq_input_state |= 1 << pin; |
174 | else |
175 | env->irq_input_state &= ~(1 << pin); |
176 | } |
177 | } |
178 | |
179 | void ppc6xx_irq_init(PowerPCCPU *cpu) |
180 | { |
181 | CPUPPCState *env = &cpu->env; |
182 | |
183 | env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, cpu, |
184 | PPC6xx_INPUT_NB); |
185 | } |
186 | |
187 | #if defined(TARGET_PPC64) |
188 | /* PowerPC 970 internal IRQ controller */ |
189 | static void ppc970_set_irq(void *opaque, int pin, int level) |
190 | { |
191 | PowerPCCPU *cpu = opaque; |
192 | CPUPPCState *env = &cpu->env; |
193 | int cur_level; |
194 | |
195 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
196 | env, pin, level); |
197 | cur_level = (env->irq_input_state >> pin) & 1; |
198 | /* Don't generate spurious events */ |
199 | if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
200 | CPUState *cs = CPU(cpu); |
201 | |
202 | switch (pin) { |
203 | case PPC970_INPUT_INT: |
204 | /* Level sensitive - active high */ |
205 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
206 | __func__, level); |
207 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
208 | break; |
209 | case PPC970_INPUT_THINT: |
210 | /* Level sensitive - active high */ |
211 | LOG_IRQ("%s: set the SMI IRQ state to %d\n" , __func__, |
212 | level); |
213 | ppc_set_irq(cpu, PPC_INTERRUPT_THERM, level); |
214 | break; |
215 | case PPC970_INPUT_MCP: |
216 | /* Negative edge sensitive */ |
217 | /* XXX: TODO: actual reaction may depends on HID0 status |
218 | * 603/604/740/750: check HID0[EMCP] |
219 | */ |
220 | if (cur_level == 1 && level == 0) { |
221 | LOG_IRQ("%s: raise machine check state\n" , |
222 | __func__); |
223 | ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1); |
224 | } |
225 | break; |
226 | case PPC970_INPUT_CKSTP: |
227 | /* Level sensitive - active low */ |
228 | /* XXX: TODO: relay the signal to CKSTP_OUT pin */ |
229 | if (level) { |
230 | LOG_IRQ("%s: stop the CPU\n" , __func__); |
231 | cs->halted = 1; |
232 | } else { |
233 | LOG_IRQ("%s: restart the CPU\n" , __func__); |
234 | cs->halted = 0; |
235 | qemu_cpu_kick(cs); |
236 | } |
237 | break; |
238 | case PPC970_INPUT_HRESET: |
239 | /* Level sensitive - active low */ |
240 | if (level) { |
241 | cpu_interrupt(cs, CPU_INTERRUPT_RESET); |
242 | } |
243 | break; |
244 | case PPC970_INPUT_SRESET: |
245 | LOG_IRQ("%s: set the RESET IRQ state to %d\n" , |
246 | __func__, level); |
247 | ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level); |
248 | break; |
249 | case PPC970_INPUT_TBEN: |
250 | LOG_IRQ("%s: set the TBEN state to %d\n" , __func__, |
251 | level); |
252 | /* XXX: TODO */ |
253 | break; |
254 | default: |
255 | /* Unknown pin - do nothing */ |
256 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
257 | return; |
258 | } |
259 | if (level) |
260 | env->irq_input_state |= 1 << pin; |
261 | else |
262 | env->irq_input_state &= ~(1 << pin); |
263 | } |
264 | } |
265 | |
266 | void ppc970_irq_init(PowerPCCPU *cpu) |
267 | { |
268 | CPUPPCState *env = &cpu->env; |
269 | |
270 | env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, cpu, |
271 | PPC970_INPUT_NB); |
272 | } |
273 | |
274 | /* POWER7 internal IRQ controller */ |
275 | static void power7_set_irq(void *opaque, int pin, int level) |
276 | { |
277 | PowerPCCPU *cpu = opaque; |
278 | CPUPPCState *env = &cpu->env; |
279 | |
280 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
281 | env, pin, level); |
282 | |
283 | switch (pin) { |
284 | case POWER7_INPUT_INT: |
285 | /* Level sensitive - active high */ |
286 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
287 | __func__, level); |
288 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
289 | break; |
290 | default: |
291 | /* Unknown pin - do nothing */ |
292 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
293 | return; |
294 | } |
295 | if (level) { |
296 | env->irq_input_state |= 1 << pin; |
297 | } else { |
298 | env->irq_input_state &= ~(1 << pin); |
299 | } |
300 | } |
301 | |
302 | void ppcPOWER7_irq_init(PowerPCCPU *cpu) |
303 | { |
304 | CPUPPCState *env = &cpu->env; |
305 | |
306 | env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu, |
307 | POWER7_INPUT_NB); |
308 | } |
309 | |
310 | /* POWER9 internal IRQ controller */ |
311 | static void power9_set_irq(void *opaque, int pin, int level) |
312 | { |
313 | PowerPCCPU *cpu = opaque; |
314 | CPUPPCState *env = &cpu->env; |
315 | |
316 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
317 | env, pin, level); |
318 | |
319 | switch (pin) { |
320 | case POWER9_INPUT_INT: |
321 | /* Level sensitive - active high */ |
322 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
323 | __func__, level); |
324 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
325 | break; |
326 | case POWER9_INPUT_HINT: |
327 | /* Level sensitive - active high */ |
328 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
329 | __func__, level); |
330 | ppc_set_irq(cpu, PPC_INTERRUPT_HVIRT, level); |
331 | break; |
332 | default: |
333 | /* Unknown pin - do nothing */ |
334 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
335 | return; |
336 | } |
337 | if (level) { |
338 | env->irq_input_state |= 1 << pin; |
339 | } else { |
340 | env->irq_input_state &= ~(1 << pin); |
341 | } |
342 | } |
343 | |
344 | void ppcPOWER9_irq_init(PowerPCCPU *cpu) |
345 | { |
346 | CPUPPCState *env = &cpu->env; |
347 | |
348 | env->irq_inputs = (void **)qemu_allocate_irqs(&power9_set_irq, cpu, |
349 | POWER9_INPUT_NB); |
350 | } |
351 | #endif /* defined(TARGET_PPC64) */ |
352 | |
353 | void ppc40x_core_reset(PowerPCCPU *cpu) |
354 | { |
355 | CPUPPCState *env = &cpu->env; |
356 | target_ulong dbsr; |
357 | |
358 | qemu_log_mask(CPU_LOG_RESET, "Reset PowerPC core\n" ); |
359 | cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET); |
360 | dbsr = env->spr[SPR_40x_DBSR]; |
361 | dbsr &= ~0x00000300; |
362 | dbsr |= 0x00000100; |
363 | env->spr[SPR_40x_DBSR] = dbsr; |
364 | } |
365 | |
366 | void ppc40x_chip_reset(PowerPCCPU *cpu) |
367 | { |
368 | CPUPPCState *env = &cpu->env; |
369 | target_ulong dbsr; |
370 | |
371 | qemu_log_mask(CPU_LOG_RESET, "Reset PowerPC chip\n" ); |
372 | cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET); |
373 | /* XXX: TODO reset all internal peripherals */ |
374 | dbsr = env->spr[SPR_40x_DBSR]; |
375 | dbsr &= ~0x00000300; |
376 | dbsr |= 0x00000200; |
377 | env->spr[SPR_40x_DBSR] = dbsr; |
378 | } |
379 | |
380 | void ppc40x_system_reset(PowerPCCPU *cpu) |
381 | { |
382 | qemu_log_mask(CPU_LOG_RESET, "Reset PowerPC system\n" ); |
383 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
384 | } |
385 | |
386 | void store_40x_dbcr0(CPUPPCState *env, uint32_t val) |
387 | { |
388 | PowerPCCPU *cpu = env_archcpu(env); |
389 | |
390 | switch ((val >> 28) & 0x3) { |
391 | case 0x0: |
392 | /* No action */ |
393 | break; |
394 | case 0x1: |
395 | /* Core reset */ |
396 | ppc40x_core_reset(cpu); |
397 | break; |
398 | case 0x2: |
399 | /* Chip reset */ |
400 | ppc40x_chip_reset(cpu); |
401 | break; |
402 | case 0x3: |
403 | /* System reset */ |
404 | ppc40x_system_reset(cpu); |
405 | break; |
406 | } |
407 | } |
408 | |
409 | /* PowerPC 40x internal IRQ controller */ |
410 | static void ppc40x_set_irq(void *opaque, int pin, int level) |
411 | { |
412 | PowerPCCPU *cpu = opaque; |
413 | CPUPPCState *env = &cpu->env; |
414 | int cur_level; |
415 | |
416 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
417 | env, pin, level); |
418 | cur_level = (env->irq_input_state >> pin) & 1; |
419 | /* Don't generate spurious events */ |
420 | if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
421 | CPUState *cs = CPU(cpu); |
422 | |
423 | switch (pin) { |
424 | case PPC40x_INPUT_RESET_SYS: |
425 | if (level) { |
426 | LOG_IRQ("%s: reset the PowerPC system\n" , |
427 | __func__); |
428 | ppc40x_system_reset(cpu); |
429 | } |
430 | break; |
431 | case PPC40x_INPUT_RESET_CHIP: |
432 | if (level) { |
433 | LOG_IRQ("%s: reset the PowerPC chip\n" , __func__); |
434 | ppc40x_chip_reset(cpu); |
435 | } |
436 | break; |
437 | case PPC40x_INPUT_RESET_CORE: |
438 | /* XXX: TODO: update DBSR[MRR] */ |
439 | if (level) { |
440 | LOG_IRQ("%s: reset the PowerPC core\n" , __func__); |
441 | ppc40x_core_reset(cpu); |
442 | } |
443 | break; |
444 | case PPC40x_INPUT_CINT: |
445 | /* Level sensitive - active high */ |
446 | LOG_IRQ("%s: set the critical IRQ state to %d\n" , |
447 | __func__, level); |
448 | ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level); |
449 | break; |
450 | case PPC40x_INPUT_INT: |
451 | /* Level sensitive - active high */ |
452 | LOG_IRQ("%s: set the external IRQ state to %d\n" , |
453 | __func__, level); |
454 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
455 | break; |
456 | case PPC40x_INPUT_HALT: |
457 | /* Level sensitive - active low */ |
458 | if (level) { |
459 | LOG_IRQ("%s: stop the CPU\n" , __func__); |
460 | cs->halted = 1; |
461 | } else { |
462 | LOG_IRQ("%s: restart the CPU\n" , __func__); |
463 | cs->halted = 0; |
464 | qemu_cpu_kick(cs); |
465 | } |
466 | break; |
467 | case PPC40x_INPUT_DEBUG: |
468 | /* Level sensitive - active high */ |
469 | LOG_IRQ("%s: set the debug pin state to %d\n" , |
470 | __func__, level); |
471 | ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level); |
472 | break; |
473 | default: |
474 | /* Unknown pin - do nothing */ |
475 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
476 | return; |
477 | } |
478 | if (level) |
479 | env->irq_input_state |= 1 << pin; |
480 | else |
481 | env->irq_input_state &= ~(1 << pin); |
482 | } |
483 | } |
484 | |
485 | void ppc40x_irq_init(PowerPCCPU *cpu) |
486 | { |
487 | CPUPPCState *env = &cpu->env; |
488 | |
489 | env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq, |
490 | cpu, PPC40x_INPUT_NB); |
491 | } |
492 | |
493 | /* PowerPC E500 internal IRQ controller */ |
494 | static void ppce500_set_irq(void *opaque, int pin, int level) |
495 | { |
496 | PowerPCCPU *cpu = opaque; |
497 | CPUPPCState *env = &cpu->env; |
498 | int cur_level; |
499 | |
500 | LOG_IRQ("%s: env %p pin %d level %d\n" , __func__, |
501 | env, pin, level); |
502 | cur_level = (env->irq_input_state >> pin) & 1; |
503 | /* Don't generate spurious events */ |
504 | if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
505 | switch (pin) { |
506 | case PPCE500_INPUT_MCK: |
507 | if (level) { |
508 | LOG_IRQ("%s: reset the PowerPC system\n" , |
509 | __func__); |
510 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); |
511 | } |
512 | break; |
513 | case PPCE500_INPUT_RESET_CORE: |
514 | if (level) { |
515 | LOG_IRQ("%s: reset the PowerPC core\n" , __func__); |
516 | ppc_set_irq(cpu, PPC_INTERRUPT_MCK, level); |
517 | } |
518 | break; |
519 | case PPCE500_INPUT_CINT: |
520 | /* Level sensitive - active high */ |
521 | LOG_IRQ("%s: set the critical IRQ state to %d\n" , |
522 | __func__, level); |
523 | ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level); |
524 | break; |
525 | case PPCE500_INPUT_INT: |
526 | /* Level sensitive - active high */ |
527 | LOG_IRQ("%s: set the core IRQ state to %d\n" , |
528 | __func__, level); |
529 | ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); |
530 | break; |
531 | case PPCE500_INPUT_DEBUG: |
532 | /* Level sensitive - active high */ |
533 | LOG_IRQ("%s: set the debug pin state to %d\n" , |
534 | __func__, level); |
535 | ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level); |
536 | break; |
537 | default: |
538 | /* Unknown pin - do nothing */ |
539 | LOG_IRQ("%s: unknown IRQ pin %d\n" , __func__, pin); |
540 | return; |
541 | } |
542 | if (level) |
543 | env->irq_input_state |= 1 << pin; |
544 | else |
545 | env->irq_input_state &= ~(1 << pin); |
546 | } |
547 | } |
548 | |
549 | void ppce500_irq_init(PowerPCCPU *cpu) |
550 | { |
551 | CPUPPCState *env = &cpu->env; |
552 | |
553 | env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq, |
554 | cpu, PPCE500_INPUT_NB); |
555 | } |
556 | |
557 | /* Enable or Disable the E500 EPR capability */ |
558 | void ppce500_set_mpic_proxy(bool enabled) |
559 | { |
560 | CPUState *cs; |
561 | |
562 | CPU_FOREACH(cs) { |
563 | PowerPCCPU *cpu = POWERPC_CPU(cs); |
564 | |
565 | cpu->env.mpic_proxy = enabled; |
566 | if (kvm_enabled()) { |
567 | kvmppc_set_mpic_proxy(cpu, enabled); |
568 | } |
569 | } |
570 | } |
571 | |
572 | /*****************************************************************************/ |
573 | /* PowerPC time base and decrementer emulation */ |
574 | |
575 | uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset) |
576 | { |
577 | /* TB time in tb periods */ |
578 | return muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND) + tb_offset; |
579 | } |
580 | |
581 | uint64_t cpu_ppc_load_tbl (CPUPPCState *env) |
582 | { |
583 | ppc_tb_t *tb_env = env->tb_env; |
584 | uint64_t tb; |
585 | |
586 | if (kvm_enabled()) { |
587 | return env->spr[SPR_TBL]; |
588 | } |
589 | |
590 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); |
591 | LOG_TB("%s: tb %016" PRIx64 "\n" , __func__, tb); |
592 | |
593 | return tb; |
594 | } |
595 | |
596 | static inline uint32_t _cpu_ppc_load_tbu(CPUPPCState *env) |
597 | { |
598 | ppc_tb_t *tb_env = env->tb_env; |
599 | uint64_t tb; |
600 | |
601 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); |
602 | LOG_TB("%s: tb %016" PRIx64 "\n" , __func__, tb); |
603 | |
604 | return tb >> 32; |
605 | } |
606 | |
607 | uint32_t cpu_ppc_load_tbu (CPUPPCState *env) |
608 | { |
609 | if (kvm_enabled()) { |
610 | return env->spr[SPR_TBU]; |
611 | } |
612 | |
613 | return _cpu_ppc_load_tbu(env); |
614 | } |
615 | |
616 | static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk, |
617 | int64_t *tb_offsetp, uint64_t value) |
618 | { |
619 | *tb_offsetp = value - |
620 | muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND); |
621 | |
622 | LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n" , |
623 | __func__, value, *tb_offsetp); |
624 | } |
625 | |
626 | void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value) |
627 | { |
628 | ppc_tb_t *tb_env = env->tb_env; |
629 | uint64_t tb; |
630 | |
631 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); |
632 | tb &= 0xFFFFFFFF00000000ULL; |
633 | cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), |
634 | &tb_env->tb_offset, tb | (uint64_t)value); |
635 | } |
636 | |
637 | static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value) |
638 | { |
639 | ppc_tb_t *tb_env = env->tb_env; |
640 | uint64_t tb; |
641 | |
642 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); |
643 | tb &= 0x00000000FFFFFFFFULL; |
644 | cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), |
645 | &tb_env->tb_offset, ((uint64_t)value << 32) | tb); |
646 | } |
647 | |
648 | void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value) |
649 | { |
650 | _cpu_ppc_store_tbu(env, value); |
651 | } |
652 | |
653 | uint64_t cpu_ppc_load_atbl (CPUPPCState *env) |
654 | { |
655 | ppc_tb_t *tb_env = env->tb_env; |
656 | uint64_t tb; |
657 | |
658 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); |
659 | LOG_TB("%s: tb %016" PRIx64 "\n" , __func__, tb); |
660 | |
661 | return tb; |
662 | } |
663 | |
664 | uint32_t cpu_ppc_load_atbu (CPUPPCState *env) |
665 | { |
666 | ppc_tb_t *tb_env = env->tb_env; |
667 | uint64_t tb; |
668 | |
669 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); |
670 | LOG_TB("%s: tb %016" PRIx64 "\n" , __func__, tb); |
671 | |
672 | return tb >> 32; |
673 | } |
674 | |
675 | void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value) |
676 | { |
677 | ppc_tb_t *tb_env = env->tb_env; |
678 | uint64_t tb; |
679 | |
680 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); |
681 | tb &= 0xFFFFFFFF00000000ULL; |
682 | cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), |
683 | &tb_env->atb_offset, tb | (uint64_t)value); |
684 | } |
685 | |
686 | void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value) |
687 | { |
688 | ppc_tb_t *tb_env = env->tb_env; |
689 | uint64_t tb; |
690 | |
691 | tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); |
692 | tb &= 0x00000000FFFFFFFFULL; |
693 | cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), |
694 | &tb_env->atb_offset, ((uint64_t)value << 32) | tb); |
695 | } |
696 | |
697 | static void cpu_ppc_tb_stop (CPUPPCState *env) |
698 | { |
699 | ppc_tb_t *tb_env = env->tb_env; |
700 | uint64_t tb, atb, vmclk; |
701 | |
702 | /* If the time base is already frozen, do nothing */ |
703 | if (tb_env->tb_freq != 0) { |
704 | vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
705 | /* Get the time base */ |
706 | tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset); |
707 | /* Get the alternate time base */ |
708 | atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset); |
709 | /* Store the time base value (ie compute the current offset) */ |
710 | cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb); |
711 | /* Store the alternate time base value (compute the current offset) */ |
712 | cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb); |
713 | /* Set the time base frequency to zero */ |
714 | tb_env->tb_freq = 0; |
715 | /* Now, the time bases are frozen to tb_offset / atb_offset value */ |
716 | } |
717 | } |
718 | |
719 | static void cpu_ppc_tb_start (CPUPPCState *env) |
720 | { |
721 | ppc_tb_t *tb_env = env->tb_env; |
722 | uint64_t tb, atb, vmclk; |
723 | |
724 | /* If the time base is not frozen, do nothing */ |
725 | if (tb_env->tb_freq == 0) { |
726 | vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
727 | /* Get the time base from tb_offset */ |
728 | tb = tb_env->tb_offset; |
729 | /* Get the alternate time base from atb_offset */ |
730 | atb = tb_env->atb_offset; |
731 | /* Restore the tb frequency from the decrementer frequency */ |
732 | tb_env->tb_freq = tb_env->decr_freq; |
733 | /* Store the time base value */ |
734 | cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb); |
735 | /* Store the alternate time base value */ |
736 | cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb); |
737 | } |
738 | } |
739 | |
740 | bool ppc_decr_clear_on_delivery(CPUPPCState *env) |
741 | { |
742 | ppc_tb_t *tb_env = env->tb_env; |
743 | int flags = PPC_DECR_UNDERFLOW_TRIGGERED | PPC_DECR_UNDERFLOW_LEVEL; |
744 | return ((tb_env->flags & flags) == PPC_DECR_UNDERFLOW_TRIGGERED); |
745 | } |
746 | |
747 | static inline int64_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next) |
748 | { |
749 | ppc_tb_t *tb_env = env->tb_env; |
750 | int64_t decr, diff; |
751 | |
752 | diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
753 | if (diff >= 0) { |
754 | decr = muldiv64(diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND); |
755 | } else if (tb_env->flags & PPC_TIMER_BOOKE) { |
756 | decr = 0; |
757 | } else { |
758 | decr = -muldiv64(-diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND); |
759 | } |
760 | LOG_TB("%s: %016" PRIx64 "\n" , __func__, decr); |
761 | |
762 | return decr; |
763 | } |
764 | |
765 | target_ulong cpu_ppc_load_decr(CPUPPCState *env) |
766 | { |
767 | ppc_tb_t *tb_env = env->tb_env; |
768 | uint64_t decr; |
769 | |
770 | if (kvm_enabled()) { |
771 | return env->spr[SPR_DECR]; |
772 | } |
773 | |
774 | decr = _cpu_ppc_load_decr(env, tb_env->decr_next); |
775 | |
776 | /* |
777 | * If large decrementer is enabled then the decrementer is signed extened |
778 | * to 64 bits, otherwise it is a 32 bit value. |
779 | */ |
780 | if (env->spr[SPR_LPCR] & LPCR_LD) { |
781 | return decr; |
782 | } |
783 | return (uint32_t) decr; |
784 | } |
785 | |
786 | target_ulong cpu_ppc_load_hdecr(CPUPPCState *env) |
787 | { |
788 | PowerPCCPU *cpu = env_archcpu(env); |
789 | PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); |
790 | ppc_tb_t *tb_env = env->tb_env; |
791 | uint64_t hdecr; |
792 | |
793 | hdecr = _cpu_ppc_load_decr(env, tb_env->hdecr_next); |
794 | |
795 | /* |
796 | * If we have a large decrementer (POWER9 or later) then hdecr is sign |
797 | * extended to 64 bits, otherwise it is 32 bits. |
798 | */ |
799 | if (pcc->lrg_decr_bits > 32) { |
800 | return hdecr; |
801 | } |
802 | return (uint32_t) hdecr; |
803 | } |
804 | |
805 | uint64_t cpu_ppc_load_purr (CPUPPCState *env) |
806 | { |
807 | ppc_tb_t *tb_env = env->tb_env; |
808 | uint64_t diff; |
809 | |
810 | diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start; |
811 | |
812 | return tb_env->purr_load + |
813 | muldiv64(diff, tb_env->tb_freq, NANOSECONDS_PER_SECOND); |
814 | } |
815 | |
816 | /* When decrementer expires, |
817 | * all we need to do is generate or queue a CPU exception |
818 | */ |
819 | static inline void cpu_ppc_decr_excp(PowerPCCPU *cpu) |
820 | { |
821 | /* Raise it */ |
822 | LOG_TB("raise decrementer exception\n" ); |
823 | ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 1); |
824 | } |
825 | |
826 | static inline void cpu_ppc_decr_lower(PowerPCCPU *cpu) |
827 | { |
828 | ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 0); |
829 | } |
830 | |
831 | static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu) |
832 | { |
833 | CPUPPCState *env = &cpu->env; |
834 | |
835 | /* Raise it */ |
836 | LOG_TB("raise hv decrementer exception\n" ); |
837 | |
838 | /* The architecture specifies that we don't deliver HDEC |
839 | * interrupts in a PM state. Not only they don't cause a |
840 | * wakeup but they also get effectively discarded. |
841 | */ |
842 | if (!env->resume_as_sreset) { |
843 | ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1); |
844 | } |
845 | } |
846 | |
847 | static inline void cpu_ppc_hdecr_lower(PowerPCCPU *cpu) |
848 | { |
849 | ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0); |
850 | } |
851 | |
852 | static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, |
853 | QEMUTimer *timer, |
854 | void (*raise_excp)(void *), |
855 | void (*lower_excp)(PowerPCCPU *), |
856 | target_ulong decr, target_ulong value, |
857 | int nr_bits) |
858 | { |
859 | CPUPPCState *env = &cpu->env; |
860 | ppc_tb_t *tb_env = env->tb_env; |
861 | uint64_t now, next; |
862 | bool negative; |
863 | |
864 | /* Truncate value to decr_width and sign extend for simplicity */ |
865 | value &= ((1ULL << nr_bits) - 1); |
866 | negative = !!(value & (1ULL << (nr_bits - 1))); |
867 | if (negative) { |
868 | value |= (0xFFFFFFFFULL << nr_bits); |
869 | } |
870 | |
871 | LOG_TB("%s: " TARGET_FMT_lx " => " TARGET_FMT_lx "\n" , __func__, |
872 | decr, value); |
873 | |
874 | if (kvm_enabled()) { |
875 | /* KVM handles decrementer exceptions, we don't need our own timer */ |
876 | return; |
877 | } |
878 | |
879 | /* |
880 | * Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC |
881 | * interrupt. |
882 | * |
883 | * If we get a really small DEC value, we can assume that by the time we |
884 | * handled it we should inject an interrupt already. |
885 | * |
886 | * On MSB level based DEC implementations the MSB always means the interrupt |
887 | * is pending, so raise it on those. |
888 | * |
889 | * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers |
890 | * an edge interrupt, so raise it here too. |
891 | */ |
892 | if ((value < 3) || |
893 | ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && negative) || |
894 | ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && negative |
895 | && !(decr & (1ULL << (nr_bits - 1))))) { |
896 | (*raise_excp)(cpu); |
897 | return; |
898 | } |
899 | |
900 | /* On MSB level based systems a 0 for the MSB stops interrupt delivery */ |
901 | if (!negative && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) { |
902 | (*lower_excp)(cpu); |
903 | } |
904 | |
905 | /* Calculate the next timer event */ |
906 | now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
907 | next = now + muldiv64(value, NANOSECONDS_PER_SECOND, tb_env->decr_freq); |
908 | *nextp = next; |
909 | |
910 | /* Adjust timer */ |
911 | timer_mod(timer, next); |
912 | } |
913 | |
914 | static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr, |
915 | target_ulong value, int nr_bits) |
916 | { |
917 | ppc_tb_t *tb_env = cpu->env.tb_env; |
918 | |
919 | __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, |
920 | tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr, |
921 | value, nr_bits); |
922 | } |
923 | |
924 | void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value) |
925 | { |
926 | PowerPCCPU *cpu = env_archcpu(env); |
927 | PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); |
928 | int nr_bits = 32; |
929 | |
930 | if (env->spr[SPR_LPCR] & LPCR_LD) { |
931 | nr_bits = pcc->lrg_decr_bits; |
932 | } |
933 | |
934 | _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, nr_bits); |
935 | } |
936 | |
937 | static void cpu_ppc_decr_cb(void *opaque) |
938 | { |
939 | PowerPCCPU *cpu = opaque; |
940 | |
941 | cpu_ppc_decr_excp(cpu); |
942 | } |
943 | |
944 | static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr, |
945 | target_ulong value, int nr_bits) |
946 | { |
947 | ppc_tb_t *tb_env = cpu->env.tb_env; |
948 | |
949 | if (tb_env->hdecr_timer != NULL) { |
950 | __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, |
951 | tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower, |
952 | hdecr, value, nr_bits); |
953 | } |
954 | } |
955 | |
956 | void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value) |
957 | { |
958 | PowerPCCPU *cpu = env_archcpu(env); |
959 | PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); |
960 | |
961 | _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value, |
962 | pcc->lrg_decr_bits); |
963 | } |
964 | |
965 | static void cpu_ppc_hdecr_cb(void *opaque) |
966 | { |
967 | PowerPCCPU *cpu = opaque; |
968 | |
969 | cpu_ppc_hdecr_excp(cpu); |
970 | } |
971 | |
972 | static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value) |
973 | { |
974 | ppc_tb_t *tb_env = cpu->env.tb_env; |
975 | |
976 | tb_env->purr_load = value; |
977 | tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
978 | } |
979 | |
980 | static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) |
981 | { |
982 | CPUPPCState *env = opaque; |
983 | PowerPCCPU *cpu = env_archcpu(env); |
984 | ppc_tb_t *tb_env = env->tb_env; |
985 | |
986 | tb_env->tb_freq = freq; |
987 | tb_env->decr_freq = freq; |
988 | /* There is a bug in Linux 2.4 kernels: |
989 | * if a decrementer exception is pending when it enables msr_ee at startup, |
990 | * it's not ready to handle it... |
991 | */ |
992 | _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32); |
993 | _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32); |
994 | cpu_ppc_store_purr(cpu, 0x0000000000000000ULL); |
995 | } |
996 | |
997 | static void timebase_save(PPCTimebase *tb) |
998 | { |
999 | uint64_t ticks = cpu_get_host_ticks(); |
1000 | PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); |
1001 | |
1002 | if (!first_ppc_cpu->env.tb_env) { |
1003 | error_report("No timebase object" ); |
1004 | return; |
1005 | } |
1006 | |
1007 | /* not used anymore, we keep it for compatibility */ |
1008 | tb->time_of_the_day_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST); |
1009 | /* |
1010 | * tb_offset is only expected to be changed by QEMU so |
1011 | * there is no need to update it from KVM here |
1012 | */ |
1013 | tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset; |
1014 | |
1015 | tb->runstate_paused = runstate_check(RUN_STATE_PAUSED); |
1016 | } |
1017 | |
1018 | static void timebase_load(PPCTimebase *tb) |
1019 | { |
1020 | CPUState *cpu; |
1021 | PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); |
1022 | int64_t tb_off_adj, tb_off; |
1023 | unsigned long freq; |
1024 | |
1025 | if (!first_ppc_cpu->env.tb_env) { |
1026 | error_report("No timebase object" ); |
1027 | return; |
1028 | } |
1029 | |
1030 | freq = first_ppc_cpu->env.tb_env->tb_freq; |
1031 | |
1032 | tb_off_adj = tb->guest_timebase - cpu_get_host_ticks(); |
1033 | |
1034 | tb_off = first_ppc_cpu->env.tb_env->tb_offset; |
1035 | trace_ppc_tb_adjust(tb_off, tb_off_adj, tb_off_adj - tb_off, |
1036 | (tb_off_adj - tb_off) / freq); |
1037 | |
1038 | /* Set new offset to all CPUs */ |
1039 | CPU_FOREACH(cpu) { |
1040 | PowerPCCPU *pcpu = POWERPC_CPU(cpu); |
1041 | pcpu->env.tb_env->tb_offset = tb_off_adj; |
1042 | kvmppc_set_reg_tb_offset(pcpu, pcpu->env.tb_env->tb_offset); |
1043 | } |
1044 | } |
1045 | |
1046 | void cpu_ppc_clock_vm_state_change(void *opaque, int running, |
1047 | RunState state) |
1048 | { |
1049 | PPCTimebase *tb = opaque; |
1050 | |
1051 | if (running) { |
1052 | timebase_load(tb); |
1053 | } else { |
1054 | timebase_save(tb); |
1055 | } |
1056 | } |
1057 | |
1058 | /* |
1059 | * When migrating a running guest, read the clock just |
1060 | * before migration, so that the guest clock counts |
1061 | * during the events between: |
1062 | * |
1063 | * * vm_stop() |
1064 | * * |
1065 | * * pre_save() |
1066 | * |
1067 | * This reduces clock difference on migration from 5s |
1068 | * to 0.1s (when max_downtime == 5s), because sending the |
1069 | * final pages of memory (which happens between vm_stop() |
1070 | * and pre_save()) takes max_downtime. |
1071 | */ |
1072 | static int timebase_pre_save(void *opaque) |
1073 | { |
1074 | PPCTimebase *tb = opaque; |
1075 | |
1076 | /* guest_timebase won't be overridden in case of paused guest */ |
1077 | if (!tb->runstate_paused) { |
1078 | timebase_save(tb); |
1079 | } |
1080 | |
1081 | return 0; |
1082 | } |
1083 | |
1084 | const VMStateDescription vmstate_ppc_timebase = { |
1085 | .name = "timebase" , |
1086 | .version_id = 1, |
1087 | .minimum_version_id = 1, |
1088 | .minimum_version_id_old = 1, |
1089 | .pre_save = timebase_pre_save, |
1090 | .fields = (VMStateField []) { |
1091 | VMSTATE_UINT64(guest_timebase, PPCTimebase), |
1092 | VMSTATE_INT64(time_of_the_day_ns, PPCTimebase), |
1093 | VMSTATE_END_OF_LIST() |
1094 | }, |
1095 | }; |
1096 | |
1097 | /* Set up (once) timebase frequency (in Hz) */ |
1098 | clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq) |
1099 | { |
1100 | PowerPCCPU *cpu = env_archcpu(env); |
1101 | ppc_tb_t *tb_env; |
1102 | |
1103 | tb_env = g_malloc0(sizeof(ppc_tb_t)); |
1104 | env->tb_env = tb_env; |
1105 | tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; |
1106 | if (is_book3s_arch2x(env)) { |
1107 | /* All Book3S 64bit CPUs implement level based DEC logic */ |
1108 | tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL; |
1109 | } |
1110 | /* Create new timer */ |
1111 | tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu); |
1112 | if (env->has_hv_mode) { |
1113 | tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb, |
1114 | cpu); |
1115 | } else { |
1116 | tb_env->hdecr_timer = NULL; |
1117 | } |
1118 | cpu_ppc_set_tb_clk(env, freq); |
1119 | |
1120 | return &cpu_ppc_set_tb_clk; |
1121 | } |
1122 | |
1123 | /* Specific helpers for POWER & PowerPC 601 RTC */ |
1124 | void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value) |
1125 | { |
1126 | _cpu_ppc_store_tbu(env, value); |
1127 | } |
1128 | |
1129 | uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env) |
1130 | { |
1131 | return _cpu_ppc_load_tbu(env); |
1132 | } |
1133 | |
1134 | void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value) |
1135 | { |
1136 | cpu_ppc_store_tbl(env, value & 0x3FFFFF80); |
1137 | } |
1138 | |
1139 | uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env) |
1140 | { |
1141 | return cpu_ppc_load_tbl(env) & 0x3FFFFF80; |
1142 | } |
1143 | |
1144 | /*****************************************************************************/ |
1145 | /* PowerPC 40x timers */ |
1146 | |
1147 | /* PIT, FIT & WDT */ |
1148 | typedef struct ppc40x_timer_t ppc40x_timer_t; |
1149 | struct ppc40x_timer_t { |
1150 | uint64_t pit_reload; /* PIT auto-reload value */ |
1151 | uint64_t fit_next; /* Tick for next FIT interrupt */ |
1152 | QEMUTimer *fit_timer; |
1153 | uint64_t wdt_next; /* Tick for next WDT interrupt */ |
1154 | QEMUTimer *wdt_timer; |
1155 | |
1156 | /* 405 have the PIT, 440 have a DECR. */ |
1157 | unsigned int decr_excp; |
1158 | }; |
1159 | |
1160 | /* Fixed interval timer */ |
1161 | static void cpu_4xx_fit_cb (void *opaque) |
1162 | { |
1163 | PowerPCCPU *cpu; |
1164 | CPUPPCState *env; |
1165 | ppc_tb_t *tb_env; |
1166 | ppc40x_timer_t *ppc40x_timer; |
1167 | uint64_t now, next; |
1168 | |
1169 | env = opaque; |
1170 | cpu = env_archcpu(env); |
1171 | tb_env = env->tb_env; |
1172 | ppc40x_timer = tb_env->opaque; |
1173 | now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
1174 | switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) { |
1175 | case 0: |
1176 | next = 1 << 9; |
1177 | break; |
1178 | case 1: |
1179 | next = 1 << 13; |
1180 | break; |
1181 | case 2: |
1182 | next = 1 << 17; |
1183 | break; |
1184 | case 3: |
1185 | next = 1 << 21; |
1186 | break; |
1187 | default: |
1188 | /* Cannot occur, but makes gcc happy */ |
1189 | return; |
1190 | } |
1191 | next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->tb_freq); |
1192 | if (next == now) |
1193 | next++; |
1194 | timer_mod(ppc40x_timer->fit_timer, next); |
1195 | env->spr[SPR_40x_TSR] |= 1 << 26; |
1196 | if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) { |
1197 | ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1); |
1198 | } |
1199 | LOG_TB("%s: ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n" , __func__, |
1200 | (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1), |
1201 | env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); |
1202 | } |
1203 | |
1204 | /* Programmable interval timer */ |
1205 | static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp) |
1206 | { |
1207 | ppc40x_timer_t *ppc40x_timer; |
1208 | uint64_t now, next; |
1209 | |
1210 | ppc40x_timer = tb_env->opaque; |
1211 | if (ppc40x_timer->pit_reload <= 1 || |
1212 | !((env->spr[SPR_40x_TCR] >> 26) & 0x1) || |
1213 | (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) { |
1214 | /* Stop PIT */ |
1215 | LOG_TB("%s: stop PIT\n" , __func__); |
1216 | timer_del(tb_env->decr_timer); |
1217 | } else { |
1218 | LOG_TB("%s: start PIT %016" PRIx64 "\n" , |
1219 | __func__, ppc40x_timer->pit_reload); |
1220 | now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
1221 | next = now + muldiv64(ppc40x_timer->pit_reload, |
1222 | NANOSECONDS_PER_SECOND, tb_env->decr_freq); |
1223 | if (is_excp) |
1224 | next += tb_env->decr_next - now; |
1225 | if (next == now) |
1226 | next++; |
1227 | timer_mod(tb_env->decr_timer, next); |
1228 | tb_env->decr_next = next; |
1229 | } |
1230 | } |
1231 | |
1232 | static void cpu_4xx_pit_cb (void *opaque) |
1233 | { |
1234 | PowerPCCPU *cpu; |
1235 | CPUPPCState *env; |
1236 | ppc_tb_t *tb_env; |
1237 | ppc40x_timer_t *ppc40x_timer; |
1238 | |
1239 | env = opaque; |
1240 | cpu = env_archcpu(env); |
1241 | tb_env = env->tb_env; |
1242 | ppc40x_timer = tb_env->opaque; |
1243 | env->spr[SPR_40x_TSR] |= 1 << 27; |
1244 | if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) { |
1245 | ppc_set_irq(cpu, ppc40x_timer->decr_excp, 1); |
1246 | } |
1247 | start_stop_pit(env, tb_env, 1); |
1248 | LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " " |
1249 | "%016" PRIx64 "\n" , __func__, |
1250 | (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1), |
1251 | (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1), |
1252 | env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR], |
1253 | ppc40x_timer->pit_reload); |
1254 | } |
1255 | |
1256 | /* Watchdog timer */ |
1257 | static void cpu_4xx_wdt_cb (void *opaque) |
1258 | { |
1259 | PowerPCCPU *cpu; |
1260 | CPUPPCState *env; |
1261 | ppc_tb_t *tb_env; |
1262 | ppc40x_timer_t *ppc40x_timer; |
1263 | uint64_t now, next; |
1264 | |
1265 | env = opaque; |
1266 | cpu = env_archcpu(env); |
1267 | tb_env = env->tb_env; |
1268 | ppc40x_timer = tb_env->opaque; |
1269 | now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); |
1270 | switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) { |
1271 | case 0: |
1272 | next = 1 << 17; |
1273 | break; |
1274 | case 1: |
1275 | next = 1 << 21; |
1276 | break; |
1277 | case 2: |
1278 | next = 1 << 25; |
1279 | break; |
1280 | case 3: |
1281 | next = 1 << 29; |
1282 | break; |
1283 | default: |
1284 | /* Cannot occur, but makes gcc happy */ |
1285 | return; |
1286 | } |
1287 | next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->decr_freq); |
1288 | if (next == now) |
1289 | next++; |
1290 | LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n" , __func__, |
1291 | env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); |
1292 | switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) { |
1293 | case 0x0: |
1294 | case 0x1: |
1295 | timer_mod(ppc40x_timer->wdt_timer, next); |
1296 | ppc40x_timer->wdt_next = next; |
1297 | env->spr[SPR_40x_TSR] |= 1U << 31; |
1298 | break; |
1299 | case 0x2: |
1300 | timer_mod(ppc40x_timer->wdt_timer, next); |
1301 | ppc40x_timer->wdt_next = next; |
1302 | env->spr[SPR_40x_TSR] |= 1 << 30; |
1303 | if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) { |
1304 | ppc_set_irq(cpu, PPC_INTERRUPT_WDT, 1); |
1305 | } |
1306 | break; |
1307 | case 0x3: |
1308 | env->spr[SPR_40x_TSR] &= ~0x30000000; |
1309 | env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000; |
1310 | switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) { |
1311 | case 0x0: |
1312 | /* No reset */ |
1313 | break; |
1314 | case 0x1: /* Core reset */ |
1315 | ppc40x_core_reset(cpu); |
1316 | break; |
1317 | case 0x2: /* Chip reset */ |
1318 | ppc40x_chip_reset(cpu); |
1319 | break; |
1320 | case 0x3: /* System reset */ |
1321 | ppc40x_system_reset(cpu); |
1322 | break; |
1323 | } |
1324 | } |
1325 | } |
1326 | |
1327 | void store_40x_pit (CPUPPCState *env, target_ulong val) |
1328 | { |
1329 | ppc_tb_t *tb_env; |
1330 | ppc40x_timer_t *ppc40x_timer; |
1331 | |
1332 | tb_env = env->tb_env; |
1333 | ppc40x_timer = tb_env->opaque; |
1334 | LOG_TB("%s val" TARGET_FMT_lx "\n" , __func__, val); |
1335 | ppc40x_timer->pit_reload = val; |
1336 | start_stop_pit(env, tb_env, 0); |
1337 | } |
1338 | |
1339 | target_ulong load_40x_pit (CPUPPCState *env) |
1340 | { |
1341 | return cpu_ppc_load_decr(env); |
1342 | } |
1343 | |
1344 | static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq) |
1345 | { |
1346 | CPUPPCState *env = opaque; |
1347 | ppc_tb_t *tb_env = env->tb_env; |
1348 | |
1349 | LOG_TB("%s set new frequency to %" PRIu32 "\n" , __func__, |
1350 | freq); |
1351 | tb_env->tb_freq = freq; |
1352 | tb_env->decr_freq = freq; |
1353 | /* XXX: we should also update all timers */ |
1354 | } |
1355 | |
1356 | clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq, |
1357 | unsigned int decr_excp) |
1358 | { |
1359 | ppc_tb_t *tb_env; |
1360 | ppc40x_timer_t *ppc40x_timer; |
1361 | |
1362 | tb_env = g_malloc0(sizeof(ppc_tb_t)); |
1363 | env->tb_env = tb_env; |
1364 | tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; |
1365 | ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t)); |
1366 | tb_env->tb_freq = freq; |
1367 | tb_env->decr_freq = freq; |
1368 | tb_env->opaque = ppc40x_timer; |
1369 | LOG_TB("%s freq %" PRIu32 "\n" , __func__, freq); |
1370 | if (ppc40x_timer != NULL) { |
1371 | /* We use decr timer for PIT */ |
1372 | tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env); |
1373 | ppc40x_timer->fit_timer = |
1374 | timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env); |
1375 | ppc40x_timer->wdt_timer = |
1376 | timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env); |
1377 | ppc40x_timer->decr_excp = decr_excp; |
1378 | } |
1379 | |
1380 | return &ppc_40x_set_tb_clk; |
1381 | } |
1382 | |
1383 | /*****************************************************************************/ |
1384 | /* Embedded PowerPC Device Control Registers */ |
1385 | typedef struct ppc_dcrn_t ppc_dcrn_t; |
1386 | struct ppc_dcrn_t { |
1387 | dcr_read_cb dcr_read; |
1388 | dcr_write_cb dcr_write; |
1389 | void *opaque; |
1390 | }; |
1391 | |
1392 | /* XXX: on 460, DCR addresses are 32 bits wide, |
1393 | * using DCRIPR to get the 22 upper bits of the DCR address |
1394 | */ |
1395 | #define DCRN_NB 1024 |
1396 | struct ppc_dcr_t { |
1397 | ppc_dcrn_t dcrn[DCRN_NB]; |
1398 | int (*read_error)(int dcrn); |
1399 | int (*write_error)(int dcrn); |
1400 | }; |
1401 | |
1402 | int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp) |
1403 | { |
1404 | ppc_dcrn_t *dcr; |
1405 | |
1406 | if (dcrn < 0 || dcrn >= DCRN_NB) |
1407 | goto error; |
1408 | dcr = &dcr_env->dcrn[dcrn]; |
1409 | if (dcr->dcr_read == NULL) |
1410 | goto error; |
1411 | *valp = (*dcr->dcr_read)(dcr->opaque, dcrn); |
1412 | |
1413 | return 0; |
1414 | |
1415 | error: |
1416 | if (dcr_env->read_error != NULL) |
1417 | return (*dcr_env->read_error)(dcrn); |
1418 | |
1419 | return -1; |
1420 | } |
1421 | |
1422 | int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) |
1423 | { |
1424 | ppc_dcrn_t *dcr; |
1425 | |
1426 | if (dcrn < 0 || dcrn >= DCRN_NB) |
1427 | goto error; |
1428 | dcr = &dcr_env->dcrn[dcrn]; |
1429 | if (dcr->dcr_write == NULL) |
1430 | goto error; |
1431 | (*dcr->dcr_write)(dcr->opaque, dcrn, val); |
1432 | |
1433 | return 0; |
1434 | |
1435 | error: |
1436 | if (dcr_env->write_error != NULL) |
1437 | return (*dcr_env->write_error)(dcrn); |
1438 | |
1439 | return -1; |
1440 | } |
1441 | |
1442 | int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque, |
1443 | dcr_read_cb dcr_read, dcr_write_cb dcr_write) |
1444 | { |
1445 | ppc_dcr_t *dcr_env; |
1446 | ppc_dcrn_t *dcr; |
1447 | |
1448 | dcr_env = env->dcr_env; |
1449 | if (dcr_env == NULL) |
1450 | return -1; |
1451 | if (dcrn < 0 || dcrn >= DCRN_NB) |
1452 | return -1; |
1453 | dcr = &dcr_env->dcrn[dcrn]; |
1454 | if (dcr->opaque != NULL || |
1455 | dcr->dcr_read != NULL || |
1456 | dcr->dcr_write != NULL) |
1457 | return -1; |
1458 | dcr->opaque = opaque; |
1459 | dcr->dcr_read = dcr_read; |
1460 | dcr->dcr_write = dcr_write; |
1461 | |
1462 | return 0; |
1463 | } |
1464 | |
1465 | int ppc_dcr_init (CPUPPCState *env, int (*read_error)(int dcrn), |
1466 | int (*write_error)(int dcrn)) |
1467 | { |
1468 | ppc_dcr_t *dcr_env; |
1469 | |
1470 | dcr_env = g_malloc0(sizeof(ppc_dcr_t)); |
1471 | dcr_env->read_error = read_error; |
1472 | dcr_env->write_error = write_error; |
1473 | env->dcr_env = dcr_env; |
1474 | |
1475 | return 0; |
1476 | } |
1477 | |
1478 | /*****************************************************************************/ |
1479 | /* Debug port */ |
1480 | void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val) |
1481 | { |
1482 | addr &= 0xF; |
1483 | switch (addr) { |
1484 | case 0: |
1485 | printf("%c" , val); |
1486 | break; |
1487 | case 1: |
1488 | printf("\n" ); |
1489 | fflush(stdout); |
1490 | break; |
1491 | case 2: |
1492 | printf("Set loglevel to %04" PRIx32 "\n" , val); |
1493 | qemu_set_log(val | 0x100); |
1494 | break; |
1495 | } |
1496 | } |
1497 | |
1498 | PowerPCCPU *ppc_get_vcpu_by_pir(int pir) |
1499 | { |
1500 | CPUState *cs; |
1501 | |
1502 | CPU_FOREACH(cs) { |
1503 | PowerPCCPU *cpu = POWERPC_CPU(cs); |
1504 | CPUPPCState *env = &cpu->env; |
1505 | |
1506 | if (env->spr_cb[SPR_PIR].default_value == pir) { |
1507 | return cpu; |
1508 | } |
1509 | } |
1510 | |
1511 | return NULL; |
1512 | } |
1513 | |