From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>,
"Sergey Fedorov" <serge.fdrv@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"QEMU Developers" <qemu-devel@nongnu.org>,
"Alexander Graf" <agraf@suse.de>
Subject: Re: [Qemu-devel] [PATCH v4 1/6] target-arm: Add CNTVOFF_EL2
Date: Mon, 15 Jun 2015 10:52:00 +1000 [thread overview]
Message-ID: <20150615005200.GP17878@toto> (raw)
In-Reply-To: <CAFEAcA9XGnmyc8OeRnt9nQZjk-mmizkRV9fPa50hE=TgfF+13Q@mail.gmail.com>
On Fri, Jun 12, 2015 at 05:44:24PM +0100, Peter Maydell wrote:
> On 5 June 2015 at 11:33, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> >
> > Adds support for the virtual timer offset controlled by EL2.
> >
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> > ---
>
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -1208,9 +1208,20 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
> > /* Timer enabled: calculate and set current ISTATUS, irq, and
> > * reset timer to when ISTATUS next has to change
> > */
> > + uint64_t offset = timeridx == GTIMER_VIRT ?
> > + cpu->env.cp15.cntvoff_el2 : 0;
> > uint64_t count = gt_get_countervalue(&cpu->env);
> > - /* Note that this must be unsigned 64 bit arithmetic: */
> > - int istatus = count >= gt->cval;
> > + /* The ARM spec says that count, offset and gt->cval are all
> > + * unsigned 64bit values.
> > + * The event trig is described as:
> > + * (Counter[63:0] - Offset[63:0])[63:0] - CompareValue[63:0]) >= 0
> > + *
> > + * We do the subtractions as unsigned values to avoid under/overflowing
> > + * signed integers (undefined behaviour in C).
> > + * To be able to do the compare >= 0 we cast the result into a
> > + * signed int64_t.
> > + */
> > + int istatus = (int64_t) (count - offset - gt->cval) >= 0;
>
> This is wrong. Consider the case where:
> count is 0x1000,0000,0000,0002 (it's a really large unsigned number)
> offset is zero
> cval is 1
>
> The ARM ARM required calculation gives you
> 0x1000,0000,0000,0002 - 1 >= 0
> ie 0x1000,0000,0000,0001 >= 0
> which is true. (Note that ARM ARM pseudocode works with infinite
> precision integers, not 2s-complement.)
>
> With your code:
> (count - offset - gt->cval) is 0x1000,0000,0000,0001
> Cast to an int64_t this is negative (top bit is set)
> Comparison against 0 is done as a signed value, and returns false.
>
> This is exactly the tricky case which is why we must do this as unsigned
> arithmetic.
>
> What you want is
> int istatus = count - offset >= gt->cval;
>
> which comes out to
> 0x1000,0000,0000,0002 >= 1
> which is true.
>
> (That's the code we had before, but just "use 'count - offset' rather than
> 'count'".)
Thanks, I've changed it to what you suggest allthough I'm probably missing
something cause I'm still finding the spec confusing :S
> > @@ -1265,17 +1281,19 @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
> > static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
> > {
> > int timeridx = ri->crm & 1;
> > + uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0;
> >
> > return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
> > - gt_get_countervalue(env));
> > + gt_get_countervalue(env) - offset);
>
> The docs say that the timerval read view is
> (comparevalue - (counter - offset))
> not (comparevalue - counter - offset)...
Fixed for next version.
Cheers,
Edgar
>
> > }
>
> Looks OK otherwise.
>
> thanks
> -- PMM
next prev parent reply other threads:[~2015-06-15 0:56 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-05 10:33 [Qemu-devel] [PATCH v4 0/6] arm: Steps towards EL2 support round 3 Edgar E. Iglesias
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 1/6] target-arm: Add CNTVOFF_EL2 Edgar E. Iglesias
2015-06-12 16:44 ` Peter Maydell
2015-06-15 0:52 ` Edgar E. Iglesias [this message]
2015-06-15 10:51 ` Peter Maydell
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 2/6] target-arm: Add CNTHCTL_EL2 Edgar E. Iglesias
2015-06-12 16:51 ` Peter Maydell
2015-06-15 1:03 ` Edgar E. Iglesias
2015-06-15 7:29 ` Peter Maydell
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 3/6] target-arm: Pass timeridx as argument to various timer functions Edgar E. Iglesias
2015-06-12 16:54 ` Peter Maydell
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 4/6] target-arm: Add the Hypervisor timer Edgar E. Iglesias
2015-06-12 17:00 ` Peter Maydell
2015-06-15 1:29 ` Edgar E. Iglesias
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 5/6] hw/arm/virt: Replace magic IRQ constants with macros Edgar E. Iglesias
2015-06-12 17:02 ` Peter Maydell
2015-06-05 10:33 ` [Qemu-devel] [PATCH v4 6/6] hw/arm/virt: Connect the Hypervisor timer Edgar E. Iglesias
2015-06-12 17:03 ` Peter Maydell
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=20150615005200.GP17878@toto \
--to=edgar.iglesias@xilinx.com \
--cc=agraf@suse.de \
--cc=alex.bennee@linaro.org \
--cc=edgar.iglesias@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=serge.fdrv@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.