qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Scott Wood <scottwood@freescale.com>
To: Fabien Chouteau <chouteau@adacore.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH V2] [PowerPC][RFC] booke timers
Date: Fri, 1 Jul 2011 15:22:44 -0500	[thread overview]
Message-ID: <20110701152244.278e720b@schlenkerla.am.freescale.net> (raw)
In-Reply-To: <1309529621-27691-1-git-send-email-chouteau@adacore.com>

On Fri, 1 Jul 2011 16:13:41 +0200
Fabien Chouteau <chouteau@adacore.com> wrote:

> +uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset)
>  {
>      /* TB time in tb periods */
>      return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset;
> @@ -678,18 +661,23 @@ static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp,
>                  decr, value);
>      now = qemu_get_clock_ns(vm_clock);
>      next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
> -    if (is_excp)
> +    if (is_excp) {
>          next += *nextp - now;
> -    if (next == now)
> +    }
> +    if (next == now) {
>          next++;
> +    }
>      *nextp = next;
>      /* Adjust timer */
>      qemu_mod_timer(timer, next);
>      /* If we set a negative value and the decrementer was positive,
> -     * raise an exception.
> +     * raise an exception (not for booke).
>       */
> -    if ((value & 0x80000000) && !(decr & 0x80000000))
> +    if (! (env->insns_flags & PPC_BOOKE)
> +        && (value & 0x80000000)
> +        && !(decr & 0x80000000)) {
>          (*raise_excp)(env);
> +    }
>  }
>  

Also, load_decr should go from this:

    if (diff >= 0)
        decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
    else
        decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec());

to something like this:

    if (diff >= 0) {
        decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
    } else if (env->insns_flags & PPC_BOOKE) {
        decr = 0;
    } else {
        decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec());
    }

> +/* Return the location of the bit of time base at which the FIT will raise an
> +   interrupt */
> +static uint8_t booke_get_fit_target(CPUState *env)
> +{
> +    uint8_t fp = (env->spr[SPR_BOOKE_TCR] & TCR_FP_MASK) >> TCR_FP_SHIFT;
> +
> +    /* Only for e500 */
> +    if (env->insns_flags2 & PPC2_E500) {
> +        uint32_t fpext = (env->spr[SPR_BOOKE_TCR] & TCR_E500_FPEXT_MASK)
> +            >> TCR_E500_FPEXT_SHIFT;
> +        fp |= fpext << 2;
> +    } else {
> +        fp = env->fit_period[fp];
> +    }
> +
> +    return fp;
> +}
> +
> +/* Return the location of the bit of time base at which the WDT will raise an
> +   interrupt */
> +static uint8_t booke_get_wdt_target(CPUState *env)
> +{
> +    uint8_t wp = (env->spr[SPR_BOOKE_TCR] & TCR_WP_MASK) >> TCR_WP_SHIFT;
> +
> +    /* Only for e500 */
> +    if (env->insns_flags2 & PPC2_E500) {
> +        uint32_t wpext = (env->spr[SPR_BOOKE_TCR] & TCR_E500_WPEXT_MASK)
> +            >> TCR_E500_WPEXT_SHIFT;
> +        wp |= wpext << 2;
> +    } else {
> +        wp = env->wdt_period[wp];
> +    }
> +
> +    return wp;
> +}

e500 fp/wp is expressed as bits from the MSB side of TB, so we need to
subtract from 63 to get something sane -- and document that fit/wdt_period
is from the LSB side.

> +static void booke_update_fixed_timer(CPUState         *env,
> +                                     uint8_t           target_bit,
> +                                     uint64_t          *next,
> +                                     struct QEMUTimer *timer)
> +{
> +    ppc_tb_t *tb_env = env->tb_env;
> +    uint64_t lapse;
> +    uint64_t tb;
> +    uint64_t period = 1 << (target_bit + 1);
> +    uint64_t now;
> +
> +    now = qemu_get_clock_ns(vm_clock);
> +    tb  = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
> +
> +    if (tb <= (1 << target_bit)) {
> +        lapse = (1 << target_bit) - tb;
> +    } else {
> +        lapse = period - ((tb - (1 << target_bit)) % period);

We know period is a power of two, so just do "& (period - 1)".

That should let you get rid of the special case for
"tb <= (1 << target_bit)" as well.

-Scott

  reply	other threads:[~2011-07-01 20:22 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-01 14:13 [Qemu-devel] [PATCH V2] [PowerPC][RFC] booke timers Fabien Chouteau
2011-07-01 20:22 ` Scott Wood [this message]
2011-07-04 15:06   ` Fabien Chouteau
2011-07-05 16:02     ` Scott Wood
2011-07-05 16:41       ` Fabien Chouteau
2011-07-05 18:05         ` Scott Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110701152244.278e720b@schlenkerla.am.freescale.net \
    --to=scottwood@freescale.com \
    --cc=chouteau@adacore.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).