]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ppc/ppc.c
target-arm: Fix warn about implicit conversion
[mirror_qemu.git] / hw / ppc / ppc.c
CommitLineData
a541f297 1/*
e9df014c 2 * QEMU generic PowerPC hardware System Emulator
5fafdf24 3 *
76a66253 4 * Copyright (c) 2003-2007 Jocelyn Mayer
5fafdf24 5 *
a541f297
FB
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 */
0d75590d 24#include "qemu/osdep.h"
4771d756
PB
25#include "qemu-common.h"
26#include "cpu.h"
83c9f4ca 27#include "hw/hw.h"
0d09e41a 28#include "hw/ppc/ppc.h"
2b927571 29#include "hw/ppc/ppc_e500.h"
1de7afc9 30#include "qemu/timer.h"
9c17d615 31#include "sysemu/sysemu.h"
0ce470cd 32#include "sysemu/cpus.h"
0d09e41a 33#include "hw/timer/m48t59.h"
1de7afc9 34#include "qemu/log.h"
98a8b524 35#include "qemu/error-report.h"
83c9f4ca 36#include "hw/loader.h"
9c17d615 37#include "sysemu/kvm.h"
fc87e185 38#include "kvm_ppc.h"
98a8b524 39#include "trace.h"
a541f297 40
e9df014c 41//#define PPC_DEBUG_IRQ
4b6d0a4c 42//#define PPC_DEBUG_TB
e9df014c 43
d12d51d5 44#ifdef PPC_DEBUG_IRQ
93fcfe39 45# define LOG_IRQ(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
d12d51d5
AL
46#else
47# define LOG_IRQ(...) do { } while (0)
48#endif
49
50
51#ifdef PPC_DEBUG_TB
93fcfe39 52# define LOG_TB(...) qemu_log(__VA_ARGS__)
d12d51d5
AL
53#else
54# define LOG_TB(...) do { } while (0)
55#endif
56
e2684c0b
AF
57static void cpu_ppc_tb_stop (CPUPPCState *env);
58static void cpu_ppc_tb_start (CPUPPCState *env);
dbdd2506 59
7058581a 60void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
47103572 61{
d8ed887b 62 CPUState *cs = CPU(cpu);
7058581a 63 CPUPPCState *env = &cpu->env;
fc87e185
AG
64 unsigned int old_pending = env->pending_interrupts;
65
47103572
JM
66 if (level) {
67 env->pending_interrupts |= 1 << n_IRQ;
c3affe56 68 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
47103572
JM
69 } else {
70 env->pending_interrupts &= ~(1 << n_IRQ);
d8ed887b
AF
71 if (env->pending_interrupts == 0) {
72 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
73 }
47103572 74 }
fc87e185
AG
75
76 if (old_pending != env->pending_interrupts) {
77#ifdef CONFIG_KVM
7058581a 78 kvmppc_set_interrupt(cpu, n_IRQ, level);
fc87e185
AG
79#endif
80 }
81
d12d51d5 82 LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32
aae9366a 83 "req %08x\n", __func__, env, n_IRQ, level,
259186a7 84 env->pending_interrupts, CPU(cpu)->interrupt_request);
47103572
JM
85}
86
e9df014c 87/* PowerPC 6xx / 7xx internal IRQ controller */
a0961245 88static void ppc6xx_set_irq(void *opaque, int pin, int level)
d537cf6c 89{
a0961245
AF
90 PowerPCCPU *cpu = opaque;
91 CPUPPCState *env = &cpu->env;
e9df014c 92 int cur_level;
d537cf6c 93
d12d51d5 94 LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
a496775f 95 env, pin, level);
e9df014c
JM
96 cur_level = (env->irq_input_state >> pin) & 1;
97 /* Don't generate spurious events */
24be5ae3 98 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
259186a7
AF
99 CPUState *cs = CPU(cpu);
100
e9df014c 101 switch (pin) {
dbdd2506
JM
102 case PPC6xx_INPUT_TBEN:
103 /* Level sensitive - active high */
d12d51d5 104 LOG_IRQ("%s: %s the time base\n",
dbdd2506 105 __func__, level ? "start" : "stop");
dbdd2506
JM
106 if (level) {
107 cpu_ppc_tb_start(env);
108 } else {
109 cpu_ppc_tb_stop(env);
110 }
24be5ae3
JM
111 case PPC6xx_INPUT_INT:
112 /* Level sensitive - active high */
d12d51d5 113 LOG_IRQ("%s: set the external IRQ state to %d\n",
a496775f 114 __func__, level);
7058581a 115 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
e9df014c 116 break;
24be5ae3 117 case PPC6xx_INPUT_SMI:
e9df014c 118 /* Level sensitive - active high */
d12d51d5 119 LOG_IRQ("%s: set the SMI IRQ state to %d\n",
a496775f 120 __func__, level);
7058581a 121 ppc_set_irq(cpu, PPC_INTERRUPT_SMI, level);
e9df014c 122 break;
24be5ae3 123 case PPC6xx_INPUT_MCP:
e9df014c
JM
124 /* Negative edge sensitive */
125 /* XXX: TODO: actual reaction may depends on HID0 status
126 * 603/604/740/750: check HID0[EMCP]
127 */
128 if (cur_level == 1 && level == 0) {
d12d51d5 129 LOG_IRQ("%s: raise machine check state\n",
a496775f 130 __func__);
7058581a 131 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1);
e9df014c
JM
132 }
133 break;
24be5ae3 134 case PPC6xx_INPUT_CKSTP_IN:
e9df014c
JM
135 /* Level sensitive - active low */
136 /* XXX: TODO: relay the signal to CKSTP_OUT pin */
e63ecc6f 137 /* XXX: Note that the only way to restart the CPU is to reset it */
e9df014c 138 if (level) {
d12d51d5 139 LOG_IRQ("%s: stop the CPU\n", __func__);
259186a7 140 cs->halted = 1;
e9df014c
JM
141 }
142 break;
24be5ae3 143 case PPC6xx_INPUT_HRESET:
e9df014c
JM
144 /* Level sensitive - active low */
145 if (level) {
d12d51d5 146 LOG_IRQ("%s: reset the CPU\n", __func__);
c3affe56 147 cpu_interrupt(cs, CPU_INTERRUPT_RESET);
e9df014c
JM
148 }
149 break;
24be5ae3 150 case PPC6xx_INPUT_SRESET:
d12d51d5 151 LOG_IRQ("%s: set the RESET IRQ state to %d\n",
a496775f 152 __func__, level);
7058581a 153 ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level);
e9df014c
JM
154 break;
155 default:
156 /* Unknown pin - do nothing */
d12d51d5 157 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
e9df014c
JM
158 return;
159 }
160 if (level)
161 env->irq_input_state |= 1 << pin;
162 else
163 env->irq_input_state &= ~(1 << pin);
d537cf6c
PB
164 }
165}
166
aa5a9e24 167void ppc6xx_irq_init(PowerPCCPU *cpu)
47103572 168{
aa5a9e24 169 CPUPPCState *env = &cpu->env;
a0961245
AF
170
171 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, cpu,
7b62a955 172 PPC6xx_INPUT_NB);
47103572
JM
173}
174
00af685f 175#if defined(TARGET_PPC64)
d0dfae6e 176/* PowerPC 970 internal IRQ controller */
a0961245 177static void ppc970_set_irq(void *opaque, int pin, int level)
d0dfae6e 178{
a0961245
AF
179 PowerPCCPU *cpu = opaque;
180 CPUPPCState *env = &cpu->env;
d0dfae6e
JM
181 int cur_level;
182
d12d51d5 183 LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
d0dfae6e 184 env, pin, level);
d0dfae6e
JM
185 cur_level = (env->irq_input_state >> pin) & 1;
186 /* Don't generate spurious events */
187 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
259186a7
AF
188 CPUState *cs = CPU(cpu);
189
d0dfae6e
JM
190 switch (pin) {
191 case PPC970_INPUT_INT:
192 /* Level sensitive - active high */
d12d51d5 193 LOG_IRQ("%s: set the external IRQ state to %d\n",
d0dfae6e 194 __func__, level);
7058581a 195 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
d0dfae6e
JM
196 break;
197 case PPC970_INPUT_THINT:
198 /* Level sensitive - active high */
d12d51d5 199 LOG_IRQ("%s: set the SMI IRQ state to %d\n", __func__,
d0dfae6e 200 level);
7058581a 201 ppc_set_irq(cpu, PPC_INTERRUPT_THERM, level);
d0dfae6e
JM
202 break;
203 case PPC970_INPUT_MCP:
204 /* Negative edge sensitive */
205 /* XXX: TODO: actual reaction may depends on HID0 status
206 * 603/604/740/750: check HID0[EMCP]
207 */
208 if (cur_level == 1 && level == 0) {
d12d51d5 209 LOG_IRQ("%s: raise machine check state\n",
d0dfae6e 210 __func__);
7058581a 211 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1);
d0dfae6e
JM
212 }
213 break;
214 case PPC970_INPUT_CKSTP:
215 /* Level sensitive - active low */
216 /* XXX: TODO: relay the signal to CKSTP_OUT pin */
217 if (level) {
d12d51d5 218 LOG_IRQ("%s: stop the CPU\n", __func__);
259186a7 219 cs->halted = 1;
d0dfae6e 220 } else {
d12d51d5 221 LOG_IRQ("%s: restart the CPU\n", __func__);
259186a7
AF
222 cs->halted = 0;
223 qemu_cpu_kick(cs);
d0dfae6e
JM
224 }
225 break;
226 case PPC970_INPUT_HRESET:
227 /* Level sensitive - active low */
228 if (level) {
c3affe56 229 cpu_interrupt(cs, CPU_INTERRUPT_RESET);
d0dfae6e
JM
230 }
231 break;
232 case PPC970_INPUT_SRESET:
d12d51d5 233 LOG_IRQ("%s: set the RESET IRQ state to %d\n",
d0dfae6e 234 __func__, level);
7058581a 235 ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level);
d0dfae6e
JM
236 break;
237 case PPC970_INPUT_TBEN:
d12d51d5 238 LOG_IRQ("%s: set the TBEN state to %d\n", __func__,
d0dfae6e 239 level);
d0dfae6e
JM
240 /* XXX: TODO */
241 break;
242 default:
243 /* Unknown pin - do nothing */
d12d51d5 244 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
d0dfae6e
JM
245 return;
246 }
247 if (level)
248 env->irq_input_state |= 1 << pin;
249 else
250 env->irq_input_state &= ~(1 << pin);
251 }
252}
253
aa5a9e24 254void ppc970_irq_init(PowerPCCPU *cpu)
d0dfae6e 255{
aa5a9e24 256 CPUPPCState *env = &cpu->env;
a0961245
AF
257
258 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, cpu,
7b62a955 259 PPC970_INPUT_NB);
d0dfae6e 260}
9d52e907
DG
261
262/* POWER7 internal IRQ controller */
a0961245 263static void power7_set_irq(void *opaque, int pin, int level)
9d52e907 264{
a0961245
AF
265 PowerPCCPU *cpu = opaque;
266 CPUPPCState *env = &cpu->env;
9d52e907
DG
267
268 LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
269 env, pin, level);
9d52e907
DG
270
271 switch (pin) {
272 case POWER7_INPUT_INT:
273 /* Level sensitive - active high */
274 LOG_IRQ("%s: set the external IRQ state to %d\n",
275 __func__, level);
7058581a 276 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
9d52e907
DG
277 break;
278 default:
279 /* Unknown pin - do nothing */
280 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
281 return;
282 }
283 if (level) {
284 env->irq_input_state |= 1 << pin;
285 } else {
286 env->irq_input_state &= ~(1 << pin);
287 }
288}
289
aa5a9e24 290void ppcPOWER7_irq_init(PowerPCCPU *cpu)
9d52e907 291{
aa5a9e24 292 CPUPPCState *env = &cpu->env;
a0961245
AF
293
294 env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu,
9d52e907
DG
295 POWER7_INPUT_NB);
296}
00af685f 297#endif /* defined(TARGET_PPC64) */
d0dfae6e 298
4e290a0b 299/* PowerPC 40x internal IRQ controller */
a0961245 300static void ppc40x_set_irq(void *opaque, int pin, int level)
24be5ae3 301{
a0961245
AF
302 PowerPCCPU *cpu = opaque;
303 CPUPPCState *env = &cpu->env;
24be5ae3
JM
304 int cur_level;
305
d12d51d5 306 LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
8ecc7913 307 env, pin, level);
24be5ae3
JM
308 cur_level = (env->irq_input_state >> pin) & 1;
309 /* Don't generate spurious events */
310 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
259186a7
AF
311 CPUState *cs = CPU(cpu);
312
24be5ae3 313 switch (pin) {
4e290a0b 314 case PPC40x_INPUT_RESET_SYS:
8ecc7913 315 if (level) {
d12d51d5 316 LOG_IRQ("%s: reset the PowerPC system\n",
8ecc7913 317 __func__);
f3273ba6 318 ppc40x_system_reset(cpu);
8ecc7913
JM
319 }
320 break;
4e290a0b 321 case PPC40x_INPUT_RESET_CHIP:
8ecc7913 322 if (level) {
d12d51d5 323 LOG_IRQ("%s: reset the PowerPC chip\n", __func__);
f3273ba6 324 ppc40x_chip_reset(cpu);
8ecc7913
JM
325 }
326 break;
4e290a0b 327 case PPC40x_INPUT_RESET_CORE:
24be5ae3
JM
328 /* XXX: TODO: update DBSR[MRR] */
329 if (level) {
d12d51d5 330 LOG_IRQ("%s: reset the PowerPC core\n", __func__);
f3273ba6 331 ppc40x_core_reset(cpu);
24be5ae3
JM
332 }
333 break;
4e290a0b 334 case PPC40x_INPUT_CINT:
24be5ae3 335 /* Level sensitive - active high */
d12d51d5 336 LOG_IRQ("%s: set the critical IRQ state to %d\n",
8ecc7913 337 __func__, level);
7058581a 338 ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level);
24be5ae3 339 break;
4e290a0b 340 case PPC40x_INPUT_INT:
24be5ae3 341 /* Level sensitive - active high */
d12d51d5 342 LOG_IRQ("%s: set the external IRQ state to %d\n",
a496775f 343 __func__, level);
7058581a 344 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
24be5ae3 345 break;
4e290a0b 346 case PPC40x_INPUT_HALT:
24be5ae3
JM
347 /* Level sensitive - active low */
348 if (level) {
d12d51d5 349 LOG_IRQ("%s: stop the CPU\n", __func__);
259186a7 350 cs->halted = 1;
24be5ae3 351 } else {
d12d51d5 352 LOG_IRQ("%s: restart the CPU\n", __func__);
259186a7
AF
353 cs->halted = 0;
354 qemu_cpu_kick(cs);
24be5ae3
JM
355 }
356 break;
4e290a0b 357 case PPC40x_INPUT_DEBUG:
24be5ae3 358 /* Level sensitive - active high */
d12d51d5 359 LOG_IRQ("%s: set the debug pin state to %d\n",
a496775f 360 __func__, level);
7058581a 361 ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level);
24be5ae3
JM
362 break;
363 default:
364 /* Unknown pin - do nothing */
d12d51d5 365 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
24be5ae3
JM
366 return;
367 }
368 if (level)
369 env->irq_input_state |= 1 << pin;
370 else
371 env->irq_input_state &= ~(1 << pin);
372 }
373}
374
aa5a9e24 375void ppc40x_irq_init(PowerPCCPU *cpu)
24be5ae3 376{
aa5a9e24 377 CPUPPCState *env = &cpu->env;
a0961245 378
4e290a0b 379 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
a0961245 380 cpu, PPC40x_INPUT_NB);
24be5ae3
JM
381}
382
9fdc60bf 383/* PowerPC E500 internal IRQ controller */
a0961245 384static void ppce500_set_irq(void *opaque, int pin, int level)
9fdc60bf 385{
a0961245
AF
386 PowerPCCPU *cpu = opaque;
387 CPUPPCState *env = &cpu->env;
9fdc60bf
AJ
388 int cur_level;
389
390 LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
391 env, pin, level);
392 cur_level = (env->irq_input_state >> pin) & 1;
393 /* Don't generate spurious events */
394 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
395 switch (pin) {
396 case PPCE500_INPUT_MCK:
397 if (level) {
398 LOG_IRQ("%s: reset the PowerPC system\n",
399 __func__);
400 qemu_system_reset_request();
401 }
402 break;
403 case PPCE500_INPUT_RESET_CORE:
404 if (level) {
405 LOG_IRQ("%s: reset the PowerPC core\n", __func__);
7058581a 406 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, level);
9fdc60bf
AJ
407 }
408 break;
409 case PPCE500_INPUT_CINT:
410 /* Level sensitive - active high */
411 LOG_IRQ("%s: set the critical IRQ state to %d\n",
412 __func__, level);
7058581a 413 ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level);
9fdc60bf
AJ
414 break;
415 case PPCE500_INPUT_INT:
416 /* Level sensitive - active high */
417 LOG_IRQ("%s: set the core IRQ state to %d\n",
418 __func__, level);
7058581a 419 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level);
9fdc60bf
AJ
420 break;
421 case PPCE500_INPUT_DEBUG:
422 /* Level sensitive - active high */
423 LOG_IRQ("%s: set the debug pin state to %d\n",
424 __func__, level);
7058581a 425 ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level);
9fdc60bf
AJ
426 break;
427 default:
428 /* Unknown pin - do nothing */
429 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
430 return;
431 }
432 if (level)
433 env->irq_input_state |= 1 << pin;
434 else
435 env->irq_input_state &= ~(1 << pin);
436 }
437}
438
aa5a9e24 439void ppce500_irq_init(PowerPCCPU *cpu)
9fdc60bf 440{
aa5a9e24 441 CPUPPCState *env = &cpu->env;
a0961245 442
9fdc60bf 443 env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
a0961245 444 cpu, PPCE500_INPUT_NB);
9fdc60bf 445}
e49798b1
AG
446
447/* Enable or Disable the E500 EPR capability */
448void ppce500_set_mpic_proxy(bool enabled)
449{
182735ef 450 CPUState *cs;
e49798b1 451
bdc44640 452 CPU_FOREACH(cs) {
182735ef 453 PowerPCCPU *cpu = POWERPC_CPU(cs);
5b95b8b9 454
182735ef 455 cpu->env.mpic_proxy = enabled;
5b95b8b9 456 if (kvm_enabled()) {
182735ef 457 kvmppc_set_mpic_proxy(cpu, enabled);
5b95b8b9 458 }
e49798b1
AG
459 }
460}
461
9fddaa0c 462/*****************************************************************************/
e9df014c 463/* PowerPC time base and decrementer emulation */
9fddaa0c 464
ddd1055b 465uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset)
9fddaa0c
FB
466{
467 /* TB time in tb periods */
73bcb24d 468 return muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND) + tb_offset;
9fddaa0c
FB
469}
470
e2684c0b 471uint64_t cpu_ppc_load_tbl (CPUPPCState *env)
9fddaa0c 472{
c227f099 473 ppc_tb_t *tb_env = env->tb_env;
9fddaa0c
FB
474 uint64_t tb;
475
90dc8812
SW
476 if (kvm_enabled()) {
477 return env->spr[SPR_TBL];
478 }
479
bc72ad67 480 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
d12d51d5 481 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
9fddaa0c 482
e3ea6529 483 return tb;
9fddaa0c
FB
484}
485
e2684c0b 486static inline uint32_t _cpu_ppc_load_tbu(CPUPPCState *env)
9fddaa0c 487{
c227f099 488 ppc_tb_t *tb_env = env->tb_env;
9fddaa0c
FB
489 uint64_t tb;
490
bc72ad67 491 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
d12d51d5 492 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
76a66253 493
9fddaa0c
FB
494 return tb >> 32;
495}
496
e2684c0b 497uint32_t cpu_ppc_load_tbu (CPUPPCState *env)
8a84de23 498{
90dc8812
SW
499 if (kvm_enabled()) {
500 return env->spr[SPR_TBU];
501 }
502
8a84de23
JM
503 return _cpu_ppc_load_tbu(env);
504}
505
c227f099 506static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk,
636aa200 507 int64_t *tb_offsetp, uint64_t value)
9fddaa0c 508{
73bcb24d
RS
509 *tb_offsetp = value -
510 muldiv64(vmclk, tb_env->tb_freq, NANOSECONDS_PER_SECOND);
511
d12d51d5 512 LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n",
aae9366a 513 __func__, value, *tb_offsetp);
9fddaa0c
FB
514}
515
e2684c0b 516void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value)
a062e36c 517{
c227f099 518 ppc_tb_t *tb_env = env->tb_env;
a062e36c
JM
519 uint64_t tb;
520
bc72ad67 521 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
a062e36c 522 tb &= 0xFFFFFFFF00000000ULL;
bc72ad67 523 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
dbdd2506 524 &tb_env->tb_offset, tb | (uint64_t)value);
a062e36c
JM
525}
526
e2684c0b 527static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value)
9fddaa0c 528{
c227f099 529 ppc_tb_t *tb_env = env->tb_env;
a062e36c 530 uint64_t tb;
9fddaa0c 531
bc72ad67 532 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
a062e36c 533 tb &= 0x00000000FFFFFFFFULL;
bc72ad67 534 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
dbdd2506 535 &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
9fddaa0c
FB
536}
537
e2684c0b 538void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value)
8a84de23
JM
539{
540 _cpu_ppc_store_tbu(env, value);
541}
542
e2684c0b 543uint64_t cpu_ppc_load_atbl (CPUPPCState *env)
a062e36c 544{
c227f099 545 ppc_tb_t *tb_env = env->tb_env;
a062e36c
JM
546 uint64_t tb;
547
bc72ad67 548 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
d12d51d5 549 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
a062e36c 550
b711de95 551 return tb;
a062e36c
JM
552}
553
e2684c0b 554uint32_t cpu_ppc_load_atbu (CPUPPCState *env)
a062e36c 555{
c227f099 556 ppc_tb_t *tb_env = env->tb_env;
a062e36c
JM
557 uint64_t tb;
558
bc72ad67 559 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
d12d51d5 560 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
a062e36c
JM
561
562 return tb >> 32;
563}
564
e2684c0b 565void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value)
a062e36c 566{
c227f099 567 ppc_tb_t *tb_env = env->tb_env;
a062e36c
JM
568 uint64_t tb;
569
bc72ad67 570 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
a062e36c 571 tb &= 0xFFFFFFFF00000000ULL;
bc72ad67 572 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
dbdd2506 573 &tb_env->atb_offset, tb | (uint64_t)value);
a062e36c
JM
574}
575
e2684c0b 576void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
9fddaa0c 577{
c227f099 578 ppc_tb_t *tb_env = env->tb_env;
a062e36c 579 uint64_t tb;
9fddaa0c 580
bc72ad67 581 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
a062e36c 582 tb &= 0x00000000FFFFFFFFULL;
bc72ad67 583 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
dbdd2506
JM
584 &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
585}
586
e2684c0b 587static void cpu_ppc_tb_stop (CPUPPCState *env)
dbdd2506 588{
c227f099 589 ppc_tb_t *tb_env = env->tb_env;
dbdd2506
JM
590 uint64_t tb, atb, vmclk;
591
592 /* If the time base is already frozen, do nothing */
593 if (tb_env->tb_freq != 0) {
bc72ad67 594 vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
dbdd2506
JM
595 /* Get the time base */
596 tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
597 /* Get the alternate time base */
598 atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
599 /* Store the time base value (ie compute the current offset) */
600 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
601 /* Store the alternate time base value (compute the current offset) */
602 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
603 /* Set the time base frequency to zero */
604 tb_env->tb_freq = 0;
605 /* Now, the time bases are frozen to tb_offset / atb_offset value */
606 }
607}
608
e2684c0b 609static void cpu_ppc_tb_start (CPUPPCState *env)
dbdd2506 610{
c227f099 611 ppc_tb_t *tb_env = env->tb_env;
dbdd2506 612 uint64_t tb, atb, vmclk;
aae9366a 613
dbdd2506
JM
614 /* If the time base is not frozen, do nothing */
615 if (tb_env->tb_freq == 0) {
bc72ad67 616 vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
dbdd2506
JM
617 /* Get the time base from tb_offset */
618 tb = tb_env->tb_offset;
619 /* Get the alternate time base from atb_offset */
620 atb = tb_env->atb_offset;
621 /* Restore the tb frequency from the decrementer frequency */
622 tb_env->tb_freq = tb_env->decr_freq;
623 /* Store the time base value */
624 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
625 /* Store the alternate time base value */
626 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
627 }
9fddaa0c
FB
628}
629
e81a982a
AG
630bool ppc_decr_clear_on_delivery(CPUPPCState *env)
631{
632 ppc_tb_t *tb_env = env->tb_env;
633 int flags = PPC_DECR_UNDERFLOW_TRIGGERED | PPC_DECR_UNDERFLOW_LEVEL;
634 return ((tb_env->flags & flags) == PPC_DECR_UNDERFLOW_TRIGGERED);
635}
636
e2684c0b 637static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
9fddaa0c 638{
c227f099 639 ppc_tb_t *tb_env = env->tb_env;
9fddaa0c 640 uint32_t decr;
4e588a4d 641 int64_t diff;
9fddaa0c 642
bc72ad67 643 diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ddd1055b 644 if (diff >= 0) {
73bcb24d 645 decr = muldiv64(diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND);
ddd1055b
FC
646 } else if (tb_env->flags & PPC_TIMER_BOOKE) {
647 decr = 0;
648 } else {
73bcb24d 649 decr = -muldiv64(-diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND);
ddd1055b 650 }
d12d51d5 651 LOG_TB("%s: %08" PRIx32 "\n", __func__, decr);
76a66253 652
9fddaa0c
FB
653 return decr;
654}
655
e2684c0b 656uint32_t cpu_ppc_load_decr (CPUPPCState *env)
58a7d328 657{
c227f099 658 ppc_tb_t *tb_env = env->tb_env;
58a7d328 659
90dc8812
SW
660 if (kvm_enabled()) {
661 return env->spr[SPR_DECR];
662 }
663
f55e9d9a 664 return _cpu_ppc_load_decr(env, tb_env->decr_next);
58a7d328
JM
665}
666
e2684c0b 667uint32_t cpu_ppc_load_hdecr (CPUPPCState *env)
58a7d328 668{
c227f099 669 ppc_tb_t *tb_env = env->tb_env;
58a7d328 670
f55e9d9a 671 return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
58a7d328
JM
672}
673
e2684c0b 674uint64_t cpu_ppc_load_purr (CPUPPCState *env)
58a7d328 675{
c227f099 676 ppc_tb_t *tb_env = env->tb_env;
58a7d328
JM
677 uint64_t diff;
678
bc72ad67 679 diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start;
b33c17e1 680
73bcb24d
RS
681 return tb_env->purr_load +
682 muldiv64(diff, tb_env->tb_freq, NANOSECONDS_PER_SECOND);
58a7d328 683}
58a7d328 684
9fddaa0c
FB
685/* When decrementer expires,
686 * all we need to do is generate or queue a CPU exception
687 */
7e0a9247 688static inline void cpu_ppc_decr_excp(PowerPCCPU *cpu)
9fddaa0c
FB
689{
690 /* Raise it */
d12d51d5 691 LOG_TB("raise decrementer exception\n");
7058581a 692 ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 1);
9fddaa0c
FB
693}
694
e81a982a
AG
695static inline void cpu_ppc_decr_lower(PowerPCCPU *cpu)
696{
697 ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 0);
698}
699
7e0a9247 700static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu)
58a7d328 701{
4b236b62
BH
702 CPUPPCState *env = &cpu->env;
703
58a7d328 704 /* Raise it */
4b236b62
BH
705 LOG_TB("raise hv decrementer exception\n");
706
707 /* The architecture specifies that we don't deliver HDEC
708 * interrupts in a PM state. Not only they don't cause a
709 * wakeup but they also get effectively discarded.
710 */
711 if (!env->in_pm_state) {
712 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1);
713 }
58a7d328
JM
714}
715
e81a982a
AG
716static inline void cpu_ppc_hdecr_lower(PowerPCCPU *cpu)
717{
718 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
719}
720
7e0a9247 721static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
1246b259 722 QEMUTimer *timer,
e81a982a
AG
723 void (*raise_excp)(void *),
724 void (*lower_excp)(PowerPCCPU *),
725 uint32_t decr, uint32_t value)
9fddaa0c 726{
7e0a9247 727 CPUPPCState *env = &cpu->env;
c227f099 728 ppc_tb_t *tb_env = env->tb_env;
9fddaa0c
FB
729 uint64_t now, next;
730
d12d51d5 731 LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
aae9366a 732 decr, value);
55f7d4b0
DG
733
734 if (kvm_enabled()) {
735 /* KVM handles decrementer exceptions, we don't need our own timer */
736 return;
737 }
738
e81a982a
AG
739 /*
740 * Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC
741 * interrupt.
742 *
743 * If we get a really small DEC value, we can assume that by the time we
744 * handled it we should inject an interrupt already.
745 *
746 * On MSB level based DEC implementations the MSB always means the interrupt
747 * is pending, so raise it on those.
748 *
749 * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers
750 * an edge interrupt, so raise it here too.
751 */
752 if ((value < 3) ||
753 ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && (value & 0x80000000)) ||
754 ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && (value & 0x80000000)
755 && !(decr & 0x80000000))) {
756 (*raise_excp)(cpu);
757 return;
ddd1055b 758 }
e81a982a
AG
759
760 /* On MSB level based systems a 0 for the MSB stops interrupt delivery */
761 if (!(value & 0x80000000) && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
762 (*lower_excp)(cpu);
ddd1055b 763 }
e81a982a
AG
764
765 /* Calculate the next timer event */
766 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
73bcb24d 767 next = now + muldiv64(value, NANOSECONDS_PER_SECOND, tb_env->decr_freq);
58a7d328 768 *nextp = next;
e81a982a 769
9fddaa0c 770 /* Adjust timer */
bc72ad67 771 timer_mod(timer, next);
58a7d328
JM
772}
773
7e0a9247 774static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr,
e81a982a 775 uint32_t value)
58a7d328 776{
7e0a9247 777 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328 778
7e0a9247 779 __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
e81a982a
AG
780 tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr,
781 value);
9fddaa0c
FB
782}
783
e2684c0b 784void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value)
9fddaa0c 785{
7e0a9247
AF
786 PowerPCCPU *cpu = ppc_env_get_cpu(env);
787
e81a982a 788 _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value);
9fddaa0c
FB
789}
790
50c680f0 791static void cpu_ppc_decr_cb(void *opaque)
9fddaa0c 792{
50c680f0 793 PowerPCCPU *cpu = opaque;
7e0a9247 794
e81a982a 795 cpu_ppc_decr_excp(cpu);
9fddaa0c
FB
796}
797
7e0a9247 798static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr,
e81a982a 799 uint32_t value)
58a7d328 800{
7e0a9247 801 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328 802
b172c56a 803 if (tb_env->hdecr_timer != NULL) {
7e0a9247 804 __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
e81a982a
AG
805 tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower,
806 hdecr, value);
b172c56a 807 }
58a7d328
JM
808}
809
e2684c0b 810void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)
58a7d328 811{
7e0a9247
AF
812 PowerPCCPU *cpu = ppc_env_get_cpu(env);
813
e81a982a 814 _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value);
58a7d328
JM
815}
816
50c680f0 817static void cpu_ppc_hdecr_cb(void *opaque)
58a7d328 818{
50c680f0 819 PowerPCCPU *cpu = opaque;
7e0a9247 820
e81a982a 821 cpu_ppc_hdecr_excp(cpu);
58a7d328
JM
822}
823
7e0a9247 824static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value)
58a7d328 825{
7e0a9247 826 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328
JM
827
828 tb_env->purr_load = value;
bc72ad67 829 tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
58a7d328 830}
58a7d328 831
8ecc7913
JM
832static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
833{
e2684c0b 834 CPUPPCState *env = opaque;
7e0a9247 835 PowerPCCPU *cpu = ppc_env_get_cpu(env);
c227f099 836 ppc_tb_t *tb_env = env->tb_env;
8ecc7913
JM
837
838 tb_env->tb_freq = freq;
dbdd2506 839 tb_env->decr_freq = freq;
8ecc7913
JM
840 /* There is a bug in Linux 2.4 kernels:
841 * if a decrementer exception is pending when it enables msr_ee at startup,
842 * it's not ready to handle it...
843 */
e81a982a
AG
844 _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
845 _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
7e0a9247 846 cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
8ecc7913
JM
847}
848
98a8b524
AK
849static void timebase_pre_save(void *opaque)
850{
851 PPCTimebase *tb = opaque;
4a7428c5 852 uint64_t ticks = cpu_get_host_ticks();
98a8b524
AK
853 PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
854
855 if (!first_ppc_cpu->env.tb_env) {
856 error_report("No timebase object");
857 return;
858 }
859
77bad151 860 tb->time_of_the_day_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
98a8b524
AK
861 /*
862 * tb_offset is only expected to be changed by migration so
863 * there is no need to update it from KVM here
864 */
865 tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset;
866}
867
868static int timebase_post_load(void *opaque, int version_id)
869{
870 PPCTimebase *tb_remote = opaque;
871 CPUState *cpu;
872 PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
873 int64_t tb_off_adj, tb_off, ns_diff;
874 int64_t migration_duration_ns, migration_duration_tb, guest_tb, host_ns;
875 unsigned long freq;
876
877 if (!first_ppc_cpu->env.tb_env) {
878 error_report("No timebase object");
879 return -1;
880 }
881
882 freq = first_ppc_cpu->env.tb_env->tb_freq;
883 /*
884 * Calculate timebase on the destination side of migration.
885 * The destination timebase must be not less than the source timebase.
886 * We try to adjust timebase by downtime if host clocks are not
887 * too much out of sync (1 second for now).
888 */
77bad151 889 host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
98a8b524 890 ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns);
13566fe3 891 migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff);
a2c5eaf7 892 migration_duration_tb = muldiv64(freq, migration_duration_ns,
13566fe3 893 NANOSECONDS_PER_SECOND);
98a8b524
AK
894 guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
895
4a7428c5 896 tb_off_adj = guest_tb - cpu_get_host_ticks();
98a8b524
AK
897
898 tb_off = first_ppc_cpu->env.tb_env->tb_offset;
899 trace_ppc_tb_adjust(tb_off, tb_off_adj, tb_off_adj - tb_off,
900 (tb_off_adj - tb_off) / freq);
901
902 /* Set new offset to all CPUs */
903 CPU_FOREACH(cpu) {
904 PowerPCCPU *pcpu = POWERPC_CPU(cpu);
905 pcpu->env.tb_env->tb_offset = tb_off_adj;
906 }
907
908 return 0;
909}
910
911const VMStateDescription vmstate_ppc_timebase = {
912 .name = "timebase",
913 .version_id = 1,
914 .minimum_version_id = 1,
915 .minimum_version_id_old = 1,
916 .pre_save = timebase_pre_save,
917 .post_load = timebase_post_load,
918 .fields = (VMStateField []) {
919 VMSTATE_UINT64(guest_timebase, PPCTimebase),
920 VMSTATE_INT64(time_of_the_day_ns, PPCTimebase),
921 VMSTATE_END_OF_LIST()
922 },
923};
924
9fddaa0c 925/* Set up (once) timebase frequency (in Hz) */
e2684c0b 926clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
9fddaa0c 927{
50c680f0 928 PowerPCCPU *cpu = ppc_env_get_cpu(env);
c227f099 929 ppc_tb_t *tb_env;
9fddaa0c 930
7267c094 931 tb_env = g_malloc0(sizeof(ppc_tb_t));
9fddaa0c 932 env->tb_env = tb_env;
ddd1055b 933 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
e81a982a
AG
934 if (env->insns_flags & PPC_SEGMENT_64B) {
935 /* All Book3S 64bit CPUs implement level based DEC logic */
936 tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL;
937 }
8ecc7913 938 /* Create new timer */
bc72ad67 939 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
4b236b62 940 if (env->has_hv_mode) {
bc72ad67 941 tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
50c680f0 942 cpu);
b172c56a
JM
943 } else {
944 tb_env->hdecr_timer = NULL;
945 }
8ecc7913 946 cpu_ppc_set_tb_clk(env, freq);
9fddaa0c 947
8ecc7913 948 return &cpu_ppc_set_tb_clk;
9fddaa0c
FB
949}
950
76a66253 951/* Specific helpers for POWER & PowerPC 601 RTC */
b1d8e52e 952#if 0
e2684c0b 953static clk_setup_cb cpu_ppc601_rtc_init (CPUPPCState *env)
76a66253
JM
954{
955 return cpu_ppc_tb_init(env, 7812500);
956}
b1d8e52e 957#endif
76a66253 958
e2684c0b 959void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value)
8a84de23
JM
960{
961 _cpu_ppc_store_tbu(env, value);
962}
76a66253 963
e2684c0b 964uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env)
8a84de23
JM
965{
966 return _cpu_ppc_load_tbu(env);
967}
76a66253 968
e2684c0b 969void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value)
76a66253
JM
970{
971 cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
972}
973
e2684c0b 974uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env)
76a66253
JM
975{
976 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
977}
978
636aaad7 979/*****************************************************************************/
ddd1055b 980/* PowerPC 40x timers */
636aaad7
JM
981
982/* PIT, FIT & WDT */
ddd1055b
FC
983typedef struct ppc40x_timer_t ppc40x_timer_t;
984struct ppc40x_timer_t {
636aaad7
JM
985 uint64_t pit_reload; /* PIT auto-reload value */
986 uint64_t fit_next; /* Tick for next FIT interrupt */
1246b259 987 QEMUTimer *fit_timer;
636aaad7 988 uint64_t wdt_next; /* Tick for next WDT interrupt */
1246b259 989 QEMUTimer *wdt_timer;
d63cb48d
EI
990
991 /* 405 have the PIT, 440 have a DECR. */
992 unsigned int decr_excp;
636aaad7 993};
3b46e624 994
636aaad7
JM
995/* Fixed interval timer */
996static void cpu_4xx_fit_cb (void *opaque)
997{
7058581a 998 PowerPCCPU *cpu;
e2684c0b 999 CPUPPCState *env;
c227f099 1000 ppc_tb_t *tb_env;
ddd1055b 1001 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1002 uint64_t now, next;
1003
1004 env = opaque;
7058581a 1005 cpu = ppc_env_get_cpu(env);
636aaad7 1006 tb_env = env->tb_env;
ddd1055b 1007 ppc40x_timer = tb_env->opaque;
bc72ad67 1008 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
636aaad7
JM
1009 switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
1010 case 0:
1011 next = 1 << 9;
1012 break;
1013 case 1:
1014 next = 1 << 13;
1015 break;
1016 case 2:
1017 next = 1 << 17;
1018 break;
1019 case 3:
1020 next = 1 << 21;
1021 break;
1022 default:
1023 /* Cannot occur, but makes gcc happy */
1024 return;
1025 }
73bcb24d 1026 next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->tb_freq);
636aaad7
JM
1027 if (next == now)
1028 next++;
bc72ad67 1029 timer_mod(ppc40x_timer->fit_timer, next);
636aaad7 1030 env->spr[SPR_40x_TSR] |= 1 << 26;
7058581a
AF
1031 if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) {
1032 ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1);
1033 }
90e189ec
BS
1034 LOG_TB("%s: ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
1035 (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
1036 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
636aaad7
JM
1037}
1038
1039/* Programmable interval timer */
e2684c0b 1040static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
76a66253 1041{
ddd1055b 1042 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1043 uint64_t now, next;
1044
ddd1055b
FC
1045 ppc40x_timer = tb_env->opaque;
1046 if (ppc40x_timer->pit_reload <= 1 ||
4b6d0a4c
JM
1047 !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
1048 (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
1049 /* Stop PIT */
d12d51d5 1050 LOG_TB("%s: stop PIT\n", __func__);
bc72ad67 1051 timer_del(tb_env->decr_timer);
4b6d0a4c 1052 } else {
d12d51d5 1053 LOG_TB("%s: start PIT %016" PRIx64 "\n",
ddd1055b 1054 __func__, ppc40x_timer->pit_reload);
bc72ad67 1055 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ddd1055b 1056 next = now + muldiv64(ppc40x_timer->pit_reload,
73bcb24d 1057 NANOSECONDS_PER_SECOND, tb_env->decr_freq);
4b6d0a4c
JM
1058 if (is_excp)
1059 next += tb_env->decr_next - now;
636aaad7
JM
1060 if (next == now)
1061 next++;
bc72ad67 1062 timer_mod(tb_env->decr_timer, next);
636aaad7
JM
1063 tb_env->decr_next = next;
1064 }
4b6d0a4c
JM
1065}
1066
1067static void cpu_4xx_pit_cb (void *opaque)
1068{
7058581a 1069 PowerPCCPU *cpu;
e2684c0b 1070 CPUPPCState *env;
c227f099 1071 ppc_tb_t *tb_env;
ddd1055b 1072 ppc40x_timer_t *ppc40x_timer;
4b6d0a4c
JM
1073
1074 env = opaque;
7058581a 1075 cpu = ppc_env_get_cpu(env);
4b6d0a4c 1076 tb_env = env->tb_env;
ddd1055b 1077 ppc40x_timer = tb_env->opaque;
636aaad7 1078 env->spr[SPR_40x_TSR] |= 1 << 27;
7058581a
AF
1079 if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) {
1080 ppc_set_irq(cpu, ppc40x_timer->decr_excp, 1);
1081 }
4b6d0a4c 1082 start_stop_pit(env, tb_env, 1);
90e189ec
BS
1083 LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
1084 "%016" PRIx64 "\n", __func__,
1085 (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
1086 (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
1087 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
ddd1055b 1088 ppc40x_timer->pit_reload);
636aaad7
JM
1089}
1090
1091/* Watchdog timer */
1092static void cpu_4xx_wdt_cb (void *opaque)
1093{
7058581a 1094 PowerPCCPU *cpu;
e2684c0b 1095 CPUPPCState *env;
c227f099 1096 ppc_tb_t *tb_env;
ddd1055b 1097 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1098 uint64_t now, next;
1099
1100 env = opaque;
7058581a 1101 cpu = ppc_env_get_cpu(env);
636aaad7 1102 tb_env = env->tb_env;
ddd1055b 1103 ppc40x_timer = tb_env->opaque;
bc72ad67 1104 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
636aaad7
JM
1105 switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
1106 case 0:
1107 next = 1 << 17;
1108 break;
1109 case 1:
1110 next = 1 << 21;
1111 break;
1112 case 2:
1113 next = 1 << 25;
1114 break;
1115 case 3:
1116 next = 1 << 29;
1117 break;
1118 default:
1119 /* Cannot occur, but makes gcc happy */
1120 return;
1121 }
73bcb24d 1122 next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->decr_freq);
636aaad7
JM
1123 if (next == now)
1124 next++;
90e189ec
BS
1125 LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
1126 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
636aaad7
JM
1127 switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
1128 case 0x0:
1129 case 0x1:
bc72ad67 1130 timer_mod(ppc40x_timer->wdt_timer, next);
ddd1055b 1131 ppc40x_timer->wdt_next = next;
a1f7f97b 1132 env->spr[SPR_40x_TSR] |= 1U << 31;
636aaad7
JM
1133 break;
1134 case 0x2:
bc72ad67 1135 timer_mod(ppc40x_timer->wdt_timer, next);
ddd1055b 1136 ppc40x_timer->wdt_next = next;
636aaad7 1137 env->spr[SPR_40x_TSR] |= 1 << 30;
7058581a
AF
1138 if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) {
1139 ppc_set_irq(cpu, PPC_INTERRUPT_WDT, 1);
1140 }
636aaad7
JM
1141 break;
1142 case 0x3:
1143 env->spr[SPR_40x_TSR] &= ~0x30000000;
1144 env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
1145 switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
1146 case 0x0:
1147 /* No reset */
1148 break;
1149 case 0x1: /* Core reset */
f3273ba6 1150 ppc40x_core_reset(cpu);
8ecc7913 1151 break;
636aaad7 1152 case 0x2: /* Chip reset */
f3273ba6 1153 ppc40x_chip_reset(cpu);
8ecc7913 1154 break;
636aaad7 1155 case 0x3: /* System reset */
f3273ba6 1156 ppc40x_system_reset(cpu);
8ecc7913 1157 break;
636aaad7
JM
1158 }
1159 }
76a66253
JM
1160}
1161
e2684c0b 1162void store_40x_pit (CPUPPCState *env, target_ulong val)
76a66253 1163{
c227f099 1164 ppc_tb_t *tb_env;
ddd1055b 1165 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1166
1167 tb_env = env->tb_env;
ddd1055b 1168 ppc40x_timer = tb_env->opaque;
90e189ec 1169 LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val);
ddd1055b 1170 ppc40x_timer->pit_reload = val;
4b6d0a4c 1171 start_stop_pit(env, tb_env, 0);
76a66253
JM
1172}
1173
e2684c0b 1174target_ulong load_40x_pit (CPUPPCState *env)
76a66253 1175{
636aaad7 1176 return cpu_ppc_load_decr(env);
76a66253
JM
1177}
1178
ddd1055b 1179static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
4b6d0a4c 1180{
e2684c0b 1181 CPUPPCState *env = opaque;
c227f099 1182 ppc_tb_t *tb_env = env->tb_env;
4b6d0a4c 1183
d12d51d5 1184 LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__,
aae9366a 1185 freq);
4b6d0a4c 1186 tb_env->tb_freq = freq;
dbdd2506 1187 tb_env->decr_freq = freq;
4b6d0a4c
JM
1188 /* XXX: we should also update all timers */
1189}
1190
e2684c0b 1191clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
d63cb48d 1192 unsigned int decr_excp)
636aaad7 1193{
c227f099 1194 ppc_tb_t *tb_env;
ddd1055b 1195 ppc40x_timer_t *ppc40x_timer;
636aaad7 1196
7267c094 1197 tb_env = g_malloc0(sizeof(ppc_tb_t));
8ecc7913 1198 env->tb_env = tb_env;
ddd1055b
FC
1199 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
1200 ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
8ecc7913 1201 tb_env->tb_freq = freq;
dbdd2506 1202 tb_env->decr_freq = freq;
ddd1055b 1203 tb_env->opaque = ppc40x_timer;
d12d51d5 1204 LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
ddd1055b 1205 if (ppc40x_timer != NULL) {
636aaad7 1206 /* We use decr timer for PIT */
bc72ad67 1207 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env);
ddd1055b 1208 ppc40x_timer->fit_timer =
bc72ad67 1209 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env);
ddd1055b 1210 ppc40x_timer->wdt_timer =
bc72ad67 1211 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env);
ddd1055b 1212 ppc40x_timer->decr_excp = decr_excp;
636aaad7 1213 }
8ecc7913 1214
ddd1055b 1215 return &ppc_40x_set_tb_clk;
76a66253
JM
1216}
1217
2e719ba3
JM
1218/*****************************************************************************/
1219/* Embedded PowerPC Device Control Registers */
c227f099
AL
1220typedef struct ppc_dcrn_t ppc_dcrn_t;
1221struct ppc_dcrn_t {
2e719ba3
JM
1222 dcr_read_cb dcr_read;
1223 dcr_write_cb dcr_write;
1224 void *opaque;
1225};
1226
a750fc0b
JM
1227/* XXX: on 460, DCR addresses are 32 bits wide,
1228 * using DCRIPR to get the 22 upper bits of the DCR address
1229 */
2e719ba3 1230#define DCRN_NB 1024
c227f099
AL
1231struct ppc_dcr_t {
1232 ppc_dcrn_t dcrn[DCRN_NB];
2e719ba3
JM
1233 int (*read_error)(int dcrn);
1234 int (*write_error)(int dcrn);
1235};
1236
73b01960 1237int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
2e719ba3 1238{
c227f099 1239 ppc_dcrn_t *dcr;
2e719ba3
JM
1240
1241 if (dcrn < 0 || dcrn >= DCRN_NB)
1242 goto error;
1243 dcr = &dcr_env->dcrn[dcrn];
1244 if (dcr->dcr_read == NULL)
1245 goto error;
1246 *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1247
1248 return 0;
1249
1250 error:
1251 if (dcr_env->read_error != NULL)
1252 return (*dcr_env->read_error)(dcrn);
1253
1254 return -1;
1255}
1256
73b01960 1257int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
2e719ba3 1258{
c227f099 1259 ppc_dcrn_t *dcr;
2e719ba3
JM
1260
1261 if (dcrn < 0 || dcrn >= DCRN_NB)
1262 goto error;
1263 dcr = &dcr_env->dcrn[dcrn];
1264 if (dcr->dcr_write == NULL)
1265 goto error;
1266 (*dcr->dcr_write)(dcr->opaque, dcrn, val);
1267
1268 return 0;
1269
1270 error:
1271 if (dcr_env->write_error != NULL)
1272 return (*dcr_env->write_error)(dcrn);
1273
1274 return -1;
1275}
1276
e2684c0b 1277int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque,
2e719ba3
JM
1278 dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1279{
c227f099
AL
1280 ppc_dcr_t *dcr_env;
1281 ppc_dcrn_t *dcr;
2e719ba3
JM
1282
1283 dcr_env = env->dcr_env;
1284 if (dcr_env == NULL)
1285 return -1;
1286 if (dcrn < 0 || dcrn >= DCRN_NB)
1287 return -1;
1288 dcr = &dcr_env->dcrn[dcrn];
1289 if (dcr->opaque != NULL ||
1290 dcr->dcr_read != NULL ||
1291 dcr->dcr_write != NULL)
1292 return -1;
1293 dcr->opaque = opaque;
1294 dcr->dcr_read = dcr_read;
1295 dcr->dcr_write = dcr_write;
1296
1297 return 0;
1298}
1299
e2684c0b 1300int ppc_dcr_init (CPUPPCState *env, int (*read_error)(int dcrn),
2e719ba3
JM
1301 int (*write_error)(int dcrn))
1302{
c227f099 1303 ppc_dcr_t *dcr_env;
2e719ba3 1304
7267c094 1305 dcr_env = g_malloc0(sizeof(ppc_dcr_t));
2e719ba3
JM
1306 dcr_env->read_error = read_error;
1307 dcr_env->write_error = write_error;
1308 env->dcr_env = dcr_env;
1309
1310 return 0;
1311}
1312
64201201
FB
1313/*****************************************************************************/
1314/* Debug port */
fd0bbb12 1315void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
64201201
FB
1316{
1317 addr &= 0xF;
1318 switch (addr) {
1319 case 0:
1320 printf("%c", val);
1321 break;
1322 case 1:
1323 printf("\n");
1324 fflush(stdout);
1325 break;
1326 case 2:
aae9366a 1327 printf("Set loglevel to %04" PRIx32 "\n", val);
24537a01 1328 qemu_set_log(val | 0x100);
64201201
FB
1329 break;
1330 }
1331}
1332
0ce470cd
AK
1333/* CPU device-tree ID helpers */
1334int ppc_get_vcpu_dt_id(PowerPCCPU *cpu)
1335{
1336 return cpu->cpu_dt_id;
1337}
1338
1339PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
1340{
1341 CPUState *cs;
1342
1343 CPU_FOREACH(cs) {
1344 PowerPCCPU *cpu = POWERPC_CPU(cs);
1345
1346 if (cpu->cpu_dt_id == cpu_dt_id) {
1347 return cpu;
1348 }
1349 }
1350
1351 return NULL;
1352}