Il 28/02/2013 03:12, H. Peter Anvin ha scritto: > From: "H. Peter Anvin" <h...@zytor.com> > > There is no standard method for storing timezone information > associated with the classic PC/AT RTC, however, there are standard > methods in ACPI (Time and Alarm Device) and EFI (GetTime/SetTime) for > getting this information. > > Since these are abstract methods, it is qreally firmware-specific how > it is stored, however, since Qemu initializes the RTC in the virtual > environment that information needs to come from Qemu in the first > place. > > Non-PC platforms that use the MC146181 RTC may have their own > firmware-specific methods as well. > > The most logical place to stash this information is in the RTC CMOS; > not only is it logically co-located with the relevant information, but > it is also very easy to access from ACPI bytecode. Thus, save the > timezone information in two bytes in CMOS that have no known standard > definition, but are yet within the 64 bytes that even the most basic > RTC CMOS implementations including the original MC146181 support. > > Note: all timezones currently in use in the world are on 15-minutes > boundaries, which would allow this information to be stored in a > single signed byte. However, both EFI and ACPI use a minute-granular > interface (specified as -1440 to +1440 with 2047 used to mean > "unknown", this requires a minimum of 12 bits to represent); this > follows that model.
Interesting, do you have SeaBIOS and/or OVMF patches for this? Paolo > Signed-off-by: H. Peter Anvin <h...@zytor.com> > Cc: "Kevin O'Connor" <ke...@koconnor.net> > Cc: David Woodhouse <dw...@infradead.org> > --- > hw/mc146818rtc.c | 6 ++++++ > hw/mc146818rtc_regs.h | 2 ++ > 2 files changed, 8 insertions(+) > > diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c > index 2fb11f6..72541dd 100644 > --- a/hw/mc146818rtc.c > +++ b/hw/mc146818rtc.c > @@ -681,6 +681,7 @@ static void rtc_set_date_from_host(ISADevice *dev) > { > RTCState *s = DO_UPCAST(RTCState, dev, dev); > struct tm tm; > + int minuteseast; > > qemu_get_timedate(&tm, 0); > > @@ -690,6 +691,11 @@ static void rtc_set_date_from_host(ISADevice *dev) > > /* set the CMOS date */ > rtc_set_cmos(s, &tm); > + > + /* Set the timezone information as a signed 16-bit number of minutes */ > + minuteseast = ((int64_t)s->base_rtc - (int64_t)mktime(&tm)) / 60; > + s->cmos_data[RTC_TIMEZONE_L] = (uint8_t)(minuteseast); > + s->cmos_data[RTC_TIMEZONE_H] = (uint8_t)(minuteseast >> 8); > } > > static int rtc_post_load(void *opaque, int version_id) > diff --git a/hw/mc146818rtc_regs.h b/hw/mc146818rtc_regs.h > index ccdee42..7dd5e0d 100644 > --- a/hw/mc146818rtc_regs.h > +++ b/hw/mc146818rtc_regs.h > @@ -47,6 +47,8 @@ > /* PC cmos mappings */ > #define RTC_CENTURY 0x32 > #define RTC_IBM_PS2_CENTURY_BYTE 0x37 > +#define RTC_TIMEZONE_L 0x3e > +#define RTC_TIMEZONE_H 0x3f > > #define REG_A_UIP 0x80 > >