From: "Philippe Mathieu-Daudé" <philmd@redhat.com>
To: Niek Linnenbank <nieklinnenbank@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
qemu-arm <qemu-arm@nongnu.org>,
QEMU Developers <qemu-devel@nongnu.org>,
Laurent Vivier <laurent@vivier.eu>
Subject: Re: [PATCH v3 12/17] hw/arm/allwinner: add RTC device support
Date: Sat, 18 Jan 2020 16:05:29 +0100 [thread overview]
Message-ID: <128940fd-eda9-8151-eb4f-4d29c2c1d72a@redhat.com> (raw)
In-Reply-To: <CAPan3WrkQVb7VhJRYZET_BjEWEOYow-28ft2+4=G-9SNUDm6WA@mail.gmail.com>
Hi Niek,
On 1/14/20 11:57 PM, Niek Linnenbank wrote:
> On Tue, Jan 14, 2020 at 11:52 PM Niek Linnenbank
> <nieklinnenbank@gmail.com <mailto:nieklinnenbank@gmail.com>> wrote:
>
> Hi Philippe,
>
> On Mon, Jan 13, 2020 at 11:57 PM Philippe Mathieu-Daudé
> <philmd@redhat.com <mailto:philmd@redhat.com>> wrote:
>
> On 1/8/20 9:00 PM, Niek Linnenbank wrote:
> > Allwinner System-on-Chips usually contain a Real Time Clock (RTC)
> > for non-volatile system date and time keeping. This commit
> adds a generic
> > Allwinner RTC device that supports the RTC devices found in
> Allwinner SoC
> > family sun4i (A10), sun7i (A20) and sun6i and newer (A31,
> H2+, H3, etc).
[...]
> > +static uint64_t allwinner_rtc_read(void *opaque, hwaddr offset,
> > + unsigned size)
> > +{
> > + AwRtcState *s = AW_RTC(opaque);
> > + const AwRtcClass *c = AW_RTC_GET_CLASS(s);
> > + uint64_t val = 0;
> > +
> > + if (offset >= AW_RTC_REGS_MAXADDR) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
> offset 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + return 0;
> > + }
> > +
> > + if (!c->regmap[offset]) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
> register 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + return 0;
> > + }
> > +
> > + switch (c->regmap[offset]) {
> > + case REG_LOSC: /* Low Oscillator Control */
> > + val = s->regs[REG_LOSC];
> > + s->regs[REG_LOSC] &= ~(REG_LOSC_YMD | REG_LOSC_HMS);
> > + break;
> > + case REG_YYMMDD: /* RTC Year-Month-Day */
> > + case REG_HHMMSS: /* RTC Hour-Minute-Second */
> > + case REG_GP0: /* General Purpose Register 0 */
> > + case REG_GP1: /* General Purpose Register 1 */
> > + case REG_GP2: /* General Purpose Register 2 */
> > + case REG_GP3: /* General Purpose Register 3 */
> > + val = s->regs[c->regmap[offset]];
> > + break;
> > + default:
> > + if (!c->read(s, offset)) {
> > + qemu_log_mask(LOG_UNIMP, "%s: unimplemented
> register 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + }
> > + val = s->regs[c->regmap[offset]];
> > + break;
> > + }
> > +
> > + trace_allwinner_rtc_read(offset, val);
> > + return val;
> > +}
> > +
> > +static void allwinner_rtc_write(void *opaque, hwaddr offset,
> > + uint64_t val, unsigned size)
> > +{
> > + AwRtcState *s = AW_RTC(opaque);
> > + const AwRtcClass *c = AW_RTC_GET_CLASS(s);
> > +
> > + if (offset >= AW_RTC_REGS_MAXADDR) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds
> offset 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + return;
> > + }
> > +
> > + if (!c->regmap[offset]) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid
> register 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + return;
> > + }
> > +
> > + trace_allwinner_rtc_write(offset, val);
> > +
> > + switch (c->regmap[offset]) {
> > + case REG_YYMMDD: /* RTC Year-Month-Day */
> > + s->regs[REG_YYMMDD] = val;
> > + s->regs[REG_LOSC] |= REG_LOSC_YMD;
> > + break;
> > + case REG_HHMMSS: /* RTC Hour-Minute-Second */
> > + s->regs[REG_HHMMSS] = val;
> > + s->regs[REG_LOSC] |= REG_LOSC_HMS;
> > + break;
> > + case REG_GP0: /* General Purpose Register 0 */
> > + case REG_GP1: /* General Purpose Register 1 */
> > + case REG_GP2: /* General Purpose Register 2 */
> > + case REG_GP3: /* General Purpose Register 3 */
> > + s->regs[c->regmap[offset]] = val;
> > + break;
> > + default:
> > + if (!c->write(s, offset, val)) {
> > + qemu_log_mask(LOG_UNIMP, "%s: unimplemented
> register 0x%04x\n",
> > + __func__, (uint32_t)offset);
> > + }
> > + break;
> > + }
> > +}
> > +
> > +static const MemoryRegionOps allwinner_rtc_ops = {
> > + .read = allwinner_rtc_read,
> > + .write = allwinner_rtc_write,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .valid = {
> > + .min_access_size = 4,
> > + .max_access_size = 4,
> > + },
> > + .impl.min_access_size = 4,
> > +};
> > +
> > +static void allwinner_rtc_reset(DeviceState *dev)
> > +{
> > + AwRtcState *s = AW_RTC(dev);
> > + const AwRtcClass *c = AW_RTC_GET_CLASS(dev);
> > + struct tm now;
> > +
> > + /* Clear registers */
> > + memset(s->regs, 0, sizeof(s->regs));
> > +
> > + /* Get current datetime */
> > + qemu_get_timedate(&now, 0);
> > +
> > + /* Set RTC with current datetime */
> > + s->regs[REG_YYMMDD] = ((now.tm_year - c->year_offset)
> << 16) |
> > + ((now.tm_mon + 1) << 8) |
> > + now.tm_mday;
> > + s->regs[REG_HHMMSS] = (((now.tm_wday + 6) % 7) << 29) |
> > + (now.tm_hour << 16) |
> > + (now.tm_min << 8) |
> > + now.tm_sec;
>
> This doesn't look correct.
>
> From H3 Datasheet (Rev1.2):
> 4.8.3.4. RTC YY-MM-DD Register (Default Value: 0x00000000)
> 4.8.3.5. RTC HH-MM-SS Register (Default Value: 0x00000000)
>
>
> I don't yet fully understand what you mean. Could you please explain
> a bit more what should be changed?
I was thinking about:
- Start a VM on Monday at 12:34
- Pause the VM on Tuesday at 12:34
rtc_time=Tuesday,12:34
- [Eventually savevm/migrate/loadvm]
rtc_time=Tuesday,12:34
- Resume the VM on Wednesday 12:34
(time should be Tuesday at 12:34)
so rtc_time=Tuesday,12:34
- Check time on Thursday at 12:33
(time should be Wednesday at 12:33)
rtc_time=Wednesday,12:34
- Reset the VM on Thursday at 12:34
(time was Wednesday at 12:34)
- Check time on Thursday at 12:35
(time should be Wednesday at 12:35)
However due to reset() calling qemu_get_timedate(), the rtc_time will be
Thursday at 12:35 instead of Wednesday.
I don't know how the hardware keep these 2*32-bit safe when powered off.
Laurent Vivier posted a patch where he uses a block backend for his
machine NVRAM (used by RTC). This seems to me the clever way to do this:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg666837.html
I'd use a block of 8 bytes for your RTC.
If we start a machine without rtc block backend, the 2*32-bit are
initialized as zero as the datasheet. If we provide a block, the machine
will power-on from that stored time.
You might want to look at the global -rtc command line option:
-rtc
[base=utc|localtime|datetime][,clock=host|rt|vm][,driftfix=none|slew]
Specify base as "utc" or "localtime" to let the RTC start
at the current UTC or local time, respectively. "localtime"
is required for correct date in MS-DOS or Windows. To start
at a specific point in time, provide datetime in the format
"2006-06-17T16:01:21" or "2006-06-17". The default base is
UTC.
But it might be specific to the MC146818 RTC.
> For filling the YYMMDD and HHMMSS register fields, I simply looked
> at the 4.8.3.4 and 4.8.3.5 sections
> and filled it with the time retrieved from qemu_get_timedate. The
> shifts are done so the values are set in the proper bits.
> If I read it with the hwclock -r command under Linux, this reads out OK.
> On NetBSD, this works as well, except for the base year mismatch
> which I explained above.
>
>
> I'm not sure what is the proper to model this, maybe set this
> value in
> init()? If we suspend a machine, migrate it, and resume it, what
> RTC are
> we expecting?
>
> I forgot to reply on this one.
>
> I have not used migration very often, but I did manage to test it a
> couple of times
> using the 'migrate' command on the Qemu monitor console before I
> submitted each
> new version of the patch series. My expectation would be that the RTC
> time is suspended
> along with all the other state of the machine such as memory, I/O
> devices etc. So that would mean
> the time is 'frozen' until resumed. I think that is what we currently
> have here.
>
> Do you think that is correct or should it work differently?
Yes, this is the behavior I'd expect. Maybe other would disagree.
next prev parent reply other threads:[~2020-01-18 15:06 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-08 20:00 [PATCH v3 00/17] Add Allwinner H3 SoC and Orange Pi PC Machine Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 01/17] hw/arm: add Allwinner H3 System-on-Chip Niek Linnenbank
2020-01-08 23:13 ` Philippe Mathieu-Daudé
2020-01-11 20:45 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 02/17] hw/arm: add Xunlong Orange Pi PC machine Niek Linnenbank
2020-01-08 22:44 ` Philippe Mathieu-Daudé
2020-01-10 21:20 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 03/17] hw/arm/allwinner-h3: add Clock Control Unit Niek Linnenbank
2020-01-13 19:18 ` Niek Linnenbank
2020-01-18 15:37 ` Philippe Mathieu-Daudé
2020-01-18 23:28 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 04/17] hw/arm/allwinner-h3: add USB host controller Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 05/17] hw/arm/allwinner-h3: add System Control module Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 06/17] hw/arm/allwinner: add CPU Configuration module Niek Linnenbank
2020-01-13 23:14 ` Philippe Mathieu-Daudé
2020-01-14 23:04 ` Niek Linnenbank
2020-01-18 9:06 ` Philippe Mathieu-Daudé
2020-01-18 22:17 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 07/17] hw/arm/allwinner: add Security Identifier device Niek Linnenbank
2020-01-18 15:25 ` Philippe Mathieu-Daudé
2020-01-20 17:59 ` Corey Minyard
2020-02-02 21:27 ` Niek Linnenbank
2020-02-03 13:10 ` Corey Minyard
2020-02-06 21:09 ` Niek Linnenbank
2020-02-12 21:31 ` Niek Linnenbank
2020-02-12 22:47 ` Philippe Mathieu-Daudé
2020-02-17 19:34 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 08/17] hw/arm/allwinner: add SD/MMC host controller Niek Linnenbank
2020-01-18 15:39 ` Philippe Mathieu-Daudé
2020-01-08 20:00 ` [PATCH v3 09/17] hw/arm/allwinner-h3: add EMAC ethernet device Niek Linnenbank
2020-01-18 15:17 ` Philippe Mathieu-Daudé
2020-01-08 20:00 ` [PATCH v3 10/17] hw/arm/allwinner-h3: add Boot ROM support Niek Linnenbank
2020-01-13 23:28 ` Philippe Mathieu-Daudé
2020-01-14 23:10 ` Niek Linnenbank
2020-01-18 9:09 ` Philippe Mathieu-Daudé
2020-01-18 22:28 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 11/17] hw/arm/allwinner-h3: add SDRAM controller device Niek Linnenbank
2020-01-18 15:22 ` Philippe Mathieu-Daudé
2020-01-08 20:00 ` [PATCH v3 12/17] hw/arm/allwinner: add RTC device support Niek Linnenbank
2020-01-13 22:57 ` Philippe Mathieu-Daudé
2020-01-14 22:52 ` Niek Linnenbank
2020-01-14 22:57 ` Niek Linnenbank
2020-01-18 15:05 ` Philippe Mathieu-Daudé [this message]
2020-01-18 22:52 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 13/17] tests/boot_linux_console: Add a quick test for the OrangePi PC board Niek Linnenbank
2020-01-18 11:22 ` Philippe Mathieu-Daudé
2020-01-18 23:04 ` Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 14/17] tests/boot_linux_console: Add initrd test for the Orange Pi " Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 15/17] tests/boot_linux_console: Add a SD card test for the OrangePi " Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 16/17] tests/boot_linux_console: Add a SLOW test booting Ubuntu on OrangePi PC Niek Linnenbank
2020-01-08 20:00 ` [PATCH v3 17/17] docs: add Orange Pi PC document Niek Linnenbank
2020-01-18 9:37 ` Philippe Mathieu-Daudé
2020-01-18 22:38 ` Niek Linnenbank
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=128940fd-eda9-8151-eb4f-4d29c2c1d72a@redhat.com \
--to=philmd@redhat.com \
--cc=laurent@vivier.eu \
--cc=nieklinnenbank@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.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 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).