Revision 7e0a9247
b/hw/ppc.c | ||
---|---|---|
644 | 644 |
/* When decrementer expires, |
645 | 645 |
* all we need to do is generate or queue a CPU exception |
646 | 646 |
*/ |
647 |
static inline void cpu_ppc_decr_excp(CPUPPCState *env)
|
|
647 |
static inline void cpu_ppc_decr_excp(PowerPCCPU *cpu)
|
|
648 | 648 |
{ |
649 |
PowerPCCPU *cpu = ppc_env_get_cpu(env); |
|
650 |
|
|
651 | 649 |
/* Raise it */ |
652 | 650 |
LOG_TB("raise decrementer exception\n"); |
653 | 651 |
ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 1); |
654 | 652 |
} |
655 | 653 |
|
656 |
static inline void cpu_ppc_hdecr_excp(CPUPPCState *env)
|
|
654 |
static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu)
|
|
657 | 655 |
{ |
658 |
PowerPCCPU *cpu = ppc_env_get_cpu(env); |
|
659 |
|
|
660 | 656 |
/* Raise it */ |
661 | 657 |
LOG_TB("raise decrementer exception\n"); |
662 | 658 |
ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1); |
663 | 659 |
} |
664 | 660 |
|
665 |
static void __cpu_ppc_store_decr (CPUPPCState *env, uint64_t *nextp,
|
|
666 |
struct QEMUTimer *timer,
|
|
667 |
void (*raise_excp)(CPUPPCState *),
|
|
668 |
uint32_t decr, uint32_t value,
|
|
669 |
int is_excp)
|
|
661 |
static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
|
|
662 |
struct QEMUTimer *timer, |
|
663 |
void (*raise_excp)(PowerPCCPU *),
|
|
664 |
uint32_t decr, uint32_t value, |
|
665 |
int is_excp) |
|
670 | 666 |
{ |
667 |
CPUPPCState *env = &cpu->env; |
|
671 | 668 |
ppc_tb_t *tb_env = env->tb_env; |
672 | 669 |
uint64_t now, next; |
673 | 670 |
|
... | ... | |
697 | 694 |
if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) |
698 | 695 |
&& (value & 0x80000000) |
699 | 696 |
&& !(decr & 0x80000000)) { |
700 |
(*raise_excp)(env);
|
|
697 |
(*raise_excp)(cpu);
|
|
701 | 698 |
} |
702 | 699 |
} |
703 | 700 |
|
704 |
static inline void _cpu_ppc_store_decr(CPUPPCState *env, uint32_t decr,
|
|
701 |
static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr,
|
|
705 | 702 |
uint32_t value, int is_excp) |
706 | 703 |
{ |
707 |
ppc_tb_t *tb_env = env->tb_env;
|
|
704 |
ppc_tb_t *tb_env = cpu->env.tb_env;
|
|
708 | 705 |
|
709 |
__cpu_ppc_store_decr(env, &tb_env->decr_next, tb_env->decr_timer,
|
|
706 |
__cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
|
|
710 | 707 |
&cpu_ppc_decr_excp, decr, value, is_excp); |
711 | 708 |
} |
712 | 709 |
|
713 | 710 |
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value) |
714 | 711 |
{ |
715 |
_cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0); |
|
712 |
PowerPCCPU *cpu = ppc_env_get_cpu(env); |
|
713 |
|
|
714 |
_cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, 0); |
|
716 | 715 |
} |
717 | 716 |
|
718 | 717 |
static void cpu_ppc_decr_cb (void *opaque) |
719 | 718 |
{ |
720 |
_cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1); |
|
719 |
CPUPPCState *env = opaque; |
|
720 |
|
|
721 |
_cpu_ppc_store_decr(ppc_env_get_cpu(env), 0x00000000, 0xFFFFFFFF, 1); |
|
721 | 722 |
} |
722 | 723 |
|
723 |
static inline void _cpu_ppc_store_hdecr(CPUPPCState *env, uint32_t hdecr,
|
|
724 |
static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr,
|
|
724 | 725 |
uint32_t value, int is_excp) |
725 | 726 |
{ |
726 |
ppc_tb_t *tb_env = env->tb_env;
|
|
727 |
ppc_tb_t *tb_env = cpu->env.tb_env;
|
|
727 | 728 |
|
728 | 729 |
if (tb_env->hdecr_timer != NULL) { |
729 |
__cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer,
|
|
730 |
__cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
|
|
730 | 731 |
&cpu_ppc_hdecr_excp, hdecr, value, is_excp); |
731 | 732 |
} |
732 | 733 |
} |
733 | 734 |
|
734 | 735 |
void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value) |
735 | 736 |
{ |
736 |
_cpu_ppc_store_hdecr(env, cpu_ppc_load_hdecr(env), value, 0); |
|
737 |
PowerPCCPU *cpu = ppc_env_get_cpu(env); |
|
738 |
|
|
739 |
_cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value, 0); |
|
737 | 740 |
} |
738 | 741 |
|
739 | 742 |
static void cpu_ppc_hdecr_cb (void *opaque) |
740 | 743 |
{ |
741 |
_cpu_ppc_store_hdecr(opaque, 0x00000000, 0xFFFFFFFF, 1); |
|
744 |
CPUPPCState *env = opaque; |
|
745 |
|
|
746 |
_cpu_ppc_store_hdecr(ppc_env_get_cpu(env), 0x00000000, 0xFFFFFFFF, 1); |
|
742 | 747 |
} |
743 | 748 |
|
744 |
static void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value)
|
|
749 |
static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value)
|
|
745 | 750 |
{ |
746 |
ppc_tb_t *tb_env = env->tb_env;
|
|
751 |
ppc_tb_t *tb_env = cpu->env.tb_env;
|
|
747 | 752 |
|
748 | 753 |
tb_env->purr_load = value; |
749 | 754 |
tb_env->purr_start = qemu_get_clock_ns(vm_clock); |
... | ... | |
752 | 757 |
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) |
753 | 758 |
{ |
754 | 759 |
CPUPPCState *env = opaque; |
760 |
PowerPCCPU *cpu = ppc_env_get_cpu(env); |
|
755 | 761 |
ppc_tb_t *tb_env = env->tb_env; |
756 | 762 |
|
757 | 763 |
tb_env->tb_freq = freq; |
... | ... | |
760 | 766 |
* if a decrementer exception is pending when it enables msr_ee at startup, |
761 | 767 |
* it's not ready to handle it... |
762 | 768 |
*/ |
763 |
_cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
|
764 |
_cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
|
765 |
cpu_ppc_store_purr(env, 0x0000000000000000ULL);
|
|
769 |
_cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
|
770 |
_cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
|
771 |
cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
|
|
766 | 772 |
} |
767 | 773 |
|
768 | 774 |
/* Set up (once) timebase frequency (in Hz) */ |
Also available in: Unified diff