qemu-sparc update
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAABAgAGBQJWjmYNAAoJEFvCxW+uDzIfSycH/An/L9tDFXtoC/W7Dq7/cKQw 7AWhskcfgCxxo0DoqnyHc6JKgONr8Jv15Vf7PTMM23KHioCX5wEgH52mOT5bKXDy RnGG5qe4rj5A0i48kRZTG0ryjcKHra5I08UsznljGROmp5/fjLXAG1QEgrKKGXGn kQyWZ46g8vka+MBKtetNipFForimIWOWjVO54neb7kwLMV2yiE8gaD4oAgJDmgSN dHXB6rxCpBcnjdYCuri/9E1hVZmv7GmUH5e3cbD/COJu8ZFHASqXvtAih786vQa0 Fj441hO1WToi8PrrZBv76UxUton06O1+QvYZsCMf073vEyQKUhyHrYpd2hpWFQI= =zyNj -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-signed' into staging qemu-sparc update # gpg: Signature made Thu 07 Jan 2016 13:20:13 GMT using RSA key ID AE0F321F # gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" * remotes/mcayland/tags/qemu-sparc-signed: target-sparc: implement NPT timer bit sun4u: split NPT and INT_DIS accesses between timer and compare registers sun4u: split out NPT and INT_DIS into separate CPUTimer fields Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
263699432c
@ -363,6 +363,8 @@ void cpu_put_timer(QEMUFile *f, CPUTimer *s)
|
||||
qemu_put_be32s(f, &s->frequency);
|
||||
qemu_put_be32s(f, &s->disabled);
|
||||
qemu_put_be64s(f, &s->disabled_mask);
|
||||
qemu_put_be32s(f, &s->npt);
|
||||
qemu_put_be64s(f, &s->npt_mask);
|
||||
qemu_put_sbe64s(f, &s->clock_offset);
|
||||
|
||||
timer_put(f, s->qtimer);
|
||||
@ -373,6 +375,8 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
|
||||
qemu_get_be32s(f, &s->frequency);
|
||||
qemu_get_be32s(f, &s->disabled);
|
||||
qemu_get_be64s(f, &s->disabled_mask);
|
||||
qemu_get_be32s(f, &s->npt);
|
||||
qemu_get_be64s(f, &s->npt_mask);
|
||||
qemu_get_sbe64s(f, &s->clock_offset);
|
||||
|
||||
timer_get(f, s->qtimer);
|
||||
@ -380,15 +384,17 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
|
||||
|
||||
static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
|
||||
QEMUBHFunc *cb, uint32_t frequency,
|
||||
uint64_t disabled_mask)
|
||||
uint64_t disabled_mask, uint64_t npt_mask)
|
||||
{
|
||||
CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
|
||||
|
||||
timer->name = name;
|
||||
timer->frequency = frequency;
|
||||
timer->disabled_mask = disabled_mask;
|
||||
timer->npt_mask = npt_mask;
|
||||
|
||||
timer->disabled = 1;
|
||||
timer->npt = 1;
|
||||
timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
|
||||
timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
|
||||
@ -494,17 +500,17 @@ static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
|
||||
|
||||
void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
|
||||
{
|
||||
uint64_t real_count = count & ~timer->disabled_mask;
|
||||
uint64_t disabled_bit = count & timer->disabled_mask;
|
||||
uint64_t real_count = count & ~timer->npt_mask;
|
||||
uint64_t npt_bit = count & timer->npt_mask;
|
||||
|
||||
int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
|
||||
cpu_to_timer_ticks(real_count, timer->frequency);
|
||||
|
||||
TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
|
||||
TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n",
|
||||
timer->name, real_count,
|
||||
timer->disabled?"disabled":"enabled", timer);
|
||||
timer->npt ? "disabled" : "enabled", timer);
|
||||
|
||||
timer->disabled = disabled_bit ? 1 : 0;
|
||||
timer->npt = npt_bit ? 1 : 0;
|
||||
timer->clock_offset = vm_clock_offset;
|
||||
}
|
||||
|
||||
@ -514,12 +520,13 @@ uint64_t cpu_tick_get_count(CPUTimer *timer)
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
|
||||
timer->frequency);
|
||||
|
||||
TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
|
||||
TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n",
|
||||
timer->name, real_count,
|
||||
timer->disabled?"disabled":"enabled", timer);
|
||||
timer->npt ? "disabled" : "enabled", timer);
|
||||
|
||||
if (timer->disabled)
|
||||
real_count |= timer->disabled_mask;
|
||||
if (timer->npt) {
|
||||
real_count |= timer->npt_mask;
|
||||
}
|
||||
|
||||
return real_count;
|
||||
}
|
||||
@ -799,13 +806,16 @@ static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
|
||||
env = &cpu->env;
|
||||
|
||||
env->tick = cpu_timer_create("tick", cpu, tick_irq,
|
||||
tick_frequency, TICK_NPT_MASK);
|
||||
tick_frequency, TICK_INT_DIS,
|
||||
TICK_NPT_MASK);
|
||||
|
||||
env->stick = cpu_timer_create("stick", cpu, stick_irq,
|
||||
stick_frequency, TICK_INT_DIS);
|
||||
stick_frequency, TICK_INT_DIS,
|
||||
TICK_NPT_MASK);
|
||||
|
||||
env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
|
||||
hstick_frequency, TICK_INT_DIS);
|
||||
hstick_frequency, TICK_INT_DIS,
|
||||
TICK_NPT_MASK);
|
||||
|
||||
reset_info = g_malloc0(sizeof(ResetData));
|
||||
reset_info->cpu = cpu;
|
||||
|
@ -366,6 +366,8 @@ struct CPUTimer
|
||||
uint32_t frequency;
|
||||
uint32_t disabled;
|
||||
uint64_t disabled_mask;
|
||||
uint32_t npt;
|
||||
uint64_t npt_mask;
|
||||
int64_t clock_offset;
|
||||
QEMUTimer *qtimer;
|
||||
};
|
||||
|
@ -51,10 +51,16 @@ void helper_tick_set_count(void *opaque, uint64_t count)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t helper_tick_get_count(void *opaque)
|
||||
uint64_t helper_tick_get_count(CPUSPARCState *env, void *opaque, int mem_idx)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
return cpu_tick_get_count(opaque);
|
||||
CPUTimer *timer = opaque;
|
||||
|
||||
if (timer->npt && mem_idx < MMU_KERNEL_IDX) {
|
||||
helper_raise_exception(env, TT_PRIV_INSN);
|
||||
}
|
||||
|
||||
return cpu_tick_get_count(timer);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -25,7 +25,7 @@ DEF_HELPER_2(set_softint, void, env, i64)
|
||||
DEF_HELPER_2(clear_softint, void, env, i64)
|
||||
DEF_HELPER_2(write_softint, void, env, i64)
|
||||
DEF_HELPER_2(tick_set_count, void, ptr, i64)
|
||||
DEF_HELPER_1(tick_get_count, i64, ptr)
|
||||
DEF_HELPER_3(tick_get_count, i64, env, ptr, int)
|
||||
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
|
||||
#endif
|
||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
||||
|
@ -2708,12 +2708,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
case 0x4: /* V9 rdtick */
|
||||
{
|
||||
TCGv_ptr r_tickptr;
|
||||
TCGv_i32 r_const;
|
||||
|
||||
r_tickptr = tcg_temp_new_ptr();
|
||||
r_const = tcg_const_i32(dc->mem_idx);
|
||||
tcg_gen_ld_ptr(r_tickptr, cpu_env,
|
||||
offsetof(CPUSPARCState, tick));
|
||||
gen_helper_tick_get_count(cpu_dst, r_tickptr);
|
||||
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
|
||||
r_const);
|
||||
tcg_temp_free_ptr(r_tickptr);
|
||||
tcg_temp_free_i32(r_const);
|
||||
gen_store_gpr(dc, rd, cpu_dst);
|
||||
}
|
||||
break;
|
||||
@ -2750,12 +2754,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
case 0x18: /* System tick */
|
||||
{
|
||||
TCGv_ptr r_tickptr;
|
||||
TCGv_i32 r_const;
|
||||
|
||||
r_tickptr = tcg_temp_new_ptr();
|
||||
r_const = tcg_const_i32(dc->mem_idx);
|
||||
tcg_gen_ld_ptr(r_tickptr, cpu_env,
|
||||
offsetof(CPUSPARCState, stick));
|
||||
gen_helper_tick_get_count(cpu_dst, r_tickptr);
|
||||
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
|
||||
r_const);
|
||||
tcg_temp_free_ptr(r_tickptr);
|
||||
tcg_temp_free_i32(r_const);
|
||||
gen_store_gpr(dc, rd, cpu_dst);
|
||||
}
|
||||
break;
|
||||
@ -2863,12 +2871,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
|
||||
case 4: // tick
|
||||
{
|
||||
TCGv_ptr r_tickptr;
|
||||
TCGv_i32 r_const;
|
||||
|
||||
r_tickptr = tcg_temp_new_ptr();
|
||||
r_const = tcg_const_i32(dc->mem_idx);
|
||||
tcg_gen_ld_ptr(r_tickptr, cpu_env,
|
||||
offsetof(CPUSPARCState, tick));
|
||||
gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
|
||||
gen_helper_tick_get_count(cpu_tmp0, cpu_env,
|
||||
r_tickptr, r_const);
|
||||
tcg_temp_free_ptr(r_tickptr);
|
||||
tcg_temp_free_i32(r_const);
|
||||
}
|
||||
break;
|
||||
case 5: // tba
|
||||
|
Loading…
Reference in New Issue
Block a user