mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
rtc: implement century byte
Implement the century byte in the RTC emulation, and test that it works.
This leads to some annoying compatibility code because we need to treat
a value of 2000 for the base_year property as "use the century byte
properly" (which would be a value of 0).
The century byte will now be always-zero, rather than always-20,
for the MIPS Magnum machine whose base_year is 1980. Commit 42fc73a
(Support epoch of 1980 in RTC emulation for MIPS Magnum, 2009-01-24)
correctly said:
With an epoch of 1980 and a year of 2009, one could argue that [the
century byte] should hold either 0, 1, 19 or 20. NT 3.50 on MIPS
does not read the century byte.
so I picked the simplest and most sensible implementation which is to
return 0 for 1980-2079, 1 for 2080-2179 and so on.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
e67edb943f
commit
b8994faf2a
2 changed files with 48 additions and 11 deletions
|
@ -519,7 +519,9 @@ static void rtc_get_time(RTCState *s, struct tm *tm)
|
|||
tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
|
||||
tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
|
||||
tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
|
||||
tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
|
||||
tm->tm_year =
|
||||
rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year +
|
||||
rtc_from_bcd(s, s->cmos_data[RTC_CENTURY]) * 100 - 1900;
|
||||
}
|
||||
|
||||
static void rtc_set_time(RTCState *s)
|
||||
|
@ -552,10 +554,9 @@ static void rtc_set_cmos(RTCState *s, const struct tm *tm)
|
|||
s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1);
|
||||
s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday);
|
||||
s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1);
|
||||
year = (tm->tm_year - s->base_year) % 100;
|
||||
if (year < 0)
|
||||
year += 100;
|
||||
s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
|
||||
year = tm->tm_year + 1900 - s->base_year;
|
||||
s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year % 100);
|
||||
s->cmos_data[RTC_CENTURY] = rtc_to_bcd(s, year / 100);
|
||||
}
|
||||
|
||||
static void rtc_update_time(RTCState *s)
|
||||
|
@ -673,7 +674,6 @@ static void rtc_set_date_from_host(ISADevice *dev)
|
|||
{
|
||||
RTCState *s = DO_UPCAST(RTCState, dev, dev);
|
||||
struct tm tm;
|
||||
int val;
|
||||
|
||||
qemu_get_timedate(&tm, 0);
|
||||
|
||||
|
@ -683,9 +683,6 @@ static void rtc_set_date_from_host(ISADevice *dev)
|
|||
|
||||
/* set the CMOS date */
|
||||
rtc_set_cmos(s, &tm);
|
||||
|
||||
val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
|
||||
rtc_set_memory(dev, RTC_CENTURY, val);
|
||||
}
|
||||
|
||||
static int rtc_post_load(void *opaque, int version_id)
|
||||
|
@ -810,6 +807,18 @@ static int rtc_initfn(ISADevice *dev)
|
|||
s->cmos_data[RTC_REG_C] = 0x00;
|
||||
s->cmos_data[RTC_REG_D] = 0x80;
|
||||
|
||||
/* This is for historical reasons. The default base year qdev property
|
||||
* was set to 2000 for most machine types before the century byte was
|
||||
* implemented.
|
||||
*
|
||||
* This if statement means that the century byte will be always 0
|
||||
* (at least until 2079...) for base_year = 1980, but will be set
|
||||
* correctly for base_year = 2000.
|
||||
*/
|
||||
if (s->base_year == 2000) {
|
||||
s->base_year = 0;
|
||||
}
|
||||
|
||||
rtc_set_date_from_host(dev);
|
||||
|
||||
#ifdef TARGET_I386
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue