]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ppc/ppc.c
Replaced get_tick_per_sec() by NANOSECONDS_PER_SECOND
[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
a0961245 167void ppc6xx_irq_init(CPUPPCState *env)
47103572 168{
a0961245
AF
169 PowerPCCPU *cpu = ppc_env_get_cpu(env);
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
a0961245 254void ppc970_irq_init(CPUPPCState *env)
d0dfae6e 255{
a0961245
AF
256 PowerPCCPU *cpu = ppc_env_get_cpu(env);
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
a0961245 290void ppcPOWER7_irq_init(CPUPPCState *env)
9d52e907 291{
a0961245
AF
292 PowerPCCPU *cpu = ppc_env_get_cpu(env);
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
a0961245 375void ppc40x_irq_init(CPUPPCState *env)
24be5ae3 376{
a0961245
AF
377 PowerPCCPU *cpu = ppc_env_get_cpu(env);
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
a0961245 439void ppce500_irq_init(CPUPPCState *env)
9fdc60bf 440{
a0961245
AF
441 PowerPCCPU *cpu = ppc_env_get_cpu(env);
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
JM
701{
702 /* Raise it */
d12d51d5 703 LOG_TB("raise decrementer exception\n");
7058581a 704 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1);
58a7d328
JM
705}
706
e81a982a
AG
707static inline void cpu_ppc_hdecr_lower(PowerPCCPU *cpu)
708{
709 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
710}
711
7e0a9247 712static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
1246b259 713 QEMUTimer *timer,
e81a982a
AG
714 void (*raise_excp)(void *),
715 void (*lower_excp)(PowerPCCPU *),
716 uint32_t decr, uint32_t value)
9fddaa0c 717{
7e0a9247 718 CPUPPCState *env = &cpu->env;
c227f099 719 ppc_tb_t *tb_env = env->tb_env;
9fddaa0c
FB
720 uint64_t now, next;
721
d12d51d5 722 LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
aae9366a 723 decr, value);
55f7d4b0
DG
724
725 if (kvm_enabled()) {
726 /* KVM handles decrementer exceptions, we don't need our own timer */
727 return;
728 }
729
e81a982a
AG
730 /*
731 * Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC
732 * interrupt.
733 *
734 * If we get a really small DEC value, we can assume that by the time we
735 * handled it we should inject an interrupt already.
736 *
737 * On MSB level based DEC implementations the MSB always means the interrupt
738 * is pending, so raise it on those.
739 *
740 * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers
741 * an edge interrupt, so raise it here too.
742 */
743 if ((value < 3) ||
744 ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && (value & 0x80000000)) ||
745 ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && (value & 0x80000000)
746 && !(decr & 0x80000000))) {
747 (*raise_excp)(cpu);
748 return;
ddd1055b 749 }
e81a982a
AG
750
751 /* On MSB level based systems a 0 for the MSB stops interrupt delivery */
752 if (!(value & 0x80000000) && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
753 (*lower_excp)(cpu);
ddd1055b 754 }
e81a982a
AG
755
756 /* Calculate the next timer event */
757 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
73bcb24d 758 next = now + muldiv64(value, NANOSECONDS_PER_SECOND, tb_env->decr_freq);
58a7d328 759 *nextp = next;
e81a982a 760
9fddaa0c 761 /* Adjust timer */
bc72ad67 762 timer_mod(timer, next);
58a7d328
JM
763}
764
7e0a9247 765static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr,
e81a982a 766 uint32_t value)
58a7d328 767{
7e0a9247 768 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328 769
7e0a9247 770 __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
e81a982a
AG
771 tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr,
772 value);
9fddaa0c
FB
773}
774
e2684c0b 775void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value)
9fddaa0c 776{
7e0a9247
AF
777 PowerPCCPU *cpu = ppc_env_get_cpu(env);
778
e81a982a 779 _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value);
9fddaa0c
FB
780}
781
50c680f0 782static void cpu_ppc_decr_cb(void *opaque)
9fddaa0c 783{
50c680f0 784 PowerPCCPU *cpu = opaque;
7e0a9247 785
e81a982a 786 cpu_ppc_decr_excp(cpu);
9fddaa0c
FB
787}
788
7e0a9247 789static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr,
e81a982a 790 uint32_t value)
58a7d328 791{
7e0a9247 792 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328 793
b172c56a 794 if (tb_env->hdecr_timer != NULL) {
7e0a9247 795 __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
e81a982a
AG
796 tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower,
797 hdecr, value);
b172c56a 798 }
58a7d328
JM
799}
800
e2684c0b 801void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)
58a7d328 802{
7e0a9247
AF
803 PowerPCCPU *cpu = ppc_env_get_cpu(env);
804
e81a982a 805 _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value);
58a7d328
JM
806}
807
50c680f0 808static void cpu_ppc_hdecr_cb(void *opaque)
58a7d328 809{
50c680f0 810 PowerPCCPU *cpu = opaque;
7e0a9247 811
e81a982a 812 cpu_ppc_hdecr_excp(cpu);
58a7d328
JM
813}
814
7e0a9247 815static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value)
58a7d328 816{
7e0a9247 817 ppc_tb_t *tb_env = cpu->env.tb_env;
58a7d328
JM
818
819 tb_env->purr_load = value;
bc72ad67 820 tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
58a7d328 821}
58a7d328 822
8ecc7913
JM
823static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
824{
e2684c0b 825 CPUPPCState *env = opaque;
7e0a9247 826 PowerPCCPU *cpu = ppc_env_get_cpu(env);
c227f099 827 ppc_tb_t *tb_env = env->tb_env;
8ecc7913
JM
828
829 tb_env->tb_freq = freq;
dbdd2506 830 tb_env->decr_freq = freq;
8ecc7913
JM
831 /* There is a bug in Linux 2.4 kernels:
832 * if a decrementer exception is pending when it enables msr_ee at startup,
833 * it's not ready to handle it...
834 */
e81a982a
AG
835 _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
836 _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
7e0a9247 837 cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
8ecc7913
JM
838}
839
98a8b524
AK
840static void timebase_pre_save(void *opaque)
841{
842 PPCTimebase *tb = opaque;
4a7428c5 843 uint64_t ticks = cpu_get_host_ticks();
98a8b524
AK
844 PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
845
846 if (!first_ppc_cpu->env.tb_env) {
847 error_report("No timebase object");
848 return;
849 }
850
77bad151 851 tb->time_of_the_day_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
98a8b524
AK
852 /*
853 * tb_offset is only expected to be changed by migration so
854 * there is no need to update it from KVM here
855 */
856 tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset;
857}
858
859static int timebase_post_load(void *opaque, int version_id)
860{
861 PPCTimebase *tb_remote = opaque;
862 CPUState *cpu;
863 PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
864 int64_t tb_off_adj, tb_off, ns_diff;
865 int64_t migration_duration_ns, migration_duration_tb, guest_tb, host_ns;
866 unsigned long freq;
867
868 if (!first_ppc_cpu->env.tb_env) {
869 error_report("No timebase object");
870 return -1;
871 }
872
873 freq = first_ppc_cpu->env.tb_env->tb_freq;
874 /*
875 * Calculate timebase on the destination side of migration.
876 * The destination timebase must be not less than the source timebase.
877 * We try to adjust timebase by downtime if host clocks are not
878 * too much out of sync (1 second for now).
879 */
77bad151 880 host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
98a8b524 881 ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns);
13566fe3
SH
882 migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff);
883 migration_duration_tb = muldiv64(migration_duration_ns, freq,
884 NANOSECONDS_PER_SECOND);
98a8b524
AK
885 guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
886
4a7428c5 887 tb_off_adj = guest_tb - cpu_get_host_ticks();
98a8b524
AK
888
889 tb_off = first_ppc_cpu->env.tb_env->tb_offset;
890 trace_ppc_tb_adjust(tb_off, tb_off_adj, tb_off_adj - tb_off,
891 (tb_off_adj - tb_off) / freq);
892
893 /* Set new offset to all CPUs */
894 CPU_FOREACH(cpu) {
895 PowerPCCPU *pcpu = POWERPC_CPU(cpu);
896 pcpu->env.tb_env->tb_offset = tb_off_adj;
897 }
898
899 return 0;
900}
901
902const VMStateDescription vmstate_ppc_timebase = {
903 .name = "timebase",
904 .version_id = 1,
905 .minimum_version_id = 1,
906 .minimum_version_id_old = 1,
907 .pre_save = timebase_pre_save,
908 .post_load = timebase_post_load,
909 .fields = (VMStateField []) {
910 VMSTATE_UINT64(guest_timebase, PPCTimebase),
911 VMSTATE_INT64(time_of_the_day_ns, PPCTimebase),
912 VMSTATE_END_OF_LIST()
913 },
914};
915
9fddaa0c 916/* Set up (once) timebase frequency (in Hz) */
e2684c0b 917clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
9fddaa0c 918{
50c680f0 919 PowerPCCPU *cpu = ppc_env_get_cpu(env);
c227f099 920 ppc_tb_t *tb_env;
9fddaa0c 921
7267c094 922 tb_env = g_malloc0(sizeof(ppc_tb_t));
9fddaa0c 923 env->tb_env = tb_env;
ddd1055b 924 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
e81a982a
AG
925 if (env->insns_flags & PPC_SEGMENT_64B) {
926 /* All Book3S 64bit CPUs implement level based DEC logic */
927 tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL;
928 }
8ecc7913 929 /* Create new timer */
bc72ad67 930 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
b172c56a
JM
931 if (0) {
932 /* XXX: find a suitable condition to enable the hypervisor decrementer
933 */
bc72ad67 934 tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
50c680f0 935 cpu);
b172c56a
JM
936 } else {
937 tb_env->hdecr_timer = NULL;
938 }
8ecc7913 939 cpu_ppc_set_tb_clk(env, freq);
9fddaa0c 940
8ecc7913 941 return &cpu_ppc_set_tb_clk;
9fddaa0c
FB
942}
943
76a66253 944/* Specific helpers for POWER & PowerPC 601 RTC */
b1d8e52e 945#if 0
e2684c0b 946static clk_setup_cb cpu_ppc601_rtc_init (CPUPPCState *env)
76a66253
JM
947{
948 return cpu_ppc_tb_init(env, 7812500);
949}
b1d8e52e 950#endif
76a66253 951
e2684c0b 952void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value)
8a84de23
JM
953{
954 _cpu_ppc_store_tbu(env, value);
955}
76a66253 956
e2684c0b 957uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env)
8a84de23
JM
958{
959 return _cpu_ppc_load_tbu(env);
960}
76a66253 961
e2684c0b 962void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value)
76a66253
JM
963{
964 cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
965}
966
e2684c0b 967uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env)
76a66253
JM
968{
969 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
970}
971
636aaad7 972/*****************************************************************************/
ddd1055b 973/* PowerPC 40x timers */
636aaad7
JM
974
975/* PIT, FIT & WDT */
ddd1055b
FC
976typedef struct ppc40x_timer_t ppc40x_timer_t;
977struct ppc40x_timer_t {
636aaad7
JM
978 uint64_t pit_reload; /* PIT auto-reload value */
979 uint64_t fit_next; /* Tick for next FIT interrupt */
1246b259 980 QEMUTimer *fit_timer;
636aaad7 981 uint64_t wdt_next; /* Tick for next WDT interrupt */
1246b259 982 QEMUTimer *wdt_timer;
d63cb48d
EI
983
984 /* 405 have the PIT, 440 have a DECR. */
985 unsigned int decr_excp;
636aaad7 986};
3b46e624 987
636aaad7
JM
988/* Fixed interval timer */
989static void cpu_4xx_fit_cb (void *opaque)
990{
7058581a 991 PowerPCCPU *cpu;
e2684c0b 992 CPUPPCState *env;
c227f099 993 ppc_tb_t *tb_env;
ddd1055b 994 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
995 uint64_t now, next;
996
997 env = opaque;
7058581a 998 cpu = ppc_env_get_cpu(env);
636aaad7 999 tb_env = env->tb_env;
ddd1055b 1000 ppc40x_timer = tb_env->opaque;
bc72ad67 1001 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
636aaad7
JM
1002 switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
1003 case 0:
1004 next = 1 << 9;
1005 break;
1006 case 1:
1007 next = 1 << 13;
1008 break;
1009 case 2:
1010 next = 1 << 17;
1011 break;
1012 case 3:
1013 next = 1 << 21;
1014 break;
1015 default:
1016 /* Cannot occur, but makes gcc happy */
1017 return;
1018 }
73bcb24d 1019 next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->tb_freq);
636aaad7
JM
1020 if (next == now)
1021 next++;
bc72ad67 1022 timer_mod(ppc40x_timer->fit_timer, next);
636aaad7 1023 env->spr[SPR_40x_TSR] |= 1 << 26;
7058581a
AF
1024 if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) {
1025 ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1);
1026 }
90e189ec
BS
1027 LOG_TB("%s: ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
1028 (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
1029 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
636aaad7
JM
1030}
1031
1032/* Programmable interval timer */
e2684c0b 1033static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
76a66253 1034{
ddd1055b 1035 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1036 uint64_t now, next;
1037
ddd1055b
FC
1038 ppc40x_timer = tb_env->opaque;
1039 if (ppc40x_timer->pit_reload <= 1 ||
4b6d0a4c
JM
1040 !((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
1041 (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
1042 /* Stop PIT */
d12d51d5 1043 LOG_TB("%s: stop PIT\n", __func__);
bc72ad67 1044 timer_del(tb_env->decr_timer);
4b6d0a4c 1045 } else {
d12d51d5 1046 LOG_TB("%s: start PIT %016" PRIx64 "\n",
ddd1055b 1047 __func__, ppc40x_timer->pit_reload);
bc72ad67 1048 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ddd1055b 1049 next = now + muldiv64(ppc40x_timer->pit_reload,
73bcb24d 1050 NANOSECONDS_PER_SECOND, tb_env->decr_freq);
4b6d0a4c
JM
1051 if (is_excp)
1052 next += tb_env->decr_next - now;
636aaad7
JM
1053 if (next == now)
1054 next++;
bc72ad67 1055 timer_mod(tb_env->decr_timer, next);
636aaad7
JM
1056 tb_env->decr_next = next;
1057 }
4b6d0a4c
JM
1058}
1059
1060static void cpu_4xx_pit_cb (void *opaque)
1061{
7058581a 1062 PowerPCCPU *cpu;
e2684c0b 1063 CPUPPCState *env;
c227f099 1064 ppc_tb_t *tb_env;
ddd1055b 1065 ppc40x_timer_t *ppc40x_timer;
4b6d0a4c
JM
1066
1067 env = opaque;
7058581a 1068 cpu = ppc_env_get_cpu(env);
4b6d0a4c 1069 tb_env = env->tb_env;
ddd1055b 1070 ppc40x_timer = tb_env->opaque;
636aaad7 1071 env->spr[SPR_40x_TSR] |= 1 << 27;
7058581a
AF
1072 if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) {
1073 ppc_set_irq(cpu, ppc40x_timer->decr_excp, 1);
1074 }
4b6d0a4c 1075 start_stop_pit(env, tb_env, 1);
90e189ec
BS
1076 LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
1077 "%016" PRIx64 "\n", __func__,
1078 (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
1079 (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
1080 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
ddd1055b 1081 ppc40x_timer->pit_reload);
636aaad7
JM
1082}
1083
1084/* Watchdog timer */
1085static void cpu_4xx_wdt_cb (void *opaque)
1086{
7058581a 1087 PowerPCCPU *cpu;
e2684c0b 1088 CPUPPCState *env;
c227f099 1089 ppc_tb_t *tb_env;
ddd1055b 1090 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1091 uint64_t now, next;
1092
1093 env = opaque;
7058581a 1094 cpu = ppc_env_get_cpu(env);
636aaad7 1095 tb_env = env->tb_env;
ddd1055b 1096 ppc40x_timer = tb_env->opaque;
bc72ad67 1097 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
636aaad7
JM
1098 switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
1099 case 0:
1100 next = 1 << 17;
1101 break;
1102 case 1:
1103 next = 1 << 21;
1104 break;
1105 case 2:
1106 next = 1 << 25;
1107 break;
1108 case 3:
1109 next = 1 << 29;
1110 break;
1111 default:
1112 /* Cannot occur, but makes gcc happy */
1113 return;
1114 }
73bcb24d 1115 next = now + muldiv64(next, NANOSECONDS_PER_SECOND, tb_env->decr_freq);
636aaad7
JM
1116 if (next == now)
1117 next++;
90e189ec
BS
1118 LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__,
1119 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
636aaad7
JM
1120 switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
1121 case 0x0:
1122 case 0x1:
bc72ad67 1123 timer_mod(ppc40x_timer->wdt_timer, next);
ddd1055b 1124 ppc40x_timer->wdt_next = next;
a1f7f97b 1125 env->spr[SPR_40x_TSR] |= 1U << 31;
636aaad7
JM
1126 break;
1127 case 0x2:
bc72ad67 1128 timer_mod(ppc40x_timer->wdt_timer, next);
ddd1055b 1129 ppc40x_timer->wdt_next = next;
636aaad7 1130 env->spr[SPR_40x_TSR] |= 1 << 30;
7058581a
AF
1131 if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) {
1132 ppc_set_irq(cpu, PPC_INTERRUPT_WDT, 1);
1133 }
636aaad7
JM
1134 break;
1135 case 0x3:
1136 env->spr[SPR_40x_TSR] &= ~0x30000000;
1137 env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
1138 switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
1139 case 0x0:
1140 /* No reset */
1141 break;
1142 case 0x1: /* Core reset */
f3273ba6 1143 ppc40x_core_reset(cpu);
8ecc7913 1144 break;
636aaad7 1145 case 0x2: /* Chip reset */
f3273ba6 1146 ppc40x_chip_reset(cpu);
8ecc7913 1147 break;
636aaad7 1148 case 0x3: /* System reset */
f3273ba6 1149 ppc40x_system_reset(cpu);
8ecc7913 1150 break;
636aaad7
JM
1151 }
1152 }
76a66253
JM
1153}
1154
e2684c0b 1155void store_40x_pit (CPUPPCState *env, target_ulong val)
76a66253 1156{
c227f099 1157 ppc_tb_t *tb_env;
ddd1055b 1158 ppc40x_timer_t *ppc40x_timer;
636aaad7
JM
1159
1160 tb_env = env->tb_env;
ddd1055b 1161 ppc40x_timer = tb_env->opaque;
90e189ec 1162 LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val);
ddd1055b 1163 ppc40x_timer->pit_reload = val;
4b6d0a4c 1164 start_stop_pit(env, tb_env, 0);
76a66253
JM
1165}
1166
e2684c0b 1167target_ulong load_40x_pit (CPUPPCState *env)
76a66253 1168{
636aaad7 1169 return cpu_ppc_load_decr(env);
76a66253
JM
1170}
1171
ddd1055b 1172static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
4b6d0a4c 1173{
e2684c0b 1174 CPUPPCState *env = opaque;
c227f099 1175 ppc_tb_t *tb_env = env->tb_env;
4b6d0a4c 1176
d12d51d5 1177 LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__,
aae9366a 1178 freq);
4b6d0a4c 1179 tb_env->tb_freq = freq;
dbdd2506 1180 tb_env->decr_freq = freq;
4b6d0a4c
JM
1181 /* XXX: we should also update all timers */
1182}
1183
e2684c0b 1184clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
d63cb48d 1185 unsigned int decr_excp)
636aaad7 1186{
c227f099 1187 ppc_tb_t *tb_env;
ddd1055b 1188 ppc40x_timer_t *ppc40x_timer;
636aaad7 1189
7267c094 1190 tb_env = g_malloc0(sizeof(ppc_tb_t));
8ecc7913 1191 env->tb_env = tb_env;
ddd1055b
FC
1192 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
1193 ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
8ecc7913 1194 tb_env->tb_freq = freq;
dbdd2506 1195 tb_env->decr_freq = freq;
ddd1055b 1196 tb_env->opaque = ppc40x_timer;
d12d51d5 1197 LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
ddd1055b 1198 if (ppc40x_timer != NULL) {
636aaad7 1199 /* We use decr timer for PIT */
bc72ad67 1200 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env);
ddd1055b 1201 ppc40x_timer->fit_timer =
bc72ad67 1202 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env);
ddd1055b 1203 ppc40x_timer->wdt_timer =
bc72ad67 1204 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env);
ddd1055b 1205 ppc40x_timer->decr_excp = decr_excp;
636aaad7 1206 }
8ecc7913 1207
ddd1055b 1208 return &ppc_40x_set_tb_clk;
76a66253
JM
1209}
1210
2e719ba3
JM
1211/*****************************************************************************/
1212/* Embedded PowerPC Device Control Registers */
c227f099
AL
1213typedef struct ppc_dcrn_t ppc_dcrn_t;
1214struct ppc_dcrn_t {
2e719ba3
JM
1215 dcr_read_cb dcr_read;
1216 dcr_write_cb dcr_write;
1217 void *opaque;
1218};
1219
a750fc0b
JM
1220/* XXX: on 460, DCR addresses are 32 bits wide,
1221 * using DCRIPR to get the 22 upper bits of the DCR address
1222 */
2e719ba3 1223#define DCRN_NB 1024
c227f099
AL
1224struct ppc_dcr_t {
1225 ppc_dcrn_t dcrn[DCRN_NB];
2e719ba3
JM
1226 int (*read_error)(int dcrn);
1227 int (*write_error)(int dcrn);
1228};
1229
73b01960 1230int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
2e719ba3 1231{
c227f099 1232 ppc_dcrn_t *dcr;
2e719ba3
JM
1233
1234 if (dcrn < 0 || dcrn >= DCRN_NB)
1235 goto error;
1236 dcr = &dcr_env->dcrn[dcrn];
1237 if (dcr->dcr_read == NULL)
1238 goto error;
1239 *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1240
1241 return 0;
1242
1243 error:
1244 if (dcr_env->read_error != NULL)
1245 return (*dcr_env->read_error)(dcrn);
1246
1247 return -1;
1248}
1249
73b01960 1250int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
2e719ba3 1251{
c227f099 1252 ppc_dcrn_t *dcr;
2e719ba3
JM
1253
1254 if (dcrn < 0 || dcrn >= DCRN_NB)
1255 goto error;
1256 dcr = &dcr_env->dcrn[dcrn];
1257 if (dcr->dcr_write == NULL)
1258 goto error;
1259 (*dcr->dcr_write)(dcr->opaque, dcrn, val);
1260
1261 return 0;
1262
1263 error:
1264 if (dcr_env->write_error != NULL)
1265 return (*dcr_env->write_error)(dcrn);
1266
1267 return -1;
1268}
1269
e2684c0b 1270int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque,
2e719ba3
JM
1271 dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1272{
c227f099
AL
1273 ppc_dcr_t *dcr_env;
1274 ppc_dcrn_t *dcr;
2e719ba3
JM
1275
1276 dcr_env = env->dcr_env;
1277 if (dcr_env == NULL)
1278 return -1;
1279 if (dcrn < 0 || dcrn >= DCRN_NB)
1280 return -1;
1281 dcr = &dcr_env->dcrn[dcrn];
1282 if (dcr->opaque != NULL ||
1283 dcr->dcr_read != NULL ||
1284 dcr->dcr_write != NULL)
1285 return -1;
1286 dcr->opaque = opaque;
1287 dcr->dcr_read = dcr_read;
1288 dcr->dcr_write = dcr_write;
1289
1290 return 0;
1291}
1292
e2684c0b 1293int ppc_dcr_init (CPUPPCState *env, int (*read_error)(int dcrn),
2e719ba3
JM
1294 int (*write_error)(int dcrn))
1295{
c227f099 1296 ppc_dcr_t *dcr_env;
2e719ba3 1297
7267c094 1298 dcr_env = g_malloc0(sizeof(ppc_dcr_t));
2e719ba3
JM
1299 dcr_env->read_error = read_error;
1300 dcr_env->write_error = write_error;
1301 env->dcr_env = dcr_env;
1302
1303 return 0;
1304}
1305
64201201
FB
1306/*****************************************************************************/
1307/* Debug port */
fd0bbb12 1308void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
64201201
FB
1309{
1310 addr &= 0xF;
1311 switch (addr) {
1312 case 0:
1313 printf("%c", val);
1314 break;
1315 case 1:
1316 printf("\n");
1317 fflush(stdout);
1318 break;
1319 case 2:
aae9366a 1320 printf("Set loglevel to %04" PRIx32 "\n", val);
24537a01 1321 qemu_set_log(val | 0x100);
64201201
FB
1322 break;
1323 }
1324}
1325
0ce470cd
AK
1326/* CPU device-tree ID helpers */
1327int ppc_get_vcpu_dt_id(PowerPCCPU *cpu)
1328{
1329 return cpu->cpu_dt_id;
1330}
1331
1332PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
1333{
1334 CPUState *cs;
1335
1336 CPU_FOREACH(cs) {
1337 PowerPCCPU *cpu = POWERPC_CPU(cs);
1338
1339 if (cpu->cpu_dt_id == cpu_dt_id) {
1340 return cpu;
1341 }
1342 }
1343
1344 return NULL;
1345}