From: "Andreas Färber" <andreas.faerber@web.de>
To: Alex Horn <alex.horn@cs.ox.ac.uk>
Cc: Blue Swirl <blauwirbel@gmail.com>,
peter.maydell@linaro.org, qemu-devel@nongnu.org,
anthony@codemonkey.ws
Subject: Re: [Qemu-devel] [PATCH 1/1] tmp105: Fix I2C protocol bug
Date: Wed, 12 Dec 2012 05:34:51 +0100 [thread overview]
Message-ID: <50C8096B.60202@web.de> (raw)
In-Reply-To: <1354736883-22417-1-git-send-email-alex.horn@cs.ox.ac.uk>
Am 05.12.2012 20:48, schrieb Alex Horn:
> The private buffer length field must only be incremented after the I2C
> frame has been transmitted.
>
> To expose this bug, assume the temperature in the TMP105 hardware model
> is +0.125 C (e.g. snow slush). Note that eleven bit precision is required
> to read this value; otherwise the reading is equal to zero centigrade (ice).
>
> Continue by considering the following I2C protocol steps:
>
> 1) Start transfer with I2C_START_SEND
> 2) Send byte 0x01 (i.e. configuration register)
> 3) Send byte 0x40 (i.e. eleven bit precision)
> 4) End transfer with I2C_FINISH
>
> 5) Start transfer with I2C_START_SEND
> 6) Send byte 0x00 (i.e. temperature register)
> 7) End transfer I2C_FINISH
>
> 8) Start transfer with I2C_START_RECV
> 9) Receive high-order byte of temperature
> ...
>
> In step (1), the function tmp105_tx() is called. By the conditional
> check !s->len and the side effect with ++, s->len is equal to 1 when
> step (2) begins. Thus, 0x40 is written to s->buf[1] in step (3).
> By definition of tmp105_write(), s->config is set to zero in step (3).
> Thus, when we read the higher-order byte in step (9), it is zero!
>
> In other words, the TMP105 hardware model allows us to measure 0 C (ice)
> even with eleven bit precision when, in fact, it should be 0.125 C (slush)!
>
> Signed-off-by: Alex Horn <alex.horn@cs.ox.ac.uk>
> ---
> hw/tmp105.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/hw/tmp105.c b/hw/tmp105.c
> index 8e8dbd9..5f41a3f 100644
> --- a/hw/tmp105.c
> +++ b/hw/tmp105.c
> @@ -152,7 +152,7 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data)
> {
> TMP105State *s = (TMP105State *) i2c;
>
> - if (!s->len ++)
> + if (s->len == 0)
> s->pointer = data;
> else {
> if (s->len <= 2)
> @@ -160,6 +160,7 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data)
> tmp105_write(s);
> }
>
> + s->len ++;
> return 0;
> }
>
This fix leaves setting the upper and lower limits (commands 2 and 3)
broken. The following works for me:
diff --git a/hw/tmp105.c b/hw/tmp105.c
index 8e8dbd9..512fe0c 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -152,11 +152,14 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data)
{
TMP105State *s = (TMP105State *) i2c;
- if (!s->len ++)
+ if (s->len == 0) {
s->pointer = data;
- else {
- if (s->len <= 2)
+ s->len++;
+ } else {
+ if (s->len <= 2) {
s->buf[s->len - 1] = data;
+ }
+ s->len++;
tmp105_write(s);
}
The trick is incrementing before the tmp105_write() call but after the
length check and buffer fill.
I've hacked together a real qtest using the n800's omap_i2c that I'll
send out. It sets and reads back the limits, failing in master.
Andreas
prev parent reply other threads:[~2012-12-12 4:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-05 19:48 [Qemu-devel] [PATCH 1/1] tmp105: Fix I2C protocol bug Alex Horn
2012-12-06 21:21 ` Blue Swirl
2012-12-07 13:12 ` Alex Horn
2012-12-12 4:34 ` Andreas Färber [this message]
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=50C8096B.60202@web.de \
--to=andreas.faerber@web.de \
--cc=alex.horn@cs.ox.ac.uk \
--cc=anthony@codemonkey.ws \
--cc=blauwirbel@gmail.com \
--cc=peter.maydell@linaro.org \
--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 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.