All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Michael Davidsaver <mdavidsaver@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Thomas Huth <thuth@redhat.com>,
	Antoine Mathys <barsamin@gmail.com>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 05/14] timer: ds1338 change write handling and fix wday_offset handling
Date: Mon, 16 Jul 2018 14:25:44 +1000	[thread overview]
Message-ID: <20180716042544.GH2599@umbus.fritz.box> (raw)
In-Reply-To: <20180705182001.16537-6-mdavidsaver@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5605 bytes --]

On Thu, Jul 05, 2018 at 11:19:52AM -0700, Michael Davidsaver wrote:
> instead of a read-modify-write, do direct translation
> of device registers to struct tm members.
> 
> This new ds1338_update() is the reverse of
> the existing capture_current_time().
> 
> Simplifies later handling of CENTURY bit in
> similar Dallas RTC chips.
> 
> Correctly handle different real weekday in
> guest and host timezones.
> Allow guest to use any day as start of week
> (day 1).  eg. Monday instead of Sunday.
> 
> Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
> ---
>  hw/timer/ds1338.c | 95 ++++++++++++++++++++++++++++---------------------------
>  1 file changed, 48 insertions(+), 47 deletions(-)
> 
> diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c
> index 637a0f4246..0134ffd72a 100644
> --- a/hw/timer/ds1338.c
> +++ b/hw/timer/ds1338.c
> @@ -110,7 +110,10 @@ static void capture_current_time(DS1338State *s)
>          /* 24 hour mode. */
>          s->nvram[R_HOUR] = to_bcd(now.tm_hour);
>      }
> -    s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7 + 1;
> +    s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7;
> +    if (s->nvram[R_WDAY] == 0) {
> +        s->nvram[R_WDAY] = 7;
> +    }

This looks a bit odd - you've removed the + 1 here, but...

