} else {
LOG_IRQ("%s: restart the CPU\n", __func__);
env->halted = 0;
+ qemu_cpu_kick(env);
}
break;
case PPC970_INPUT_HRESET:
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,
PPC970_INPUT_NB);
}
+
+/* POWER7 internal IRQ controller */
+static void power7_set_irq (void *opaque, int pin, int level)
+{
+ CPUState *env = opaque;
+
+ LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
+ env, pin, level);
+
+ switch (pin) {
+ case POWER7_INPUT_INT:
+ /* Level sensitive - active high */
+ LOG_IRQ("%s: set the external IRQ state to %d\n",
+ __func__, level);
+ ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
+ break;
+ default:
+ /* Unknown pin - do nothing */
+ LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
+ return;
+ }
+ if (level) {
+ env->irq_input_state |= 1 << pin;
+ } else {
+ env->irq_input_state &= ~(1 << pin);
+ }
+}
+
+void ppcPOWER7_irq_init (CPUState *env)
+{
+ env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, env,
+ POWER7_INPUT_NB);
+}
#endif /* defined(TARGET_PPC64) */
/* PowerPC 40x internal IRQ controller */
} else {
LOG_IRQ("%s: restart the CPU\n", __func__);
env->halted = 0;
+ qemu_cpu_kick(env);
}
break;
case PPC40x_INPUT_DEBUG:
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+ if (kvm_enabled()) {
+ return env->spr[SPR_TBL];
+ }
+
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb >> 32;
uint32_t cpu_ppc_load_tbu (CPUState *env)
{
+ if (kvm_enabled()) {
+ return env->spr[SPR_TBU];
+ }
+
return _cpu_ppc_load_tbu(env);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
tb &= 0xFFFFFFFF00000000ULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
&tb_env->tb_offset, tb | (uint64_t)value);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
tb &= 0x00000000FFFFFFFFULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
&tb_env->tb_offset, ((uint64_t)value << 32) | tb);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb >> 32;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
tb &= 0xFFFFFFFF00000000ULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
&tb_env->atb_offset, tb | (uint64_t)value);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
tb &= 0x00000000FFFFFFFFULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
&tb_env->atb_offset, ((uint64_t)value << 32) | tb);
}
/* If the time base is already frozen, do nothing */
if (tb_env->tb_freq != 0) {
- vmclk = qemu_get_clock(vm_clock);
+ vmclk = qemu_get_clock_ns(vm_clock);
/* Get the time base */
tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
/* Get the alternate time base */
/* If the time base is not frozen, do nothing */
if (tb_env->tb_freq == 0) {
- vmclk = qemu_get_clock(vm_clock);
+ vmclk = qemu_get_clock_ns(vm_clock);
/* Get the time base from tb_offset */
tb = tb_env->tb_offset;
/* Get the alternate time base from atb_offset */
uint32_t decr;
int64_t diff;
- diff = next - qemu_get_clock(vm_clock);
+ diff = next - qemu_get_clock_ns(vm_clock);
if (diff >= 0)
decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
else
{
ppc_tb_t *tb_env = env->tb_env;
+ if (kvm_enabled()) {
+ return env->spr[SPR_DECR];
+ }
+
return _cpu_ppc_load_decr(env, tb_env->decr_next);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t diff;
- diff = qemu_get_clock(vm_clock) - tb_env->purr_start;
+ diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start;
return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec());
}
LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
decr, value);
- now = qemu_get_clock(vm_clock);
+ now = qemu_get_clock_ns(vm_clock);
next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
if (is_excp)
next += *nextp - now;
ppc_tb_t *tb_env = env->tb_env;
tb_env->purr_load = value;
- tb_env->purr_start = qemu_get_clock(vm_clock);
+ tb_env->purr_start = qemu_get_clock_ns(vm_clock);
}
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
tb_env = qemu_mallocz(sizeof(ppc_tb_t));
env->tb_env = tb_env;
/* Create new timer */
- tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
+ tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, env);
if (0) {
/* XXX: find a suitable condition to enable the hypervisor decrementer
*/
- tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env);
+ tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb, env);
} else {
tb_env->hdecr_timer = NULL;
}
env = opaque;
tb_env = env->tb_env;
ppcemb_timer = tb_env->opaque;
- now = qemu_get_clock(vm_clock);
+ now = qemu_get_clock_ns(vm_clock);
switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
case 0:
next = 1 << 9;
} else {
LOG_TB("%s: start PIT %016" PRIx64 "\n",
__func__, ppcemb_timer->pit_reload);
- now = qemu_get_clock(vm_clock);
+ now = qemu_get_clock_ns(vm_clock);
next = now + muldiv64(ppcemb_timer->pit_reload,
get_ticks_per_sec(), tb_env->decr_freq);
if (is_excp)
env = opaque;
tb_env = env->tb_env;
ppcemb_timer = tb_env->opaque;
- now = qemu_get_clock(vm_clock);
+ now = qemu_get_clock_ns(vm_clock);
switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
case 0:
next = 1 << 17;
LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
if (ppcemb_timer != NULL) {
/* We use decr timer for PIT */
- tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env);
+ tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env);
ppcemb_timer->fit_timer =
- qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
+ qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env);
ppcemb_timer->wdt_timer =
- qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
+ qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env);
ppcemb_timer->decr_excp = decr_excp;
}