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:
Peter Maydell 2016-01-07 13:33:19 +00:00
commit 263699432c
5 changed files with 49 additions and 19 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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)

View File

@ -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