>      s->nvram[R_DATE] = to_bcd(now.tm_mday);
>      s->nvram[R_MONTH] = to_bcd(now.tm_mon + 1);
>      s->nvram[R_YEAR] = to_bcd(now.tm_year - 100);
> @@ -161,6 +164,46 @@ static int ds1338_recv(I2CSlave *i2c)
>      return res;
>  }
>  
> +/* call after guest writes to current time registers
> + * to re-compute our offset from host time.
> + */
> +static void ds1338_update(DS1338State *s)
> +{
> +
> +    struct tm now = {};
> +
> +    /* TODO: Implement CH (stop) bit?  */
> +    now.tm_sec = from_bcd(s->nvram[R_SEC] & 0x7f);
> +    now.tm_min = from_bcd(s->nvram[R_MIN] & 0x7f);
> +    if (ARRAY_FIELD_EX32(s->nvram, HOUR, SET12)) {
> +        /* 12 hour (1-12) */
> +        /* read and wrap 1-12 -> 0-11 */
> +        now.tm_hour = from_bcd(ARRAY_FIELD_EX32(s->nvram, HOUR, HOUR12)) % 12u;
> +        if (ARRAY_FIELD_EX32(s->nvram, HOUR, AMPM)) {
> +            now.tm_hour += 12;
> +        }
> +
> +    } else {
> +        now.tm_hour = from_bcd(ARRAY_FIELD_EX32(s->nvram, HOUR, HOUR24));
> +    }
> +    now.tm_wday = from_bcd(s->nvram[R_WDAY]) - 1u;

.. you still have the -1 here.  Am I missing something?

> +    now.tm_mday = from_bcd(s->nvram[R_DATE] & 0x3f);
> +    now.tm_mon = from_bcd(s->nvram[R_MONTH] & 0x1f) - 1;
> +    now.tm_year = from_bcd(s->nvram[R_YEAR]) + 100;
> +    s->offset = qemu_timedate_diff(&now);
> +
> +    {
> +        /* Round trip to get real wday_offset based on time delta and
> +         * ref. timezone.
> +         * Race if midnight (in ref. timezone) happens here.
> +         */
> +        int user_wday = now.tm_wday;
> +        qemu_get_timedate(&now, s->offset);
> +
> +        s->wday_offset = (user_wday - now.tm_wday) % 7 + 1;
> +    }
> +}
> +
>  static int ds1338_send(I2CSlave *i2c, uint8_t data)
>  {
>      DS1338State *s = DS1338(i2c);
> @@ -170,52 +213,7 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
>          s->addr_byte = false;
>          return 0;
>      }
> -    if (s->ptr < 7) {
> -        /* Time register. */
> -        struct tm now;
> -        qemu_get_timedate(&now, s->offset);
> -        switch(s->ptr) {
> -        case R_SEC:
> -            /* TODO: Implement CH (stop) bit.  */
> -            now.tm_sec = from_bcd(data & 0x7f);
> -            break;
> -        case R_MIN:
> -            now.tm_min = from_bcd(data & 0x7f);
> -            break;
> -        case R_HOUR:
> -            if (FIELD_EX32(data, HOUR, SET12)) {
> -                /* 12 hour (1-12) */
> -                /* read and wrap 1-12 -> 0-11 */
> -                now.tm_hour = from_bcd(FIELD_EX32(data, HOUR, HOUR12)) % 12u;
> -                if (FIELD_EX32(data, HOUR, AMPM)) {
> -                    now.tm_hour += 12;
> -                }
> -
> -            } else {
> -                now.tm_hour = from_bcd(FIELD_EX32(data, HOUR, HOUR24));
> -            }
> -            break;
> -        case R_WDAY:
> -            {
> -                /* The day field is supposed to contain a value in
> -                   the range 1-7. Otherwise behavior is undefined.
> -                 */
> -                int user_wday = (data & 7) - 1;
> -                s->wday_offset = (user_wday - now.tm_wday + 7) % 7;
> -            }
> -            break;
> -        case R_DATE:
> -            now.tm_mday = from_bcd(data & 0x3f);
> -            break;
> -        case R_MONTH:
> -            now.tm_mon = from_bcd(data & 0x1f) - 1;
> -            break;
> -        case R_YEAR:
> -            now.tm_year = from_bcd(data) + 100;
> -            break;
> -        }
> -        s->offset = qemu_timedate_diff(&now);
> -    } else if (s->ptr == R_CTRL) {
> +    if (s->ptr == R_CTRL) {
>          /* Control register. */
>  
>          /* Ensure bits 2, 3 and 6 will read back as zero. */
> @@ -227,6 +225,9 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
>  
>      }
>      s->nvram[s->ptr] = data;
> +    if (s->ptr <= R_YEAR) {
> +        ds1338_update(s);
> +    }
>      inc_regptr(s);
>      return 0;
>  }

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2018-07-16  5:51 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-05 18:19 [Qemu-devel] [PATCH 00/14] Generalize Dallas/Maxim I2C RTC devices v3 Michael Davidsaver
2018-07-05 18:19 ` [Qemu-devel] [PATCH 01/14] tests: more thorough tests of ds1338 Michael Davidsaver
2018-07-17 15:28   ` Peter Maydell
2018-07-05 18:19 ` [Qemu-devel] [PATCH 02/14] timer: ds1338 use registerfields.h Michael Davidsaver
2018-07-06  1:35   ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 03/14] timer: ds1338 persist 12-hour mode selection Michael Davidsaver
2018-07-06  3:39   ` David Gibson
2018-07-06  4:35     ` Michael Davidsaver
2018-07-07 17:59       ` Michael Davidsaver
2018-07-09  5:09       ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 04/14] timer: ds1338 clarify HOUR handling Michael Davidsaver
2018-07-09  5:12   ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 05/14] timer: ds1338 change write handling and fix wday_offset handling Michael Davidsaver
2018-07-16  4:25   ` David Gibson [this message]
2018-07-05 18:19 ` [Qemu-devel] [PATCH 06/14] tests: ds-rtc test 12 hour mode Michael Davidsaver
2018-07-07 17:49   ` [Qemu-devel] [PATCH v2 " Michael Davidsaver
2018-07-09  6:49     ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 07/14] tests: ds-rtc test wday offset Michael Davidsaver
2018-07-07 17:50   ` [Qemu-devel] [PATCH v2 " Michael Davidsaver
2018-07-09  6:50     ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 08/14] timer: rename ds1338 -> dsrtc Michael Davidsaver
2018-07-05 18:19 ` [Qemu-devel] [PATCH 09/14] timer: rename file ds1338.c -> ds-rtc.c Michael Davidsaver
2018-07-05 18:19 ` [Qemu-devel] [PATCH 10/14] timer: ds1338 remove vestige of un-modeled OSF Michael Davidsaver
2018-07-16  4:26   ` David Gibson
2018-07-05 18:19 ` [Qemu-devel] [PATCH 12/14] timer: ds-rtc handle CENTURY bit Michael Davidsaver
2018-07-16  9:43   ` David Gibson
2018-07-05 18:20 ` [Qemu-devel] [PATCH 13/14] timer: ds-rtc model ds1375 Michael Davidsaver
2018-07-16  9:44   ` David Gibson
2018-07-05 18:20 ` [Qemu-devel] [PATCH 14/14] tests: drop ds1338-test Michael Davidsaver
2018-07-17 15:23   ` Peter Maydell
     [not found] ` <20180705182001.16537-12-mdavidsaver@gmail.com>
2018-07-16  9:19   ` [Qemu-devel] [PATCH 11/14] timer: generalize ds1338 David Gibson

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=20180716042544.GH2599@umbus.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=barsamin@gmail.com \
    --cc=mdavidsaver@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.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.