21
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
27
DisplayState *ds, const char **fd_filename, int snapshot,
28
const char *kernel_filename, const char *kernel_cmdline,
29
const char *initrd_filename);
31
void ppc_init (int ram_size, int vga_ram_size, int boot_device,
32
DisplayState *ds, const char **fd_filename, int snapshot,
33
const char *kernel_filename, const char *kernel_cmdline,
34
const char *initrd_filename)
36
/* For now, only PREP is supported */
37
return ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
38
snapshot, kernel_filename, kernel_cmdline,
26
#include "qemu-timer.h"
30
//#define PPC_DEBUG_IRQ
31
//#define PPC_DEBUG_TB
36
static void cpu_ppc_tb_stop (CPUState *env);
37
static void cpu_ppc_tb_start (CPUState *env);
39
static void ppc_set_irq (CPUState *env, int n_IRQ, int level)
42
env->pending_interrupts |= 1 << n_IRQ;
43
cpu_interrupt(env, CPU_INTERRUPT_HARD);
45
env->pending_interrupts &= ~(1 << n_IRQ);
46
if (env->pending_interrupts == 0)
47
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
49
#if defined(PPC_DEBUG_IRQ)
50
if (loglevel & CPU_LOG_INT) {
51
fprintf(logfile, "%s: %p n_IRQ %d level %d => pending %08" PRIx32
52
"req %08x\n", __func__, env, n_IRQ, level,
53
env->pending_interrupts, env->interrupt_request);
58
/* PowerPC 6xx / 7xx internal IRQ controller */
59
static void ppc6xx_set_irq (void *opaque, int pin, int level)
61
CPUState *env = opaque;
64
#if defined(PPC_DEBUG_IRQ)
65
if (loglevel & CPU_LOG_INT) {
66
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
70
cur_level = (env->irq_input_state >> pin) & 1;
71
/* Don't generate spurious events */
72
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
74
case PPC6xx_INPUT_TBEN:
75
/* Level sensitive - active high */
76
#if defined(PPC_DEBUG_IRQ)
77
if (loglevel & CPU_LOG_INT) {
78
fprintf(logfile, "%s: %s the time base\n",
79
__func__, level ? "start" : "stop");
83
cpu_ppc_tb_start(env);
87
case PPC6xx_INPUT_INT:
88
/* Level sensitive - active high */
89
#if defined(PPC_DEBUG_IRQ)
90
if (loglevel & CPU_LOG_INT) {
91
fprintf(logfile, "%s: set the external IRQ state to %d\n",
95
ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
97
case PPC6xx_INPUT_SMI:
98
/* Level sensitive - active high */
99
#if defined(PPC_DEBUG_IRQ)
100
if (loglevel & CPU_LOG_INT) {
101
fprintf(logfile, "%s: set the SMI IRQ state to %d\n",
105
ppc_set_irq(env, PPC_INTERRUPT_SMI, level);
107
case PPC6xx_INPUT_MCP:
108
/* Negative edge sensitive */
109
/* XXX: TODO: actual reaction may depends on HID0 status
110
* 603/604/740/750: check HID0[EMCP]
112
if (cur_level == 1 && level == 0) {
113
#if defined(PPC_DEBUG_IRQ)
114
if (loglevel & CPU_LOG_INT) {
115
fprintf(logfile, "%s: raise machine check state\n",
119
ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
122
case PPC6xx_INPUT_CKSTP_IN:
123
/* Level sensitive - active low */
124
/* XXX: TODO: relay the signal to CKSTP_OUT pin */
125
/* XXX: Note that the only way to restart the CPU is to reset it */
127
#if defined(PPC_DEBUG_IRQ)
128
if (loglevel & CPU_LOG_INT) {
129
fprintf(logfile, "%s: stop the CPU\n", __func__);
135
case PPC6xx_INPUT_HRESET:
136
/* Level sensitive - active low */
138
#if defined(PPC_DEBUG_IRQ)
139
if (loglevel & CPU_LOG_INT) {
140
fprintf(logfile, "%s: reset the CPU\n", __func__);
143
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
148
qemu_system_reset_request();
152
case PPC6xx_INPUT_SRESET:
153
#if defined(PPC_DEBUG_IRQ)
154
if (loglevel & CPU_LOG_INT) {
155
fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
159
ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
162
/* Unknown pin - do nothing */
163
#if defined(PPC_DEBUG_IRQ)
164
if (loglevel & CPU_LOG_INT) {
165
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
171
env->irq_input_state |= 1 << pin;
173
env->irq_input_state &= ~(1 << pin);
177
void ppc6xx_irq_init (CPUState *env)
179
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env,
183
#if defined(TARGET_PPC64)
184
/* PowerPC 970 internal IRQ controller */
185
static void ppc970_set_irq (void *opaque, int pin, int level)
187
CPUState *env = opaque;
190
#if defined(PPC_DEBUG_IRQ)
191
if (loglevel & CPU_LOG_INT) {
192
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
196
cur_level = (env->irq_input_state >> pin) & 1;
197
/* Don't generate spurious events */
198
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
200
case PPC970_INPUT_INT:
201
/* Level sensitive - active high */
202
#if defined(PPC_DEBUG_IRQ)
203
if (loglevel & CPU_LOG_INT) {
204
fprintf(logfile, "%s: set the external IRQ state to %d\n",
208
ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
210
case PPC970_INPUT_THINT:
211
/* Level sensitive - active high */
212
#if defined(PPC_DEBUG_IRQ)
213
if (loglevel & CPU_LOG_INT) {
214
fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__,
218
ppc_set_irq(env, PPC_INTERRUPT_THERM, level);
220
case PPC970_INPUT_MCP:
221
/* Negative edge sensitive */
222
/* XXX: TODO: actual reaction may depends on HID0 status
223
* 603/604/740/750: check HID0[EMCP]
225
if (cur_level == 1 && level == 0) {
226
#if defined(PPC_DEBUG_IRQ)
227
if (loglevel & CPU_LOG_INT) {
228
fprintf(logfile, "%s: raise machine check state\n",
232
ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
235
case PPC970_INPUT_CKSTP:
236
/* Level sensitive - active low */
237
/* XXX: TODO: relay the signal to CKSTP_OUT pin */
239
#if defined(PPC_DEBUG_IRQ)
240
if (loglevel & CPU_LOG_INT) {
241
fprintf(logfile, "%s: stop the CPU\n", __func__);
246
#if defined(PPC_DEBUG_IRQ)
247
if (loglevel & CPU_LOG_INT) {
248
fprintf(logfile, "%s: restart the CPU\n", __func__);
254
case PPC970_INPUT_HRESET:
255
/* Level sensitive - active low */
258
#if defined(PPC_DEBUG_IRQ)
259
if (loglevel & CPU_LOG_INT) {
260
fprintf(logfile, "%s: reset the CPU\n", __func__);
267
case PPC970_INPUT_SRESET:
268
#if defined(PPC_DEBUG_IRQ)
269
if (loglevel & CPU_LOG_INT) {
270
fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
274
ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
276
case PPC970_INPUT_TBEN:
277
#if defined(PPC_DEBUG_IRQ)
278
if (loglevel & CPU_LOG_INT) {
279
fprintf(logfile, "%s: set the TBEN state to %d\n", __func__,
286
/* Unknown pin - do nothing */
287
#if defined(PPC_DEBUG_IRQ)
288
if (loglevel & CPU_LOG_INT) {
289
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
295
env->irq_input_state |= 1 << pin;
297
env->irq_input_state &= ~(1 << pin);
301
void ppc970_irq_init (CPUState *env)
303
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,
306
#endif /* defined(TARGET_PPC64) */
308
/* PowerPC 40x internal IRQ controller */
309
static void ppc40x_set_irq (void *opaque, int pin, int level)
311
CPUState *env = opaque;
314
#if defined(PPC_DEBUG_IRQ)
315
if (loglevel & CPU_LOG_INT) {
316
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
320
cur_level = (env->irq_input_state >> pin) & 1;
321
/* Don't generate spurious events */
322
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
324
case PPC40x_INPUT_RESET_SYS:
326
#if defined(PPC_DEBUG_IRQ)
327
if (loglevel & CPU_LOG_INT) {
328
fprintf(logfile, "%s: reset the PowerPC system\n",
332
ppc40x_system_reset(env);
335
case PPC40x_INPUT_RESET_CHIP:
337
#if defined(PPC_DEBUG_IRQ)
338
if (loglevel & CPU_LOG_INT) {
339
fprintf(logfile, "%s: reset the PowerPC chip\n", __func__);
342
ppc40x_chip_reset(env);
345
case PPC40x_INPUT_RESET_CORE:
346
/* XXX: TODO: update DBSR[MRR] */
348
#if defined(PPC_DEBUG_IRQ)
349
if (loglevel & CPU_LOG_INT) {
350
fprintf(logfile, "%s: reset the PowerPC core\n", __func__);
353
ppc40x_core_reset(env);
356
case PPC40x_INPUT_CINT:
357
/* Level sensitive - active high */
358
#if defined(PPC_DEBUG_IRQ)
359
if (loglevel & CPU_LOG_INT) {
360
fprintf(logfile, "%s: set the critical IRQ state to %d\n",
364
ppc_set_irq(env, PPC_INTERRUPT_CEXT, level);
366
case PPC40x_INPUT_INT:
367
/* Level sensitive - active high */
368
#if defined(PPC_DEBUG_IRQ)
369
if (loglevel & CPU_LOG_INT) {
370
fprintf(logfile, "%s: set the external IRQ state to %d\n",
374
ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
376
case PPC40x_INPUT_HALT:
377
/* Level sensitive - active low */
379
#if defined(PPC_DEBUG_IRQ)
380
if (loglevel & CPU_LOG_INT) {
381
fprintf(logfile, "%s: stop the CPU\n", __func__);
386
#if defined(PPC_DEBUG_IRQ)
387
if (loglevel & CPU_LOG_INT) {
388
fprintf(logfile, "%s: restart the CPU\n", __func__);
394
case PPC40x_INPUT_DEBUG:
395
/* Level sensitive - active high */
396
#if defined(PPC_DEBUG_IRQ)
397
if (loglevel & CPU_LOG_INT) {
398
fprintf(logfile, "%s: set the debug pin state to %d\n",
402
ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
405
/* Unknown pin - do nothing */
406
#if defined(PPC_DEBUG_IRQ)
407
if (loglevel & CPU_LOG_INT) {
408
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
414
env->irq_input_state |= 1 << pin;
416
env->irq_input_state &= ~(1 << pin);
420
void ppc40x_irq_init (CPUState *env)
422
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq,
423
env, PPC40x_INPUT_NB);
426
/*****************************************************************************/
427
/* PowerPC time base and decrementer emulation */
429
/* Time base management */
430
int64_t tb_offset; /* Compensation */
431
int64_t atb_offset; /* Compensation */
432
uint32_t tb_freq; /* TB frequency */
433
/* Decrementer management */
434
uint64_t decr_next; /* Tick for next decr interrupt */
435
uint32_t decr_freq; /* decrementer frequency */
436
struct QEMUTimer *decr_timer;
437
/* Hypervisor decrementer management */
438
uint64_t hdecr_next; /* Tick for next hdecr interrupt */
439
struct QEMUTimer *hdecr_timer;
445
static always_inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env, uint64_t vmclk,
448
/* TB time in tb periods */
449
return muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec) + tb_offset;
452
uint32_t cpu_ppc_load_tbl (CPUState *env)
454
ppc_tb_t *tb_env = env->tb_env;
457
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
458
#if defined(PPC_DEBUG_TB)
460
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);
464
return tb & 0xFFFFFFFF;
467
static always_inline uint32_t _cpu_ppc_load_tbu (CPUState *env)
469
ppc_tb_t *tb_env = env->tb_env;
472
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
473
#if defined(PPC_DEBUG_TB)
475
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);
482
uint32_t cpu_ppc_load_tbu (CPUState *env)
484
return _cpu_ppc_load_tbu(env);
487
static always_inline void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t vmclk,
491
*tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, ticks_per_sec);
494
fprintf(logfile, "%s: tb %016" PRIx64 " offset %08" PRIx64 "\n",
495
__func__, value, *tb_offsetp);
500
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
502
ppc_tb_t *tb_env = env->tb_env;
505
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
506
tb &= 0xFFFFFFFF00000000ULL;
507
cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
508
&tb_env->tb_offset, tb | (uint64_t)value);
511
static always_inline void _cpu_ppc_store_tbu (CPUState *env, uint32_t value)
513
ppc_tb_t *tb_env = env->tb_env;
516
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
517
tb &= 0x00000000FFFFFFFFULL;
518
cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
519
&tb_env->tb_offset, ((uint64_t)value << 32) | tb);
522
void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
524
_cpu_ppc_store_tbu(env, value);
527
uint32_t cpu_ppc_load_atbl (CPUState *env)
529
ppc_tb_t *tb_env = env->tb_env;
532
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
533
#if defined(PPC_DEBUG_TB)
535
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);
539
return tb & 0xFFFFFFFF;
542
uint32_t cpu_ppc_load_atbu (CPUState *env)
544
ppc_tb_t *tb_env = env->tb_env;
547
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
548
#if defined(PPC_DEBUG_TB)
550
fprintf(logfile, "%s: tb %016" PRIx64 "\n", __func__, tb);
557
void cpu_ppc_store_atbl (CPUState *env, uint32_t value)
559
ppc_tb_t *tb_env = env->tb_env;
562
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
563
tb &= 0xFFFFFFFF00000000ULL;
564
cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
565
&tb_env->atb_offset, tb | (uint64_t)value);
568
void cpu_ppc_store_atbu (CPUState *env, uint32_t value)
570
ppc_tb_t *tb_env = env->tb_env;
573
tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
574
tb &= 0x00000000FFFFFFFFULL;
575
cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
576
&tb_env->atb_offset, ((uint64_t)value << 32) | tb);
579
static void cpu_ppc_tb_stop (CPUState *env)
581
ppc_tb_t *tb_env = env->tb_env;
582
uint64_t tb, atb, vmclk;
584
/* If the time base is already frozen, do nothing */
585
if (tb_env->tb_freq != 0) {
586
vmclk = qemu_get_clock(vm_clock);
587
/* Get the time base */
588
tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
589
/* Get the alternate time base */
590
atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset);
591
/* Store the time base value (ie compute the current offset) */
592
cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
593
/* Store the alternate time base value (compute the current offset) */
594
cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
595
/* Set the time base frequency to zero */
597
/* Now, the time bases are frozen to tb_offset / atb_offset value */
601
static void cpu_ppc_tb_start (CPUState *env)
603
ppc_tb_t *tb_env = env->tb_env;
604
uint64_t tb, atb, vmclk;
606
/* If the time base is not frozen, do nothing */
607
if (tb_env->tb_freq == 0) {
608
vmclk = qemu_get_clock(vm_clock);
609
/* Get the time base from tb_offset */
610
tb = tb_env->tb_offset;
611
/* Get the alternate time base from atb_offset */
612
atb = tb_env->atb_offset;
613
/* Restore the tb frequency from the decrementer frequency */
614
tb_env->tb_freq = tb_env->decr_freq;
615
/* Store the time base value */
616
cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb);
617
/* Store the alternate time base value */
618
cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb);
622
static always_inline uint32_t _cpu_ppc_load_decr (CPUState *env,
625
ppc_tb_t *tb_env = env->tb_env;
629
diff = tb_env->decr_next - qemu_get_clock(vm_clock);
631
decr = muldiv64(diff, tb_env->decr_freq, ticks_per_sec);
633
decr = -muldiv64(-diff, tb_env->decr_freq, ticks_per_sec);
634
#if defined(PPC_DEBUG_TB)
636
fprintf(logfile, "%s: %08" PRIx32 "\n", __func__, decr);
643
uint32_t cpu_ppc_load_decr (CPUState *env)
645
ppc_tb_t *tb_env = env->tb_env;
647
return _cpu_ppc_load_decr(env, &tb_env->decr_next);
650
uint32_t cpu_ppc_load_hdecr (CPUState *env)
652
ppc_tb_t *tb_env = env->tb_env;
654
return _cpu_ppc_load_decr(env, &tb_env->hdecr_next);
657
uint64_t cpu_ppc_load_purr (CPUState *env)
659
ppc_tb_t *tb_env = env->tb_env;
662
diff = qemu_get_clock(vm_clock) - tb_env->purr_start;
664
return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, ticks_per_sec);
667
/* When decrementer expires,
668
* all we need to do is generate or queue a CPU exception
670
static always_inline void cpu_ppc_decr_excp (CPUState *env)
675
fprintf(logfile, "raise decrementer exception\n");
678
ppc_set_irq(env, PPC_INTERRUPT_DECR, 1);
681
static always_inline void cpu_ppc_hdecr_excp (CPUState *env)
686
fprintf(logfile, "raise decrementer exception\n");
689
ppc_set_irq(env, PPC_INTERRUPT_HDECR, 1);
692
static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp,
693
struct QEMUTimer *timer,
694
void (*raise_excp)(CPUState *),
695
uint32_t decr, uint32_t value,
698
ppc_tb_t *tb_env = env->tb_env;
703
fprintf(logfile, "%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
707
now = qemu_get_clock(vm_clock);
708
next = now + muldiv64(value, ticks_per_sec, tb_env->decr_freq);
710
next += *nextp - now;
715
qemu_mod_timer(timer, next);
716
/* If we set a negative value and the decrementer was positive,
717
* raise an exception.
719
if ((value & 0x80000000) && !(decr & 0x80000000))
723
static always_inline void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
724
uint32_t value, int is_excp)
726
ppc_tb_t *tb_env = env->tb_env;
728
__cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
729
&cpu_ppc_decr_excp, decr, value, is_excp);
732
void cpu_ppc_store_decr (CPUState *env, uint32_t value)
734
_cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
737
static void cpu_ppc_decr_cb (void *opaque)
739
_cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
742
static always_inline void _cpu_ppc_store_hdecr (CPUState *env, uint32_t hdecr,
743
uint32_t value, int is_excp)
745
ppc_tb_t *tb_env = env->tb_env;
747
if (tb_env->hdecr_timer != NULL) {
748
__cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
749
&cpu_ppc_hdecr_excp, hdecr, value, is_excp);
753
void cpu_ppc_store_hdecr (CPUState *env, uint32_t value)
755
_cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0);
758
static void cpu_ppc_hdecr_cb (void *opaque)
760
_cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1);
763
void cpu_ppc_store_purr (CPUState *env, uint64_t value)
765
ppc_tb_t *tb_env = env->tb_env;
767
tb_env->purr_load = value;
768
tb_env->purr_start = qemu_get_clock(vm_clock);
771
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
773
CPUState *env = opaque;
774
ppc_tb_t *tb_env = env->tb_env;
776
tb_env->tb_freq = freq;
777
tb_env->decr_freq = freq;
778
/* There is a bug in Linux 2.4 kernels:
779
* if a decrementer exception is pending when it enables msr_ee at startup,
780
* it's not ready to handle it...
782
_cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
783
_cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
784
cpu_ppc_store_purr(env, 0x0000000000000000ULL);
787
/* Set up (once) timebase frequency (in Hz) */
788
clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
792
tb_env = qemu_mallocz(sizeof(ppc_tb_t));
795
env->tb_env = tb_env;
796
/* Create new timer */
797
tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
799
/* XXX: find a suitable condition to enable the hypervisor decrementer
801
tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env);
803
tb_env->hdecr_timer = NULL;
805
cpu_ppc_set_tb_clk(env, freq);
807
return &cpu_ppc_set_tb_clk;
810
/* Specific helpers for POWER & PowerPC 601 RTC */
811
clk_setup_cb cpu_ppc601_rtc_init (CPUState *env)
813
return cpu_ppc_tb_init(env, 7812500);
816
void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
818
_cpu_ppc_store_tbu(env, value);
821
uint32_t cpu_ppc601_load_rtcu (CPUState *env)
823
return _cpu_ppc_load_tbu(env);
826
void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
828
cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
831
uint32_t cpu_ppc601_load_rtcl (CPUState *env)
833
return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
836
/*****************************************************************************/
837
/* Embedded PowerPC timers */
840
typedef struct ppcemb_timer_t ppcemb_timer_t;
841
struct ppcemb_timer_t {
842
uint64_t pit_reload; /* PIT auto-reload value */
843
uint64_t fit_next; /* Tick for next FIT interrupt */
844
struct QEMUTimer *fit_timer;
845
uint64_t wdt_next; /* Tick for next WDT interrupt */
846
struct QEMUTimer *wdt_timer;
849
/* Fixed interval timer */
850
static void cpu_4xx_fit_cb (void *opaque)
854
ppcemb_timer_t *ppcemb_timer;
858
tb_env = env->tb_env;
859
ppcemb_timer = tb_env->opaque;
860
now = qemu_get_clock(vm_clock);
861
switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
875
/* Cannot occur, but makes gcc happy */
878
next = now + muldiv64(next, ticks_per_sec, tb_env->tb_freq);
881
qemu_mod_timer(ppcemb_timer->fit_timer, next);
882
env->spr[SPR_40x_TSR] |= 1 << 26;
883
if ((env->spr[SPR_40x_TCR] >> 23) & 0x1)
884
ppc_set_irq(env, PPC_INTERRUPT_FIT, 1);
887
fprintf(logfile, "%s: ir %d TCR " ADDRX " TSR " ADDRX "\n", __func__,
888
(int)((env->spr[SPR_40x_TCR] >> 23) & 0x1),
889
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
894
/* Programmable interval timer */
895
static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp)
897
ppcemb_timer_t *ppcemb_timer;
900
ppcemb_timer = tb_env->opaque;
901
if (ppcemb_timer->pit_reload <= 1 ||
902
!((env->spr[SPR_40x_TCR] >> 26) & 0x1) ||
903
(is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
907
fprintf(logfile, "%s: stop PIT\n", __func__);
910
qemu_del_timer(tb_env->decr_timer);
914
fprintf(logfile, "%s: start PIT %016" PRIx64 "\n",
915
__func__, ppcemb_timer->pit_reload);
918
now = qemu_get_clock(vm_clock);
919
next = now + muldiv64(ppcemb_timer->pit_reload,
920
ticks_per_sec, tb_env->decr_freq);
922
next += tb_env->decr_next - now;
925
qemu_mod_timer(tb_env->decr_timer, next);
926
tb_env->decr_next = next;
930
static void cpu_4xx_pit_cb (void *opaque)
934
ppcemb_timer_t *ppcemb_timer;
937
tb_env = env->tb_env;
938
ppcemb_timer = tb_env->opaque;
939
env->spr[SPR_40x_TSR] |= 1 << 27;
940
if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
941
ppc_set_irq(env, PPC_INTERRUPT_PIT, 1);
942
start_stop_pit(env, tb_env, 1);
945
fprintf(logfile, "%s: ar %d ir %d TCR " ADDRX " TSR " ADDRX " "
946
"%016" PRIx64 "\n", __func__,
947
(int)((env->spr[SPR_40x_TCR] >> 22) & 0x1),
948
(int)((env->spr[SPR_40x_TCR] >> 26) & 0x1),
949
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
950
ppcemb_timer->pit_reload);
956
static void cpu_4xx_wdt_cb (void *opaque)
960
ppcemb_timer_t *ppcemb_timer;
964
tb_env = env->tb_env;
965
ppcemb_timer = tb_env->opaque;
966
now = qemu_get_clock(vm_clock);
967
switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
981
/* Cannot occur, but makes gcc happy */
984
next = now + muldiv64(next, ticks_per_sec, tb_env->decr_freq);
989
fprintf(logfile, "%s: TCR " ADDRX " TSR " ADDRX "\n", __func__,
990
env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]);
993
switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
996
qemu_mod_timer(ppcemb_timer->wdt_timer, next);
997
ppcemb_timer->wdt_next = next;
998
env->spr[SPR_40x_TSR] |= 1 << 31;
1001
qemu_mod_timer(ppcemb_timer->wdt_timer, next);
1002
ppcemb_timer->wdt_next = next;
1003
env->spr[SPR_40x_TSR] |= 1 << 30;
1004
if ((env->spr[SPR_40x_TCR] >> 27) & 0x1)
1005
ppc_set_irq(env, PPC_INTERRUPT_WDT, 1);
1008
env->spr[SPR_40x_TSR] &= ~0x30000000;
1009
env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000;
1010
switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) {
1014
case 0x1: /* Core reset */
1015
ppc40x_core_reset(env);
1017
case 0x2: /* Chip reset */
1018
ppc40x_chip_reset(env);
1020
case 0x3: /* System reset */
1021
ppc40x_system_reset(env);
1027
void store_40x_pit (CPUState *env, target_ulong val)
1030
ppcemb_timer_t *ppcemb_timer;
1032
tb_env = env->tb_env;
1033
ppcemb_timer = tb_env->opaque;
1035
if (loglevel != 0) {
1036
fprintf(logfile, "%s val" ADDRX "\n", __func__, val);
1039
ppcemb_timer->pit_reload = val;
1040
start_stop_pit(env, tb_env, 0);
1043
target_ulong load_40x_pit (CPUState *env)
1045
return cpu_ppc_load_decr(env);
1048
void store_booke_tsr (CPUState *env, target_ulong val)
1051
if (loglevel != 0) {
1052
fprintf(logfile, "%s: val " ADDRX "\n", __func__, val);
1055
env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
1056
if (val & 0x80000000)
1057
ppc_set_irq(env, PPC_INTERRUPT_PIT, 0);
1060
void store_booke_tcr (CPUState *env, target_ulong val)
1064
tb_env = env->tb_env;
1066
if (loglevel != 0) {
1067
fprintf(logfile, "%s: val " ADDRX "\n", __func__, val);
1070
env->spr[SPR_40x_TCR] = val & 0xFFC00000;
1071
start_stop_pit(env, tb_env, 1);
1072
cpu_4xx_wdt_cb(env);
1075
static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq)
1077
CPUState *env = opaque;
1078
ppc_tb_t *tb_env = env->tb_env;
1081
if (loglevel != 0) {
1082
fprintf(logfile, "%s set new frequency to %" PRIu32 "\n", __func__,
1086
tb_env->tb_freq = freq;
1087
tb_env->decr_freq = freq;
1088
/* XXX: we should also update all timers */
1091
clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
1094
ppcemb_timer_t *ppcemb_timer;
1096
tb_env = qemu_mallocz(sizeof(ppc_tb_t));
1097
if (tb_env == NULL) {
1100
env->tb_env = tb_env;
1101
ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
1102
tb_env->tb_freq = freq;
1103
tb_env->decr_freq = freq;
1104
tb_env->opaque = ppcemb_timer;
1106
if (loglevel != 0) {
1107
fprintf(logfile, "%s freq %" PRIu32 "\n", __func__, freq);
1110
if (ppcemb_timer != NULL) {
1111
/* We use decr timer for PIT */
1112
tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env);
1113
ppcemb_timer->fit_timer =
1114
qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
1115
ppcemb_timer->wdt_timer =
1116
qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
1119
return &ppc_emb_set_tb_clk;
1122
/*****************************************************************************/
1123
/* Embedded PowerPC Device Control Registers */
1124
typedef struct ppc_dcrn_t ppc_dcrn_t;
1126
dcr_read_cb dcr_read;
1127
dcr_write_cb dcr_write;
1131
/* XXX: on 460, DCR addresses are 32 bits wide,
1132
* using DCRIPR to get the 22 upper bits of the DCR address
1134
#define DCRN_NB 1024
1136
ppc_dcrn_t dcrn[DCRN_NB];
1137
int (*read_error)(int dcrn);
1138
int (*write_error)(int dcrn);
1141
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
1145
if (dcrn < 0 || dcrn >= DCRN_NB)
1147
dcr = &dcr_env->dcrn[dcrn];
1148
if (dcr->dcr_read == NULL)
1150
*valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
1155
if (dcr_env->read_error != NULL)
1156
return (*dcr_env->read_error)(dcrn);
1161
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
1165
if (dcrn < 0 || dcrn >= DCRN_NB)
1167
dcr = &dcr_env->dcrn[dcrn];
1168
if (dcr->dcr_write == NULL)
1170
(*dcr->dcr_write)(dcr->opaque, dcrn, val);
1175
if (dcr_env->write_error != NULL)
1176
return (*dcr_env->write_error)(dcrn);
1181
int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
1182
dcr_read_cb dcr_read, dcr_write_cb dcr_write)
1187
dcr_env = env->dcr_env;
1188
if (dcr_env == NULL)
1190
if (dcrn < 0 || dcrn >= DCRN_NB)
1192
dcr = &dcr_env->dcrn[dcrn];
1193
if (dcr->opaque != NULL ||
1194
dcr->dcr_read != NULL ||
1195
dcr->dcr_write != NULL)
1197
dcr->opaque = opaque;
1198
dcr->dcr_read = dcr_read;
1199
dcr->dcr_write = dcr_write;
1204
int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
1205
int (*write_error)(int dcrn))
1209
dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
1210
if (dcr_env == NULL)
1212
dcr_env->read_error = read_error;
1213
dcr_env->write_error = write_error;
1214
env->dcr_env = dcr_env;
1220
/*****************************************************************************/
1221
/* Handle system reset (for now, just stop emulation) */
1222
void cpu_ppc_reset (CPUState *env)
1224
printf("Reset asked... Stop emulation\n");
1229
/*****************************************************************************/
1231
void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
1243
printf("Set loglevel to %04" PRIx32 "\n", val);
1244
cpu_set_log(val | 0x100);
1249
/*****************************************************************************/
1251
static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr)
1253
return (*nvram->read_fn)(nvram->opaque, addr);;
1256
static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val)
1258
(*nvram->write_fn)(nvram->opaque, addr, val);
1261
void NVRAM_set_byte (nvram_t *nvram, uint32_t addr, uint8_t value)
1263
nvram_write(nvram, addr, value);
1266
uint8_t NVRAM_get_byte (nvram_t *nvram, uint32_t addr)
1268
return nvram_read(nvram, addr);
1271
void NVRAM_set_word (nvram_t *nvram, uint32_t addr, uint16_t value)
1273
nvram_write(nvram, addr, value >> 8);
1274
nvram_write(nvram, addr + 1, value & 0xFF);
1277
uint16_t NVRAM_get_word (nvram_t *nvram, uint32_t addr)
1281
tmp = nvram_read(nvram, addr) << 8;
1282
tmp |= nvram_read(nvram, addr + 1);
1287
void NVRAM_set_lword (nvram_t *nvram, uint32_t addr, uint32_t value)
1289
nvram_write(nvram, addr, value >> 24);
1290
nvram_write(nvram, addr + 1, (value >> 16) & 0xFF);
1291
nvram_write(nvram, addr + 2, (value >> 8) & 0xFF);
1292
nvram_write(nvram, addr + 3, value & 0xFF);
1295
uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr)
1299
tmp = nvram_read(nvram, addr) << 24;
1300
tmp |= nvram_read(nvram, addr + 1) << 16;
1301
tmp |= nvram_read(nvram, addr + 2) << 8;
1302
tmp |= nvram_read(nvram, addr + 3);
1307
void NVRAM_set_string (nvram_t *nvram, uint32_t addr,
1308
const unsigned char *str, uint32_t max)
1312
for (i = 0; i < max && str[i] != '\0'; i++) {
1313
nvram_write(nvram, addr + i, str[i]);
1315
nvram_write(nvram, addr + i, str[i]);
1316
nvram_write(nvram, addr + max - 1, '\0');
1319
int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max)
1323
memset(dst, 0, max);
1324
for (i = 0; i < max; i++) {
1325
dst[i] = NVRAM_get_byte(nvram, addr + i);
1333
static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
1336
uint16_t pd, pd1, pd2;
1341
pd2 = ((pd >> 4) & 0x000F) ^ pd1;
1342
tmp ^= (pd1 << 3) | (pd1 << 8);
1343
tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
1348
uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count)
1351
uint16_t crc = 0xFFFF;
1356
for (i = 0; i != count; i++) {
1357
crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
1360
crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
1366
#define CMDLINE_ADDR 0x017ff000
1368
int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
1369
const unsigned char *arch,
1370
uint32_t RAM_size, int boot_device,
1371
uint32_t kernel_image, uint32_t kernel_size,
1372
const char *cmdline,
1373
uint32_t initrd_image, uint32_t initrd_size,
1374
uint32_t NVRAM_image,
1375
int width, int height, int depth)
1379
/* Set parameters for Open Hack'Ware BIOS */
1380
NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
1381
NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
1382
NVRAM_set_word(nvram, 0x14, NVRAM_size);
1383
NVRAM_set_string(nvram, 0x20, arch, 16);
1384
NVRAM_set_lword(nvram, 0x30, RAM_size);
1385
NVRAM_set_byte(nvram, 0x34, boot_device);
1386
NVRAM_set_lword(nvram, 0x38, kernel_image);
1387
NVRAM_set_lword(nvram, 0x3C, kernel_size);
1389
/* XXX: put the cmdline in NVRAM too ? */
1390
strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
1391
NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR);
1392
NVRAM_set_lword(nvram, 0x44, strlen(cmdline));
1394
NVRAM_set_lword(nvram, 0x40, 0);
1395
NVRAM_set_lword(nvram, 0x44, 0);
1397
NVRAM_set_lword(nvram, 0x48, initrd_image);
1398
NVRAM_set_lword(nvram, 0x4C, initrd_size);
1399
NVRAM_set_lword(nvram, 0x50, NVRAM_image);
1401
NVRAM_set_word(nvram, 0x54, width);
1402
NVRAM_set_word(nvram, 0x56, height);
1403
NVRAM_set_word(nvram, 0x58, depth);
1404
crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
1405
NVRAM_set_word(nvram, 0xFC, crc);