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